Add list of categories on promotion

and remove constraint on unit on list of products.

issue6820
review43551002
This commit is contained in:
Cédric Krier
2017-11-11 16:13:17 +01:00
parent 46487f7480
commit 18b63a9ed6
6 changed files with 60 additions and 21 deletions
+3
View File
@@ -1,3 +1,6 @@
* Add list of categories on promotion
* Remove unit constraint on list of products from promotion
Version 4.6.0 - 2017-10-30
* Bug fixes (see mercurial logs for details)
* Support price list when computing unit price
+1
View File
@@ -9,6 +9,7 @@ def register():
Pool.register(
SalePromotion,
SalePromotion_Product,
SalePromotion_ProductCategory,
Sale,
SaleLine,
module='sale_promotion', type_='model')
+2 -1
View File
@@ -18,6 +18,7 @@ The criteria are the fields:
- *Price List*: The sale price list.
- *Start Date*/*End Date*: The period for which the promotion is valid.
- *Quantity*: The sum quantity of the sale lines which have the same *Unit*.
- *Products*: The list of products to use to compute quantity.
- *Products*: The list of products to apply the promotion.
- *Categories*: The list of product categories to apply the promotion.
The new unit price is computed by the field *Formula*.
+32 -17
View File
@@ -14,7 +14,7 @@ from trytond.tools import decistmt
from trytond.modules.product import price_digits
__all__ = ['Sale', 'SaleLine',
'SalePromotion', 'SalePromotion_Product']
'SalePromotion', 'SalePromotion_Product', 'SalePromotion_ProductCategory']
class Sale:
@@ -124,14 +124,11 @@ class SalePromotion(ModelSQL, ModelView, MatchMixin):
depends=['quantity'])
unit_digits = fields.Function(fields.Integer('Unit Digits'),
'on_change_with_unit_digits')
unit_category = fields.Function(fields.Many2One('product.uom.category',
'Unit Category'), 'on_change_with_unit_category')
products = fields.Many2Many('sale.promotion-product.product',
'promotion', 'product', 'Products',
domain=[
('default_uom_category', '=', Eval('unit_category')),
],
depends=['unit_category'])
'promotion', 'product', 'Products')
categories = fields.Many2Many(
'sale.promotion-product.category', 'promotion', 'category',
"Categories")
formula = fields.Char('Formula', required=True,
help=('Python expression that will be evaluated with:\n'
'- unit_price: the original unit_price'))
@@ -159,11 +156,6 @@ class SalePromotion(ModelSQL, ModelView, MatchMixin):
return self.unit.digits
return 2
@fields.depends('unit')
def on_change_with_unit_category(self, name=None):
if self.unit:
return self.unit.category.id
@classmethod
def validate(cls, promotions):
super(SalePromotion, cls).validate(promotions)
@@ -235,10 +227,21 @@ class SalePromotion(ModelSQL, ModelView, MatchMixin):
return super(SalePromotion, self).match(pattern)
def is_valid_sale_line(self, line):
if self.products:
return line.product in self.products
elif self.unit:
return line.unit.category == self.unit.category
def parents(categories):
for category in categories:
while category:
yield category
category = category.parent
if self.unit and line.unit.category != self.unit.category:
return False
elif self.products and line.product not in self.products:
return False
elif (self.categories
and not set(parents(line.product.categories_all)).intersection(
self.categories)):
return False
else:
return True
@@ -290,3 +293,15 @@ class SalePromotion_Product(ModelSQL):
required=True, ondelete='CASCADE', select=True)
product = fields.Many2One('product.product', 'Product',
required=True, ondelete='CASCADE')
class SalePromotion_ProductCategory(ModelSQL):
"Sale Promotion - Product Category"
__name__ = 'sale.promotion-product.category'
promotion = fields.Many2One(
'sale.promotion', "Promotion",
required=True, ondelete='CASCADE', select=True)
category = fields.Many2One(
'product.category', "Category",
required=True, ondelete='CASCADE')
+20 -2
View File
@@ -41,6 +41,16 @@ Create products::
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
>>> Product = Model.get('product.product')
>>> Category = Model.get('product.category')
>>> category = Category(name="Root")
>>> category1 = category.childs.new(name="Child 1")
>>> category1b = category1.childs.new(name="Child 1b")
>>> category2 = category.childs.new(name="Child 2")
>>> category.save()
>>> category1, category2 = category.childs
>>> category1b, = category1.childs
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> template = ProductTemplate()
>>> template.name = 'Product'
@@ -50,6 +60,7 @@ Create products::
>>> template.lead_time = datetime.timedelta(0)
>>> template.list_price = Decimal('20')
>>> template.account_revenue = revenue
>>> template.categories.append(Category(category1b.id))
>>> template.save()
>>> product1 = Product()
>>> product1.template = template
@@ -61,6 +72,9 @@ Create products::
>>> product3.template = template
>>> product3.save()
>>> template4, = template.duplicate(default={'categories': [category2.id]})
>>> product4 = Product(template4.products[0].id)
Create payment term::
>>> payment_term = create_payment_term()
@@ -72,7 +86,8 @@ Create Promotion::
>>> promotion = Promotion(name='10% on 10 products 1 or 2')
>>> promotion.quantity = 10
>>> promotion.unit = unit
>>> promotion.products.extend([product1, product2])
>>> promotion.products.extend([product1, product2, product4])
>>> promotion.categories.append(Category(category1.id))
>>> promotion.formula = '0.9 * unit_price'
>>> promotion.save()
@@ -90,7 +105,10 @@ Sale enough products for promotion::
>>> sale_line.quantity = 10
>>> sale_line = sale.lines.new()
>>> sale_line.product = product3
>>> sale_line.quantity = 10
>>> sale_line.quantity = 5
>>> sale_line = sale.lines.new()
>>> sale_line.product = product4
>>> sale_line.quantity = 5
>>> sale.save()
>>> sale.untaxed_amount
Decimal('500.00')
+2 -1
View File
@@ -21,5 +21,6 @@ this repository contains the full copyright notices and license terms. -->
<field name="quantity"/>
<label name="unit"/>
<field name="unit"/>
<field name="products" colspan="4" view_ids="product.product_view_tree_simple"/>
<field name="categories" colspan="2"/>
<field name="products" colspan="2" view_ids="product.product_view_tree_simple"/>
</form>