class Invoice(models.Model): INVOICE_STATUS = ( ('PAID', 'Paid'), ('UNPA', 'Unpaid'), ('OVDU', 'Overdue'), ('CAND', 'Cancelled'), ('REFD', 'Refunded'), ) customer = models.ForeignKey(KITUser, blank=True, null=True, limit_choices_to={'is_admin': True}) invoice_alt = models.CharField(max_length=30, unique=True, default='') #invoice alternative id order = models.ForeignKey('gomez.Order', null=True, blank=True) date_raised = models.DateTimeField(null=True, blank=True) due_date = models.DateTimeField(null=True, blank=True) date_paid = models.DateTimeField(null=True, blank=True) payment_method = models.ForeignKey(PaymentMethod, on_delete=models.SET_NULL, null=True) note = models.TextField() total_net = PriceField(currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2, blank=True, null=True) total_tax = PriceField(currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2, blank=True, null=True) status = models.CharField(max_length=4, choices=INVOICE_STATUS) def __str__(self): return 'Invoice #'.format(self.id) @property def total(self): if self.total_net is not None: gross = self.total_net.net + self.total_tax.gross return Price(net=self.total_net.net, gross=gross, currency=settings.DEFAULT_CURRENCY) @total.setter def total(self, price): self.total_net = price self.total_tax = Price(price.tax, currency=price.currency)
class Pricing(models.Model): room = models.ForeignKey(Room, related_name='room_price', blank=True, null=True, verbose_name=pgettext_lazy( 'Pricing field', 'room')) package = models.ForeignKey(Package, related_name='package_price', blank=True, null=True, verbose_name=pgettext_lazy( 'Pricing field', 'package')) daily = PriceField(pgettext_lazy('Pricing field', 'daily price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) nightly = PriceField(pgettext_lazy('Pricing field', 'nightly price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) daytime = PriceField(pgettext_lazy('Pricing field', 'daytime price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) weekly = PriceField(pgettext_lazy('Pricing field', 'weekly price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) monthly = PriceField(pgettext_lazy('Pricing field', 'monthly price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) class Meta: verbose_name = pgettext_lazy('RoomPricing model', 'pricing') verbose_name_plural = pgettext_lazy('RoomPricing model', 'pricing') app_label = 'room' def __str__(self): return str(self.room.name) + ' ' + str(self.daily)
class ShippingMethodCountry(models.Model): country_code = models.CharField(pgettext_lazy( 'Shipping method country field', 'country code'), choices=COUNTRY_CODE_CHOICES, max_length=2, blank=True, default=ANY_COUNTRY) price = PriceField(pgettext_lazy('Shipping method country field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2) shipping_method = models.ForeignKey( ShippingMethod, related_name='price_per_country', verbose_name=pgettext_lazy('Shipping method country field', 'shipping method'), ) objects = ShippingMethodCountryQueryset.as_manager() class Meta: unique_together = ('country_code', 'shipping_method') verbose_name = pgettext_lazy('Shipping method country model', 'shipping method country') verbose_name_plural = pgettext_lazy('Shipping method country model', 'shipping method countries') def __str__(self): # https://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.get_FOO_display # noqa return '%s %s' % (self.shipping_method, self.get_country_code_display()) def get_total(self): return self.price
class PhysicalProduct(models.Model): weight = models.DecimalField(max_digits=6, decimal_places=2) length = models.DecimalField(max_digits=6, decimal_places=2, blank=True, default=0) width = models.DecimalField(max_digits=6, decimal_places=2, blank=True, default=0) depth = models.DecimalField(max_digits=6, decimal_places=2, blank=True, default=0) price = PriceField(pgettext_lazy('Product field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=4) def get_weight(self): try: return self.weight except AttributeError: return self.product.weight class Meta: abstract = True app_label = 'product'
class Product(Subtyped, Item): name = models.CharField(pgettext_lazy(u'Product field', u'name'), max_length=128) price = PriceField(pgettext_lazy(u'Product field', u'price'), currency=settings.SATCHLESS_DEFAULT_CURRENCY, max_digits=12, decimal_places=4) sku = models.CharField(pgettext_lazy(u'Product field', u'sku'), max_length=32, unique=True) category = models.ForeignKey(Category, related_name='products', verbose_name=pgettext_lazy( u'Product field', u'category')) def __unicode__(self): return self.name @models.permalink def get_absolute_url(self): return ('product:details', (), { 'slug': self.get_slug(), 'product_id': self.id }) def get_price_per_item(self, **kwargs): return self.price def get_slug(self): value = unidecode(self.name) value = re.sub(r'[^\w\s-]', '', value).strip().lower() return mark_safe(re.sub(r'[-\s]+', '-', value))
class ProductVariant(models.Model, Item): name = models.CharField(pgettext_lazy('Product field', 'name'), max_length=128, blank=True, default='') price = PriceField(pgettext_lazy('Product field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=4) sku = models.CharField( pgettext_lazy('Product field', 'sku'), max_length=32, unique=True) class Meta: abstract = True app_label = 'product' def __str__(self): return self.name or self.product.name def get_price_per_item(self, discounted=True, **kwargs): price = self.price if discounted: discounts = list(get_product_discounts(self, **kwargs)) if discounts: modifier = max(discounts) price += modifier return price def get_absolute_url(self): slug = self.product.get_slug() product_id = self.product.id return reverse( 'product:details', kwargs={'slug': slug, 'product_id': product_id})
class Stock(models.Model): variant = models.ForeignKey(ProductVariant, related_name='stock', verbose_name=pgettext_lazy( 'Stock item field', 'variant')) location = models.ForeignKey(Address, related_name='+', verbose_name=pgettext_lazy( 'Stock item field', 'location'), null=True) quantity = models.IntegerField(pgettext_lazy('Stock item field', 'quantity'), validators=[MinValueValidator(0)], default=Decimal(1)) cost_price = PriceField(pgettext_lazy('Stock item field', 'cost price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2, blank=True, null=True) class Meta: app_label = 'product' unique_together = ('variant', 'location') def __str__(self): return "%s - %s" % (self.variant.name, self.location)
class ProductVariant(models.Model, Item): code = models.CharField(_('Product variant field', 'code'), max_length=32, unique=True) namd = models.CharField(_('Product variant field', 'namd'), max_length=128, blank=True) price_override = PriceField(_('Product variant field', 'price override'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2, blank=True, null=True) product = models.ForeignKey(Product, related_name='variants') attributes = HStoreField(_('Product variant field', 'attributes'), default={}) images = models.ManyToManyField('ProductImage', through='VariantImage', verbose_name=_('Product variant field', 'images')) class Meta: app_label = 'products' verbose_name = _('Product variant model', 'product variant') verbose_name_plural = _('Product variant model', 'product variants') def __str__(self): return self.name or self.display_variant()
def test_get_prep_value(): field = PriceField('price', currency='BTC', default='5', max_digits=9, decimal_places=2) assert field.get_prep_value(Price(5, currency='BTC')) == Decimal(5)
class Stock(models.Model): variant = models.ForeignKey(ProductVariant, related_name='stock', verbose_name=pgettext_lazy( 'Stock item field', 'variant')) location = models.ForeignKey(StockLocation, null=True) quantity = models.IntegerField(pgettext_lazy('Stock item field', 'quantity'), validators=[MinValueValidator(0)], default=Decimal(1)) quantity_allocated = models.IntegerField(pgettext_lazy( 'Stock item field', 'allocated quantity'), validators=[MinValueValidator(0)], default=Decimal(0)) cost_price = PriceField(pgettext_lazy('Stock item field', 'cost price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2, blank=True, null=True) objects = StockManager() class Meta: app_label = 'product' unique_together = ('variant', 'location') def __str__(self): return '%s - %s' % (self.variant.name, self.location) @property def quantity_available(self): return max(self.quantity - self.quantity_allocated, 0)
class BookingHistory(models.Model): invoice_number = models.CharField( pgettext_lazy('BookingHistory field', 'invoice number'), max_length=152, default='', blank=True, null=True) price = PriceField( pgettext_lazy('Book field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) book = models.ForeignKey( Book, related_name='booking_history_payment', blank=True, null=True, default='', on_delete=models.SET_NULL, verbose_name=pgettext_lazy('BookingHistory field', 'table')) room = models.ForeignKey( Room, verbose_name=pgettext_lazy('Book field', 'rooms'), related_name='booking_history_room', blank=True, null=True, on_delete=models.SET_NULL ) customer = models.ForeignKey( Customer, blank=True, null=True, on_delete=models.SET_NULL, related_name='booking_history_customers', verbose_name=pgettext_lazy('Book field', 'customer')) check_in = models.DateTimeField( pgettext_lazy('BookingHistory field', 'Date from'), default=now) check_out = models.DateTimeField( pgettext_lazy('BookingHistory field', 'Date until'), default=now) created = models.DateField( pgettext_lazy('BookingHistory field', 'created'), default=now, editable=False)
class Payment(models.Model): invoice_number = models.CharField( pgettext_lazy('Payment invoice', 'invoice number'), max_length=152, default='', blank=True, null=True) description = models.CharField( pgettext_lazy('Payment field', 'description'), max_length=152, default='', null=True, blank=True) price_type = models.CharField( pgettext_lazy('Payment field', 'price type'), max_length=152, default='', null=True, blank=True) payment_option = models.ForeignKey( PaymentOption, related_name='booking_payment_option', blank=True, null=True, default='', on_delete=models.SET_NULL, verbose_name=pgettext_lazy('Payment field', 'table')) amount_paid = PriceField( pgettext_lazy('Payment field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) customer = models.ForeignKey( Customer, related_name='booking_payment', blank=True, null=True, default='', on_delete=models.SET_NULL, verbose_name=pgettext_lazy('Payment field', 'table')) book = models.ForeignKey( Book, related_name='booking_payment', blank=True, null=True, default='', on_delete=models.SET_NULL, verbose_name=pgettext_lazy('Payment field', 'table')) date = models.DateField( pgettext_lazy('Payment field', 'Date from'), default=now) created = models.DateField( pgettext_lazy('Payment field', 'created'), default=now, editable=False)
class FixedProductDiscount(models.Model): name = models.CharField(max_length=255) products = models.ManyToManyField(Product, blank=True) discount = PriceField(pgettext_lazy('Discount field', 'discount value'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=4) objects = ProductDiscountManager() class Meta: app_label = 'product' def modifier_for_product(self, variant): if not self.products.filter(pk=variant.product.pk).exists(): raise NotApplicable('Discount not applicable for this product') if self.discount > variant.get_price(discounted=False): raise NotApplicable('Discount too high for this product') return FixedDiscount(self.discount, name=self.name) def __str__(self): return self.name def __repr__(self): return 'FixedProductDiscount(name=%r, discount=%r)' % (str( self.discount), self.name)
def test_from_db_value_handles_none(): field = PriceField('price', currency='BTC', default='5', max_digits=9, decimal_places=2) assert field.from_db_value(None, None, None, None) is None
class Stock(models.Model): variant = models.ForeignKey(ProductVariant, related_name='stock', on_delete=models.CASCADE) location = models.ForeignKey(StockLocation, null=True, on_delete=models.CASCADE) quantity = models.IntegerField(validators=[MinValueValidator(0)], default=Decimal(1)) quantity_allocated = models.IntegerField(validators=[MinValueValidator(0)], default=Decimal(0)) cost_price = PriceField(currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2, blank=True, null=True) class Meta: app_label = 'product' unique_together = ('variant', 'location') def __str__(self): return '%s - %s' % (self.variant.name, self.location) @property def quantity_available(self): return max(self.quantity - self.quantity_allocated, 0)
class PackageOffer(models.Model): device = models.OneToOneField(Product, verbose_name='device for package offer', related_name='device') eliquids = models.ManyToManyField( Product, verbose_name='eliquids for package offer', related_name='eliquids') coil = models.ForeignKey(Product, null=True, verbose_name='coil for package offer', related_name='coil') battery = models.ForeignKey(Product, null=True, verbose_name='battery for package offer', related_name='battery') price = PriceField(pgettext_lazy('Package offer field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2, blank=True, null=True) def __str__(self): return self.device.name def get_absolute_url(self): return reverse('product:package-offer-details', kwargs={ 'slug': self.get_slug(), 'product_id': self.id }) def get_slug(self): return slugify(smart_text(unidecode(self.device.name)))
class ProviderFinance(models.Model): provider = models.ForeignKey(Provider) date_generated = models.DateField(default=now) income = PriceField(currency='NGN', decimal_places=2, max_digits=18, default=0.00) hit_count = models.IntegerField(default=1)
def test_get_db_prep_save(): field = PriceField('price', currency='BTC', default='5', max_digits=9, decimal_places=2) value = field.get_db_prep_save(Price(5, currency='BTC'), connection) assert value == '5.00'
class DeliveryGroup(models.Model, ItemSet): """Represents a single shipment. A single order can consist of many shipment groups. """ status = models.CharField( pgettext_lazy('Shipment group field', 'shipment status'), max_length=32, default=GroupStatus.NEW, choices=GroupStatus.CHOICES) order = models.ForeignKey( Order, related_name='groups', editable=False, on_delete=models.CASCADE) shipping_price = PriceField( pgettext_lazy('Shipment group field', 'shipping price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=4, default=0, editable=False) shipping_method_name = models.CharField( pgettext_lazy('Shipment group field', 'shipping method name'), max_length=255, null=True, default=None, blank=True, editable=False) tracking_number = models.CharField( pgettext_lazy('Shipment group field', 'tracking number'), max_length=255, default='', blank=True) last_updated = models.DateTimeField( pgettext_lazy('Shipment group field', 'last updated'), null=True, auto_now=True) def __str__(self): return pgettext_lazy( 'Shipment group str', 'Shipment #%s') % self.pk def __repr__(self): return '%s(%r)' % (self.__class__.__name__, list(self)) def __iter__(self): if self.id: return iter(self.lines.all()) return super(DeliveryGroup, self).__iter__() @property def shipping_required(self): return self.shipping_method_name is not None def get_total_with_shipping(self, **kwargs): return self.get_total() + self.shipping_price def get_total_quantity(self): return sum([line.get_quantity() for line in self]) def is_shipping_required(self): return self.shipping_required def can_ship(self): return self.is_shipping_required() and self.status == GroupStatus.NEW def can_cancel(self): return self.status != GroupStatus.CANCELLED def can_edit_lines(self): return self.status not in {GroupStatus.CANCELLED, GroupStatus.SHIPPED}
def test_from_db_value_checks_currency(): field = PriceField('price', currency='BTC', default='5', max_digits=9, decimal_places=2) invalid = Price(1, currency='USD') with pytest.raises(ValueError): field.from_db_value(invalid, None, None, None)
def test_formfield(): field = PriceField('price', currency='BTC', default='5', max_digits=9, decimal_places=2) form_field = field.formfield() assert isinstance(form_field, forms.PriceField) assert form_field.currency == 'BTC' assert isinstance(form_field.widget, widgets.PriceInput)
class RentPayment(models.Model): date_paid = models.CharField( pgettext_lazy('Payment field', 'date paid'), max_length=152, default='', null=True, blank=True) created = models.DateField( pgettext_lazy('Payment field', 'created'), default=now, editable=False) invoice_number = models.CharField( pgettext_lazy('Payment invoice', 'invoice number'), max_length=152, default='', blank=True, null=True) price_type = models.CharField( pgettext_lazy('Payment field', 'price type'), max_length=152, default='', null=True, blank=True) total_amount = PriceField( pgettext_lazy('Payment field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) total_balance = PriceField( pgettext_lazy('Payment field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) amount_paid = PriceField( pgettext_lazy('Payment field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) balance = PriceField( pgettext_lazy('Book field', 'balance'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) service_charges = PriceField( pgettext_lazy('Book field', 'service charges'), currency=settings.DEFAULT_CURRENCY, max_digits=12, validators=[MinValueValidator(0)], default=Decimal(0), decimal_places=2) customer = models.ForeignKey( Customer, related_name='tenant_payment', blank=True, null=True, default='', on_delete=models.CASCADE, verbose_name=pgettext_lazy('Customer field', 'customer')) room = models.ForeignKey( Room, related_name='room_payment', blank=True, null=True, default='', on_delete=models.SET_NULL, verbose_name=pgettext_lazy('Customer field', 'room')) description = models.CharField( pgettext_lazy('Payment field', 'description'), max_length=152, default='', null=True, blank=True)
class Stock(models.Model): variant = models.ForeignKey(ProductVariant, related_name='stock', verbose_name=pgettext_lazy( 'Stock item field', 'variant')) location = models.ForeignKey(StockLocation, default=StockLocation.DEFAULT_PK) quantity = models.IntegerField(pgettext_lazy('Stock item field', 'quantity'), validators=[MinValueValidator(0)], default=Decimal(1)) invoice_number = models.CharField( pgettext_lazy('Stock item field', 'invoice_number'), null=True, max_length=36, ) low_stock_threshold = models.IntegerField( pgettext_lazy('Stock item field', 'low stock threshold'), validators=[MinValueValidator(0)], null=True, blank=True, default=Decimal(10)) quantity_allocated = models.IntegerField(pgettext_lazy( 'Stock item field', 'allocated quantity'), validators=[MinValueValidator(0)], default=Decimal(0)) cost_price = PriceField(pgettext_lazy('Stock item field', 'cost price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2, blank=True, null=True) objects = StockManager() class Meta: app_label = 'product' unique_together = ('variant', 'location') def __str__(self): return '%s - %s' % (self.variant.name, self.pk) @property def quantity_available(self): return max(self.quantity - self.quantity_allocated, 0) def cost_priceAsData(self): return self.cost_price def varaintName(self): return self.variant.price_override def Access_pk(self): return self.pk
class Product(models.Model, ItemRange): name = models.CharField( pgettext_lazy('Product field', 'name'), max_length=128) description = models.TextField( verbose_name=pgettext_lazy('Product field', 'description')) categories = models.ManyToManyField( Category, verbose_name=pgettext_lazy('Product field', 'categories'), related_name='products') price = PriceField( pgettext_lazy('Product field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2) weight = WeightField( pgettext_lazy('Product field', 'weight'), unit=settings.DEFAULT_WEIGHT, max_digits=6, decimal_places=2) available_on = models.DateField( pgettext_lazy('Product field', 'available on'), blank=True, null=True) attributes = models.ManyToManyField( 'ProductAttribute', related_name='products', blank=True) updated_at = models.DateTimeField( pgettext_lazy('Product field', 'updated at'), auto_now=True, null=True) objects = ProductManager() class Meta: app_label = 'product' def __iter__(self): if not hasattr(self, '__variants'): setattr(self, '__variants', self.variants.all()) return iter(getattr(self, '__variants')) def __repr__(self): class_ = type(self) return '<%s.%s(pk=%r, name=%r)>' % ( class_.__module__, class_.__name__, self.pk, self.name) def __str__(self): return self.name def get_absolute_url(self): return reverse('product:details', kwargs={'slug': self.get_slug(), 'product_id': self.id}) def get_slug(self): return slugify(smart_text(unidecode(self.name))) def is_in_stock(self): return any(variant.is_in_stock() for variant in self) def get_first_category(self): for category in self.categories.all(): if not category.hidden: return category return None
class Model(models.Model): price_net = AmountField('net', currency='BTC', default='5', max_digits=9, decimal_places=2) price_gross = AmountField('gross', currency='BTC', default='5', max_digits=9, decimal_places=2) price = PriceField(net_field='price_net', gross_field='price_gross')
class DeliveryGroup(models.Model, ItemSet): STATUS_CHOICES = (('new', pgettext_lazy('Delivery group status field value', 'Processing')), ('cancelled', pgettext_lazy('Delivery group status field value', 'Cancelled')), ('shipped', pgettext_lazy('Delivery group status field value', 'Shipped'))) status = models.CharField(pgettext_lazy('Delivery group field', 'Delivery status'), max_length=32, default='new', choices=STATUS_CHOICES) method = models.CharField(pgettext_lazy('Delivery group field', 'Delivery method'), max_length=255) order = models.ForeignKey(Order, related_name='groups', editable=False) price = PriceField(pgettext_lazy('Delivery group field', 'unit price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=4, default=0, editable=False) objects = InheritanceManager() def __repr__(self): return '%s(%r)' % (self.__class__.__name__, list(self)) def __iter__(self): if self.id: return iter(self.items.select_related('product').all()) return super(DeliveryGroup, self).__iter__() def change_status(self, status): self.status = status self.save() def get_total(self, **kwargs): return super(DeliveryGroup, self).get_total(**kwargs) + self.price def add_items_from_partition(self, partition): for item_line in partition: product_variant = item_line.product price = item_line.get_price_per_item() self.items.create(product=product_variant.product, quantity=item_line.get_quantity(), unit_price_net=price.net, product_name=smart_text(product_variant), product_sku=product_variant.sku, unit_price_gross=price.gross)
class Variant(TaxedVariantMixin, VariantStockLevelMixin, satchless.product.models.Variant): price_offset = PriceField(_("unit price offset"), currency='EUR', default=0, max_digits=12, decimal_places=4) def get_price_per_item(self, discount=True, quantity=1, **kwargs): price = self.product._get_base_price(quantity=quantity) price += self.price_offset if discount and self.product.discount: price += self.product.discount return price
class PostShippingType(models.Model): typ = models.SlugField(max_length=50, unique=True) name = models.CharField(_('name'), max_length=128) price = PriceField(_('price'), currency=settings.SATCHLESS_DEFAULT_CURRENCY, max_digits=10, decimal_places=2) def __unicode__(self): return self.name class Meta: verbose_name = _('Post shipping type') verbose_name_plural = _('Post shipping types')
class Variant(StockedItem, models.Model): name = models.CharField(max_length=200) description = RichTextField() price = PriceField(currency='USD', max_digits=5, decimal_places=2) size = models.CharField(max_length=3, null=True, blank=True) color = models.CharField(max_length=10, null=True, blank=True) product = ParentalKey('product.Product', related_name='variants') stock = models.IntegerField('In stock') def __str__(self): return self.name def get_stock(self): return self.stock
class Product(models.Model, ItemRange): product_type = models.ForeignKey( ProductType, related_name='products', verbose_name=_('Product field', 'product type')) # this type of product name = models.CharField(_('Product field', 'name'), max_length=200) description = models.TextField( verbose_name=_('Product field', 'description')) categories = models.ManyToManyField(Category, verbose_name=_('Product field', 'categories'), related_name='products') price = PriceField(_('Product field', 'price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2) available_on = models.DateField(_('Product field', 'available on'), blank=True, null=True) is_published = models.BooleanField(_('Product field', 'is published'), default=True) attributes = HStoreField(_('Product field', 'attributes'), default={}) updated_at = models.DateTimeField(_('Product field', 'updated at'), auto_now=True, null=True) is_featured = models.BooleanField(_('Product field', 'is featured'), default=False) objects = ProductManager() # search_fields = [ # index.SearchField('name', partial_match=True), # index.SearchField('description'), # index.FilterField('available_on'), # index.FilterField('is_published')] class Meta: app_label = 'product' verbose_name = _('Product model', 'product') verbose_name_plural = _('Product model', 'products') permissions = (('view_product', _('Permission description', 'Can view product')), ('edit_product', _('Permission description', 'Can edit products'))) def __str__(self): return self.name