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 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 ShippingMethodCountry(models.Model): country_code = models.CharField(choices=COUNTRY_CODE_CHOICES, max_length=2, blank=True, default=ANY_COUNTRY) price = PriceField(currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2) shipping_method = models.ForeignKey(ShippingMethod, related_name='price_per_country', on_delete=models.CASCADE) objects = ShippingMethodCountryQueryset.as_manager() class Meta: unique_together = ('country_code', 'shipping_method') 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 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)
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}
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 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 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(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 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(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 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
class PriceQtyOverride(models.Model): """ Overrides price of product unit, depending of total quantity being sold. """ product = models.ForeignKey(Product, related_name='qty_price_overrides') min_qty = models.DecimalField(_("minimal quantity"), max_digits=10, decimal_places=4) price = PriceField(_("unit price"), currency='EUR', max_digits=12, decimal_places=4) class Meta: ordering = ('min_qty', )
class ProductBidHistory(models.Model): session = models.ForeignKey('bid.BidSession') product = models.ForeignKey('product.Product') user = models.ForeignKey('userprofile.user') bid_price = PriceField(pgettext_lazy('Product bid session history field', 'bid price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2) bid_time = models.DateTimeField(pgettext_lazy( 'Product bid session history field', 'bid time'), default=timezone.now, editable=False) user_display_name = models.CharField(max_length=255, blank=True, null=True)
class DeliveryGroup(Subtyped, ItemSet): STATUS_CHOICES = (('new', pgettext_lazy(u'Delivery group status field value', u'New')), ('cancelled', pgettext_lazy(u'Delivery group status field value', u'Cancelled')), ('shipped', pgettext_lazy(u'Delivery group status field value', u'Shipped'))) status = models.CharField(pgettext_lazy(u'Delivery group field', u'Delivery status'), max_length=32, default='new', choices=STATUS_CHOICES) order = models.ForeignKey(Order, related_name='groups', editable=False) price = PriceField(pgettext_lazy(u'Delivery group field', u'unit price'), currency=settings.SATCHLESS_DEFAULT_CURRENCY, max_digits=12, decimal_places=4, default=0, editable=False) 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_name = unicode(item_line.product) price = item_line.get_price_per_item() self.items.create(product=item_line.product, quantity=item_line.get_quantity(), unit_price_net=price.net, product_name=product_name, unit_price_gross=price.gross)
class Product(models.Model, Item): name = models.CharField(max_length=100) description = models.TextField() meta = JSONField() price = PriceField('Price', currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2) active = models.BooleanField(default=True) created = models.DateTimeField(auto_now=True) updated = models.DateTimeField(auto_now_add=True, null=True) def __str__(self): return self.name
class PriceQtyOverride(models.Model): """ Overrides price of product unit, depending of total quantity being sold. """ product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='qty_price_overrides') min_qty = models.DecimalField(_('minimal quantity'), max_digits=10, decimal_places=4) price = PriceField(_('unit price'), currency=settings.SATCHLESS_DEFAULT_CURRENCY, max_digits=12, decimal_places=4) class Meta: ordering = ('min_qty', )
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 PurchaseProduct(models.Model): variant = models.ForeignKey( ProductVariant, related_name='purchase_variant', verbose_name=pgettext_lazy('PurchaseProduct item field', 'variant')) stock = models.ForeignKey( Stock, related_name='purchase_stock', verbose_name=pgettext_lazy('PurchaseProduct item field', 'stock')) quantity = models.IntegerField( pgettext_lazy('PurchaseProduct item field', 'quantity'), validators=[MinValueValidator(0)], default=Decimal(1)) cost_price = PriceField( pgettext_lazy('PurchaseProduct item field', 'cost price'), currency=settings.DEFAULT_CURRENCY, max_digits=12, decimal_places=2, blank=True, null=True) supplier = models.ForeignKey( Supplier, related_name='purchase_supplier', verbose_name=pgettext_lazy('PurchaseProduct item field', 'supplier') ,null=True,blank=True) invoice_number = models.CharField( pgettext_lazy('PurchaseProduct', 'invoice_number'), null=True, max_length=36,) created = models.DateTimeField( pgettext_lazy('PurchaseProduct field', 'created'), default=now, editable=False) class Meta: verbose_name = pgettext_lazy('PurchaseProduct model', 'PurchaseProduct') verbose_name_plural = pgettext_lazy('PurchaseProduct model', 'PurchaseProducts') def __str__(self): return str(self.variant)+' '+str(self.stock) def get_total_cost(self): if not self.cost_price: # return self.cost_price.gross * self.quantity # return self.stock.variant.get_price_per_item().gross * self.quantity return 0 return self.cost_price.gross * self.quantity def get_cost_price(self): if not self.cost_price: # return self.stock.cost_price return self.stock.variant.get_price_per_item().gross return self.cost_price
class Product(models.Model, StockedItem): """An abstract class that embodies everything that can be sold.""" price = PriceField('Price', currency='EUR', max_digits=5, decimal_places=2, blank=False, default=0.0) stock = models.PositiveSmallIntegerField('Product Stock', blank=False, default=0) date_added = models.DateField('Date added') last_modified = models.DateTimeField('Last modified') slug = models.SlugField('Product slug', max_length=256) def get_price_per_item(self): return price class Meta: abstract = True
class Stock(models.Model): variant = models.ForeignKey( ProductVariant, related_name='stock', verbose_name=pgettext_lazy('Stock item field', 'variant')) location = models.CharField( pgettext_lazy('Stock item field', 'location'), max_length=100) 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 Product(Subtyped, Item): name = models.CharField(pgettext_lazy('Product field', 'name'), max_length=128) price = PriceField(pgettext_lazy('Product field', 'price'), currency=settings.SATCHLESS_DEFAULT_CURRENCY, max_digits=12, decimal_places=4) sku = models.CharField(pgettext_lazy('Product field', 'sku'), max_length=32, unique=True) category = models.ForeignKey(Category, related_name='products', verbose_name=pgettext_lazy( 'Product field', 'category')) def __unicode__(self): return self.name def get_absolute_url(self): return reverse('product:details', kwargs={ 'slug': self.get_slug(), 'product_id': self.id }) 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_slug(self): value = unidecode(self.name) value = re.sub(r'[^\w\s-]', '', value).strip().lower() return mark_safe(re.sub(r'[-\s]+', '-', value))
class Stock(models.Model): """There are five seats in Marcopolo X. Three of them have already been sold to customers. The stock records quantity is 5, quantity allocated is 3 and quantity available is 2. """ # formula===> stock quantity = quantity allocated + quantity available 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) #Each stock records also has a cost price (the price that your store had to pay to obtain it). """Once a delivery group is marked as shipped, each stock record used to fulfil its lines will have both its quantity at hand and quantity allocated decreased by the number of items shipped """ class Meta: db_table = 'stock' 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 FixedProductDiscount(models.Model): name = models.CharField(max_length=255) products = models.ManyToManyField(Product, blank=True) discount = PriceField(pgettext_lazy(u'Discount field', u'discount value'), currency=settings.SATCHLESS_DEFAULT_CURRENCY, max_digits=12, decimal_places=4) objects = ProductDiscountManager() def modifier_for_product(self, product): if not self.products.filter(pk=product.pk).exists(): raise NotApplicable('Discount not applicable for this product') if self.discount > product.get_price(discounted=False): raise NotApplicable('Discount too high for this product') return FixedDiscount(self.discount, name=self.name) def __unicode__(self): return self.name def __repr__(self): return 'SelectedProduct(name=%r, discount=%r)' % (str(self.discount), self.name)
class Product(models.Model): fuel_station = models.ForeignKey(FuelStation, verbose_name=_('Product field', 'fuel station'), related_name='products') name = models.CharField(_('Product field', 'name'), max_length=200) description = models.TextField( verbose_name=_('Product field', 'description')) category = models.ForeignKey(Category, verbose_name=_('Product field', 'category'), 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_available = models.BooleanField(_('Product field', 'is available'), default=True) 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() class Meta: app_label = 'fsinfoservice' 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
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=2) class Meta: app_label = 'product' def __repr__(self): return 'FixedProductDiscount(name=%r, discount=%r)' % (str( self.discount), self.name) def __str__(self): return self.name 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)
class Product(TaxedProductMixin, construct(CategorizedProductMixin, category=Category), satchless.product.models.Product): QTY_MODE_CHOICES = (('product', _("per product")), ('variant', _("per variant"))) qty_mode = models.CharField(_("Quantity pricing mode"), max_length=10, choices=QTY_MODE_CHOICES, default='variant', help_text=_("In 'per variant' mode the unit " "price will depend on quantity " "of single variant being sold. In " "'per product' mode, total " "quantity of all product's " "variants will be used.")) price = PriceField(_("base price"), currency='EUR', max_digits=12, decimal_places=4) discount = models.ForeignKey(Discount, null=True, blank=True, related_name='products') def __unicode__(self): return self.name def _get_base_price(self, quantity): overrides = self.qty_price_overrides.all() overrides = overrides.filter( min_qty__lte=quantity).order_by('-min_qty') try: return overrides[0].price except Exception: return self.price