Add list of categories on promotion
and remove constraint on unit on list of products. issue6820 review43551002
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -9,6 +9,7 @@ def register():
|
||||
Pool.register(
|
||||
SalePromotion,
|
||||
SalePromotion_Product,
|
||||
SalePromotion_ProductCategory,
|
||||
Sale,
|
||||
SaleLine,
|
||||
module='sale_promotion', type_='model')
|
||||
|
||||
+2
-1
@@ -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*.
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user