From 5bc0606b2b9eee5dec6b7fcc75bd06b579005352 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Mon, 21 May 2018 22:22:10 -0300 Subject: [PATCH] [REL] migration product_pack to 11.0 (#145) * [FIX] xml files names * [REL] migration product_pack to 11.0 * [FIX] Update README * [FIX] remove openerp tags and data tags * [IMP] change some funtion to improve funcionality * [FIX] change name to xml and .py files according guidelines * [FIX] remove api.one decorators * [FIX] update readme * [FIX] Remove "encoding: utf-8" * [FIX] remove api.multi, string not necesary and some other fixes * [FIX] demo data to separate according Guidelines * [FIX] fix names in fields * [FIX] remove executable --- product_pack/README.rst | 39 ++- product_pack/__init__.py | 4 +- product_pack/__manifest__.py | 17 +- product_pack/demo/demo_data.xml | 302 ------------------ product_pack/demo/product_pack_line_demo.xml | 116 +++++++ product_pack/demo/product_product_demo.xml | 89 ++++++ product_pack/models/__init__.py | 9 +- product_pack/models/product.py | 215 ------------- .../models/{pack.py => product_pack_line.py} | 23 +- product_pack/models/product_product.py | 88 +++++ product_pack/models/product_template.py | 100 ++++++ product_pack/models/sale_order.py | 6 +- product_pack/models/sale_order_line.py | 26 +- .../models/sale_order_line_pack_line.py | 21 +- product_pack/security/ir.model.access.csv | 2 +- product_pack/views/pack_view.xml | 72 ----- .../views/product_pack_line_views.xml | 30 ++ product_pack/views/product_product_views.xml | 19 ++ product_pack/views/product_template_views.xml | 22 ++ .../views/sale_order_line_pack_line_views.xml | 17 + ...ale_view.xml => sale_order_line_views.xml} | 38 +-- product_pack/views/sale_order_views.xml | 19 ++ 22 files changed, 575 insertions(+), 699 deletions(-) mode change 100755 => 100644 product_pack/__init__.py delete mode 100644 product_pack/demo/demo_data.xml create mode 100644 product_pack/demo/product_pack_line_demo.xml create mode 100644 product_pack/demo/product_product_demo.xml mode change 100755 => 100644 product_pack/models/__init__.py delete mode 100644 product_pack/models/product.py rename product_pack/models/{pack.py => product_pack_line.py} (87%) mode change 100755 => 100644 create mode 100644 product_pack/models/product_product.py create mode 100644 product_pack/models/product_template.py mode change 100755 => 100644 product_pack/models/sale_order_line_pack_line.py mode change 100755 => 100644 product_pack/security/ir.model.access.csv delete mode 100755 product_pack/views/pack_view.xml create mode 100644 product_pack/views/product_pack_line_views.xml create mode 100644 product_pack/views/product_product_views.xml create mode 100644 product_pack/views/product_template_views.xml create mode 100644 product_pack/views/sale_order_line_pack_line_views.xml rename product_pack/views/{sale_view.xml => sale_order_line_views.xml} (50%) create mode 100644 product_pack/views/sale_order_views.xml diff --git a/product_pack/README.rst b/product_pack/README.rst index ce89495cb9f..6a295723afc 100644 --- a/product_pack/README.rst +++ b/product_pack/README.rst @@ -1,12 +1,22 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 +.. |company| replace:: ADHOC SA + +.. |company_logo| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-logo.png + :alt: ADHOC SA + :target: https://www.adhoc.com.ar + +.. |icon| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-icon.png + +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: https://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 ============ Product Pack ============ -This module add "Product Pack" funcionality to sale orders. For prouct you can add some other product to sell with them, in the sale order you choose the product and then automaticaly added the products that set in Product selected. +This module add "Product Pack" funcionality to sale orders. For product you can add some other product to sell with them, in the sale order you choose the product and then automaticaly added the products that set in Product selected. + +TODO: check modifications of this fork https://github.com/mohamedhagag/dvit-odoo/tree/10.0/product_pack Installation ============ @@ -15,7 +25,6 @@ To install this module, you need to: #. Just install this module. - Configuration ============= @@ -24,8 +33,6 @@ To configure this module, you need to: #. Go to product and set "Product Pack", then set the products has to include in the product pack of the product. #. Set type of product pack. - - Usage ===== @@ -33,14 +40,9 @@ To use this module, you need to: #. Create an sale order and set product that has product pack choosed. - .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.adhoc.com.ar/ - -.. repo_id is available in https://github.com/OCA/maintainer-tools/blob/master/tools/repos_with_ids.txt -.. branch is "9.0" for example - + :alt: Try me on Runbot + :target: http://runbot.adhoc.com.ar/ Bug Tracker =========== @@ -56,19 +58,16 @@ Credits Images ------ -* ADHOC SA: `Icon `_. +* |company| |icon| Contributors ------------ - Maintainer ---------- -.. image:: http://fotos.subefotos.com/83fed853c1e15a8023b86b2b22d6145bo.png - :alt: Odoo Community Association - :target: https://www.adhoc.com.ar +|company_logo| -This module is maintained by the ADHOC SA. +This module is maintained by the |company|. To contribute to this module, please visit https://www.adhoc.com.ar. diff --git a/product_pack/__init__.py b/product_pack/__init__.py old mode 100755 new mode 100644 index 0b941ea4bc7..d0337769245 --- a/product_pack/__init__.py +++ b/product_pack/__init__.py @@ -1,5 +1,5 @@ -# -*- encoding: utf-8 -*- ############################################################################## -# For copyright and license notices, see __manifest__.py file in root directory +# For copyright and license notices, see __manifest__.py file in module root +# directory ############################################################################## from . import models diff --git a/product_pack/__manifest__.py b/product_pack/__manifest__.py index 189b4654c60..a0173b34b31 100644 --- a/product_pack/__manifest__.py +++ b/product_pack/__manifest__.py @@ -19,7 +19,7 @@ ############################################################################## { 'name': 'Product Pack', - 'version': '9.0.1.3.0', + 'version': '11.0.1.0.0', 'category': 'Product', 'sequence': 14, 'summary': '', @@ -32,15 +32,18 @@ ], 'data': [ 'security/ir.model.access.csv', - 'views/pack_view.xml', - 'views/sale_view.xml', + 'views/product_pack_line_views.xml', + 'views/product_product_views.xml', + 'views/product_template_views.xml', + 'views/sale_order_line_pack_line_views.xml', + 'views/sale_order_line_views.xml', + 'views/sale_order_views.xml', ], 'demo': [ - 'demo/demo_data.xml', + 'demo/product_product_demo.xml', + 'demo/product_pack_line_demo.xml', ], - 'test': [ - ], - 'installable': False, + 'installable': True, 'auto_install': False, 'application': False, } diff --git a/product_pack/demo/demo_data.xml b/product_pack/demo/demo_data.xml deleted file mode 100644 index c6079a188c3..00000000000 --- a/product_pack/demo/demo_data.xml +++ /dev/null @@ -1,302 +0,0 @@ - - - - - - Pack CPU (Detailed Components Price) - - - components_price - 20.5 - 30.75 - service - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Pack CPU (Detailed Totaliced Price) - - - totalice_price - 20.5 - 30.75 - service - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Pack CPU (Detailed Fixed Price) - - - fixed_price - 20.5 - 30.75 - service - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Pack CPU (None Detailed Assisted Price) - - - none_detailed_assited_price - 20.5 - 30.75 - service - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Pack CPU (None Detailed Totaliced Price) - - - none_detailed_totaliced_price - 20.5 - 30.75 - service - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Pack PC (Detailed Components Price) - - - components_price - 20.5 - 30.75 - service - - - - - - - - - - - - - - - - - - - - Pack PC (Detailed Totaliced Price) - - - totalice_price - 20.5 - 30.75 - service - - - - - - - - - - - - - - - - - - - - Pack PC (Detailed Totaliced Price) - - - totalice_price - 20.5 - 30.75 - service - - - - - - - - - - - - - - - - - - - - Pack PC (Detailed Fixed Price) - - - fixed_price - 20.5 - 30.75 - service - - - - - - - - - - - - - - - - - - - - diff --git a/product_pack/demo/product_pack_line_demo.xml b/product_pack/demo/product_pack_line_demo.xml new file mode 100644 index 00000000000..48e5773c215 --- /dev/null +++ b/product_pack/demo/product_pack_line_demo.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product_pack/demo/product_product_demo.xml b/product_pack/demo/product_product_demo.xml new file mode 100644 index 00000000000..2b95b17e451 --- /dev/null +++ b/product_pack/demo/product_product_demo.xml @@ -0,0 +1,89 @@ + + + + Pack CPU (Detailed Components Price) + + + components_price + 20.5 + 30.75 + service + + + + + Pack CPU (Detailed Totaliced Price) + + + totalice_price + 20.5 + 30.75 + service + + + + + Pack CPU (Detailed Fixed Price) + + + fixed_price + 20.5 + 30.75 + service + + + + + Pack CPU (None Detailed Assisted Price) + + + none_detailed_assited_price + 20.5 + 30.75 + service + + + + + Pack CPU (None Detailed Totaliced Price) + + + none_detailed_totaliced_price + 20.5 + 30.75 + service + + + + + Pack PC (Detailed Components Price) + + + components_price + 20.5 + 30.75 + service + + + + + Pack PC (Detailed Totaliced Price) + + + totalice_price + 20.5 + 30.75 + service + + + + + Pack PC (Detailed Fixed Price) + + + fixed_price + 20.5 + 30.75 + service + + diff --git a/product_pack/models/__init__.py b/product_pack/models/__init__.py old mode 100755 new mode 100644 index 2fc98449d22..c601b48180e --- a/product_pack/models/__init__.py +++ b/product_pack/models/__init__.py @@ -1,10 +1,11 @@ -# -*- encoding: utf-8 -*- ############################################################################## -# For copyright and license notices, see __manifest__.py file in root directory +# For copyright and license notices, see __manifest__.py file in module root +# directory ############################################################################## -from . import pack -from . import product +from . import product_pack_line +from . import product_product +from . import product_template from . import sale_order_line_pack_line from . import sale_order_line from . import sale_order diff --git a/product_pack/models/product.py b/product_pack/models/product.py deleted file mode 100644 index ab48a3a190e..00000000000 --- a/product_pack/models/product.py +++ /dev/null @@ -1,215 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# For copyright and license notices, see __manifest__.py file in root directory -############################################################################## -from odoo import fields, models, api, _ -from odoo.osv import fields as old_fields -from odoo.exceptions import UserError -import math - - -class ProductProduct(models.Model): - _inherit = 'product.product' - - pack_line_ids = fields.One2many( - 'product.pack.line', - 'parent_product_id', - 'Pack Products', - help='List of products that are part of this pack.' - ) - used_pack_line_ids = fields.One2many( - 'product.pack.line', - 'product_id', - 'On Packs', - help='List of packs where product is used.' - ) - - def _product_available( - self, cr, uid, ids, field_names=None, arg=False, context=None): - """ - For product packs we get availability in a different way - """ - pack_product_ids = self.search(cr, uid, [ - ('pack', '=', True), - ('id', 'in', ids), - ]) - res = super(ProductProduct, self)._product_available( - cr, uid, list(set(ids) - set(pack_product_ids)), - field_names, arg, context) - for product in self.browse(cr, uid, pack_product_ids, context=context): - pack_qty_available = [] - pack_virtual_available = [] - for subproduct in product.pack_line_ids: - subproduct_stock = self._product_available( - cr, uid, [subproduct.product_id.id], field_names, arg, - context)[subproduct.product_id.id] - sub_qty = subproduct.quantity - if sub_qty: - pack_qty_available.append(math.floor( - subproduct_stock['qty_available'] / sub_qty)) - pack_virtual_available.append(math.floor( - subproduct_stock['virtual_available'] / sub_qty)) - # TODO calcular correctamente pack virtual available para negativos - res[product.id] = { - 'qty_available': ( - pack_qty_available and min(pack_qty_available) or False), - 'incoming_qty': 0, - 'outgoing_qty': 0, - 'virtual_available': ( - pack_virtual_available and - max(min(pack_virtual_available), 0) or False), - } - return res - - def _search_product_quantity(self, cr, uid, obj, name, domain, context): - """ - We use original search function - """ - return super(ProductProduct, self)._search_product_quantity( - cr, uid, obj, name, domain, context) - - # overwrite ot this fields so that we can modify _product_available - # function to support packs - _columns = { - 'qty_available': old_fields.function( - _product_available, multi='qty_available', - fnct_search=_search_product_quantity), - 'virtual_available': old_fields.function( - _product_available, multi='qty_available', - fnct_search=_search_product_quantity), - 'incoming_qty': old_fields.function( - _product_available, multi='qty_available', - fnct_search=_search_product_quantity), - 'outgoing_qty': old_fields.function( - _product_available, multi='qty_available', - fnct_search=_search_product_quantity), - } - - @api.multi - @api.constrains('pack_line_ids') - def check_recursion(self): - """ - Check recursion on packs - """ - for rec in self: - pack_lines = rec.pack_line_ids - while pack_lines: - if rec in pack_lines.mapped('product_id'): - raise UserError(_( - 'Error! You cannot create recursive packs.\n' - 'Product id: %s') % rec.id) - pack_lines = pack_lines.mapped('product_id.pack_line_ids') - - -class ProductTemplate(models.Model): - _inherit = 'product.template' - - # TODO rename a pack_type - pack_price_type = fields.Selection([ - ('components_price', 'Detailed - Components Prices'), - ('totalice_price', 'Detailed - Totaliced Price'), - ('fixed_price', 'Detailed - Fixed Price'), - ('none_detailed_assited_price', 'None Detailed - Assisted Price'), - ('none_detailed_totaliced_price', 'None Detailed - Totaliced Price'), - ], - 'Pack Type', - help="* Detailed - Components Prices: Detail lines with prices on " - "sales order.\n" - "* Detailed - Totaliced Price: Detail lines on sales order totalicing " - "lines prices on pack (don't show component prices).\n" - "* Detailed - Fixed Price: Detail lines on sales order and use product" - " pack price (ignore line prices).\n" - "* None Detailed - Assisted Price: Do not detail lines on sales " - "order. Assist to get pack price using pack lines." - ) - pack = fields.Boolean( - 'Pack?', - help='Is a Product Pack?', - ) - pack_line_ids = fields.One2many( - related='product_variant_ids.pack_line_ids' - ) - used_pack_line_ids = fields.One2many( - related='product_variant_ids.used_pack_line_ids' - ) - - @api.multi - @api.constrains( - 'product_variant_ids', 'pack_price_type') - def check_relations(self): - """ - Check assited packs dont have packs a childs - """ - # check assited price has no packs child of them - for rec in self: - if rec.pack_price_type == 'none_detailed_assited_price': - child_packs = rec.mapped( - 'pack_line_ids.product_id').filtered('pack') - if child_packs: - raise UserError(_( - 'A "None Detailed - Assisted Price Pack" can not have ' - 'a pack as a child!')) - - # TODO we also should check this - # check if we are configuring a pack for a product that is partof a - # assited pack - # if self.pack: - # for product in self.product_variant_ids - # parent_assited_packs = self.env['product.pack.line'].search([ - # ('product_id', '=', self.id), - # ('parent_product_id.pack_price_type', '=', - # 'none_detailed_assited_price'), - # ]) - # print 'parent_assited_packs', parent_assited_packs - # if parent_assited_packs: - # raise Warning(_( - # 'You can not set this product as pack because it is part' - # ' of a "None Detailed - Assisted Price Pack"')) - - @api.multi - @api.constrains('company_id', 'product_variant_ids') - def check_pack_line_company(self): - """ - Check packs are related to packs of same company - """ - for rec in self: - for line in rec.pack_line_ids: - if line.product_id.company_id != rec.company_id: - raise UserError(_( - 'Pack lines products company must be the same as the ' - 'parent product company')) - for line in rec.used_pack_line_ids: - if line.parent_product_id.company_id != rec.company_id: - raise UserError(_( - 'Pack lines products company must be the same as the ' - 'parent product company')) - - @api.multi - def write(self, vals): - """ - We remove from prod.prod to avoid error - """ - if vals.get('pack_line_ids', False): - self.product_variant_ids.write( - {'pack_line_ids': vals.pop('pack_line_ids')}) - return super(ProductTemplate, self).write(vals) - - @api.model - def _price_get(self, products, ptype='list_price'): - res = super(ProductTemplate, self)._price_get( - products, ptype=ptype) - for product in products: - if ( - product.pack and - product.pack_price_type in [ - 'totalice_price', - 'none_detailed_assited_price', - 'none_detailed_totaliced_price']): - pack_price = 0.0 - for pack_line in product.pack_line_ids: - product_line_price = pack_line.product_id.price_get()[ - pack_line.product_id.id] * ( - 1 - (pack_line.discount or 0.0) / 100.0) - pack_price += (product_line_price * pack_line.quantity) - res[product.id] = pack_price - return res diff --git a/product_pack/models/pack.py b/product_pack/models/product_pack_line.py old mode 100755 new mode 100644 similarity index 87% rename from product_pack/models/pack.py rename to product_pack/models/product_pack_line.py index a36ceea6a96..1a2cb8f998b --- a/product_pack/models/pack.py +++ b/product_pack/models/product_pack_line.py @@ -1,6 +1,6 @@ -# -*- encoding: utf-8 -*- ############################################################################## -# For copyright and license notices, see __manifest__.py file in root directory +# For copyright and license notices, see __manifest__.py file in module root +# directory ############################################################################## from odoo import fields, models, api import odoo.addons.decimal_precision as dp @@ -14,10 +14,10 @@ class ProductPack(models.Model): 'product.product', 'Parent Product', ondelete='cascade', + index=True, required=True ) quantity = fields.Float( - 'Quantity', required=True, default=1.0, digits=dp.get_precision('Product UoS'), @@ -26,6 +26,7 @@ class ProductPack(models.Model): 'product.product', 'Product', ondelete='cascade', + index=True, required=True, ) discount = fields.Float( @@ -53,11 +54,14 @@ def get_sale_order_line_vals(self, line, order): discount = 0.0 else: pricelist = order.pricelist_id.id - price = self.env['product.pricelist'].price_get( - subproduct.id, quantity, - order.partner_id.id, context={ + price = self.env['product.pricelist'].with_context( + context={ 'uom': subproduct.uom_id.id, - 'date': order.date_order})[pricelist] + 'date': order.date_order, + } + ).price_get( + subproduct.id, quantity, + order.partner_id.id)[pricelist] discount = self.discount # Obtain product name in partner's language @@ -89,9 +93,4 @@ def get_sale_order_line_vals(self, line, order): 'pack_parent_line_id': line.id, 'pack_depth': line.pack_depth + 1, } - - tmp_line = self.env['sale.order.line'].new(vals) - tmp_line.product_id_change() - vals['name'] = '%s%s' % ( - '> ' * (line.pack_depth + 1), tmp_line.name) return vals diff --git a/product_pack/models/product_product.py b/product_pack/models/product_product.py new file mode 100644 index 00000000000..4cd9f016b0d --- /dev/null +++ b/product_pack/models/product_product.py @@ -0,0 +1,88 @@ +############################################################################## +# For copyright and license notices, see __manifest__.py file in module root +# directory +############################################################################## +from odoo import fields, models, api, _ +from odoo.exceptions import ValidationError +import math + + +class ProductProduct(models.Model): + _inherit = 'product.product' + + pack_line_ids = fields.One2many( + 'product.pack.line', + 'parent_product_id', + 'Pack Products', + help='List of products that are part of this pack.' + ) + used_pack_line_ids = fields.One2many( + 'product.pack.line', + 'product_id', + 'On Packs', + help='List of packs where product is used.' + ) + + @api.depends('stock_quant_ids', 'stock_move_ids') + def _compute_quantities(self): + packs = self.filtered('pack') + no_packs = (self + packs.mapped('pack_line_ids.product_id')) - packs + super(ProductProduct, no_packs)._compute_quantities() + for product in packs: + pack_qty_available = [] + pack_virtual_available = [] + for subproduct in product.pack_line_ids: + subproduct_stock = subproduct.product_id + sub_qty = subproduct.quantity + if sub_qty: + pack_qty_available.append(math.floor( + subproduct_stock.qty_available / sub_qty)) + pack_virtual_available.append(math.floor( + subproduct_stock.virtual_available / sub_qty)) + # TODO calcular correctamente pack virtual available para negativos + vals = { + 'qty_available': ( + pack_qty_available and min(pack_qty_available) or False), + 'incoming_qty': 0, + 'outgoing_qty': 0, + 'virtual_available': ( + pack_virtual_available and + max(min(pack_virtual_available), 0) or False), + } + product.update(vals) + # return res + + @api.constrains('pack_line_ids') + def check_recursion(self): + """ + Check recursion on packs + """ + for rec in self: + pack_lines = rec.pack_line_ids + while pack_lines: + if rec in pack_lines.mapped('product_id'): + raise ValidationError(_( + 'Error! You cannot create recursive packs.\n' + 'Product id: %s') % rec.id) + pack_lines = pack_lines.mapped('product_id.pack_line_ids') + + @api.multi + def price_compute(self, price_type, uom=False, currency=False, + company=False): + packs = self.filtered(lambda p: p.pack and p.pack_price_type in [ + 'totalice_price', + 'none_detailed_assited_price', + 'none_detailed_totaliced_price', + ]) + no_packs = (self | self.mapped('pack_line_ids.product_id')) - packs + prices = super(ProductProduct, no_packs).price_compute( + price_type, uom, currency, company) + for product in packs: + pack_price = 0.0 + for pack_line in product.pack_line_ids: + product_line_price = prices[ + pack_line.product_id.id] * ( + 1 - (pack_line.discount or 0.0) / 100.0) + pack_price += (product_line_price * pack_line.quantity) + prices[product.id] = pack_price + return prices diff --git a/product_pack/models/product_template.py b/product_pack/models/product_template.py new file mode 100644 index 00000000000..307343befca --- /dev/null +++ b/product_pack/models/product_template.py @@ -0,0 +1,100 @@ +############################################################################## +# For copyright and license notices, see __manifest__.py file in module root +# directory +############################################################################## +from odoo import fields, models, api, _ +from odoo.exceptions import ValidationError + + +class ProductTemplate(models.Model): + _inherit = 'product.template' + + # TODO rename a pack_type + pack_price_type = fields.Selection([ + ('components_price', 'Detailed - Components Prices'), + ('totalice_price', 'Detailed - Totaliced Price'), + ('fixed_price', 'Detailed - Fixed Price'), + ('none_detailed_assited_price', 'None Detailed - Assisted Price'), + ('none_detailed_totaliced_price', 'None Detailed - Totaliced Price'), + ], + 'Pack Type', + help="* Detailed - Components Prices: Detail lines with prices on " + "sales order.\n" + "* Detailed - Totaliced Price: Detail lines on sales order totalicing " + "lines prices on pack (don't show component prices).\n" + "* Detailed - Fixed Price: Detail lines on sales order and use product" + " pack price (ignore line prices).\n" + "* None Detailed - Assisted Price: Do not detail lines on sales " + "order. Assist to get pack price using pack lines." + ) + pack = fields.Boolean( + 'Pack?', + help='Is a Product Pack?', + ) + pack_line_ids = fields.One2many( + related='product_variant_ids.pack_line_ids', + readonly=True, + ) + used_pack_line_ids = fields.One2many( + related='product_variant_ids.used_pack_line_ids', + readonly=True, + ) + + @api.constrains( + 'product_variant_ids', 'pack_price_type') + def check_relations(self): + """ + Check assited packs dont have packs a childs + """ + # check assited price has no packs child of them + for rec in self: + if rec.pack_price_type == 'none_detailed_assited_price': + child_packs = rec.mapped( + 'pack_line_ids.product_id').filtered('pack') + if child_packs: + raise ValidationError(_( + 'A "None Detailed - Assisted Price Pack" can not have ' + 'a pack as a child!')) + + # TODO we also should check this + # check if we are configuring a pack for a product that is partof a + # assited pack + # if self.pack: + # for product in self.product_variant_ids + # parent_assited_packs = self.env['product.pack.line'].search([ + # ('product_id', '=', self.id), + # ('parent_product_id.pack_price_type', '=', + # 'none_detailed_assited_price'), + # ]) + # print 'parent_assited_packs', parent_assited_packs + # if parent_assited_packs: + # raise Warning(_( + # 'You can not set this product as pack because it is part' + # ' of a "None Detailed - Assisted Price Pack"')) + + @api.constrains('company_id', 'product_variant_ids') + def check_pack_line_company(self): + """ + Check packs are related to packs of same company + """ + for rec in self: + for line in rec.pack_line_ids: + if line.product_id.company_id != rec.company_id: + raise ValidationError(_( + 'Pack lines products company must be the same as the ' + 'parent product company')) + for line in rec.used_pack_line_ids: + if line.parent_product_id.company_id != rec.company_id: + raise ValidationError(_( + 'Pack lines products company must be the same as the ' + 'parent product company')) + + @api.multi + def write(self, vals): + """ + We remove from prod.prod to avoid error + """ + if vals.get('pack_line_ids', False): + self.product_variant_ids.write( + {'pack_line_ids': vals.pop('pack_line_ids')}) + return super(ProductTemplate, self).write(vals) diff --git a/product_pack/models/sale_order.py b/product_pack/models/sale_order.py index b39656c7f82..6284c4e98c9 100644 --- a/product_pack/models/sale_order.py +++ b/product_pack/models/sale_order.py @@ -1,6 +1,6 @@ -# -*- encoding: utf-8 -*- ############################################################################## -# For copyright and license notices, see __manifest__.py file in root directory +# For copyright and license notices, see __manifest__.py file in module root +# directory ############################################################################## from odoo import models, api @@ -8,7 +8,7 @@ class SaleOrder(models.Model): _inherit = 'sale.order' - @api.one + @api.multi def copy(self, default=None): sale_copy = super(SaleOrder, self).copy(default) # we unlink pack lines that should not be copied diff --git a/product_pack/models/sale_order_line.py b/product_pack/models/sale_order_line.py index e07283c8030..30933956f3b 100644 --- a/product_pack/models/sale_order_line.py +++ b/product_pack/models/sale_order_line.py @@ -1,6 +1,6 @@ -# -*- encoding: utf-8 -*- ############################################################################## -# For copyright and license notices, see __manifest__.py file in root directory +# For copyright and license notices, see __manifest__.py file in module root +# directory ############################################################################## from odoo import fields, models, api, _ @@ -10,8 +10,7 @@ class SaleOrderLine(models.Model): # Fields for sale order pack pack_total = fields.Float( - string='Pack total', - compute='_get_pack_total' + compute='_compute_pack_total' ) pack_line_ids = fields.One2many( 'sale.order.line.pack.line', @@ -20,7 +19,7 @@ class SaleOrderLine(models.Model): ) pack_type = fields.Selection( related='product_id.pack_price_type', - readonly=True + readonly=True, ) # Fields for common packs @@ -41,7 +40,6 @@ class SaleOrderLine(models.Model): 'Lines in pack' ) - @api.one @api.constrains('product_id', 'price_unit', 'product_uom_qty') def expand_pack_line(self): detailed_packs = ['components_price', 'totalice_price', 'fixed_price'] @@ -85,21 +83,21 @@ def action_pack_detail(self): } return view - @api.one @api.depends( 'pack_line_ids', 'pack_line_ids.price_subtotal', ) - def _get_pack_total(self): - pack_total = 0.0 - if self.pack_line_ids: - pack_total = sum(x.price_subtotal for x in self.pack_line_ids) - self.pack_total = pack_total + def _compute_pack_total(self): + for line in self: + pack_total = 0.0 + if line.pack_line_ids: + pack_total = sum(x.price_subtotal for x in line.pack_line_ids) + line.pack_total = pack_total - @api.one @api.onchange('pack_total') def _onchange_pack_line_ids(self): - self.price_unit = self.pack_total + for line in self: + line.price_unit = line.pack_total @api.constrains('product_id') def expand_none_detailed_pack(self): diff --git a/product_pack/models/sale_order_line_pack_line.py b/product_pack/models/sale_order_line_pack_line.py old mode 100755 new mode 100644 index ba4d02cc8d1..270c0d1db44 --- a/product_pack/models/sale_order_line_pack_line.py +++ b/product_pack/models/sale_order_line_pack_line.py @@ -1,6 +1,6 @@ -# -*- encoding: utf-8 -*- ############################################################################## -# For copyright and license notices, see __manifest__.py file in root directory +# For copyright and license notices, see __manifest__.py file in module root +# directory ############################################################################## from odoo import fields, models, api import odoo.addons.decimal_precision as dp @@ -14,6 +14,7 @@ class SaleOrderLinePackLine(models.Model): 'sale.order.line', 'Order Line', ondelete='cascade', + index=True, required=True ) product_id = fields.Many2one( @@ -31,7 +32,7 @@ class SaleOrderLinePackLine(models.Model): digits=dp.get_precision('Discount'), ) price_subtotal = fields.Float( - compute="_amount_line", + compute="_compute_price_subtotal", string='Subtotal', digits=dp.get_precision('Account') ) @@ -41,14 +42,14 @@ class SaleOrderLinePackLine(models.Model): required=True ) - @api.one @api.onchange('product_id') def onchange_product_id(self): - self.price_unit = self.product_id.lst_price + for line in self: + line.price_unit = line.product_id.lst_price - @api.one @api.depends('price_unit', 'product_uom_qty') - def _amount_line(self): - self.price_subtotal = ( - self.product_uom_qty * self.price_unit * - (1 - (self.discount or 0.0) / 100.0)) + def _compute_price_subtotal(self): + for line in self: + line.price_subtotal = ( + line.product_uom_qty * line.price_unit * + (1 - (line.discount or 0.0) / 100.0)) diff --git a/product_pack/security/ir.model.access.csv b/product_pack/security/ir.model.access.csv old mode 100755 new mode 100644 index 3e37e925737..6afe6221aca --- a/product_pack/security/ir.model.access.csv +++ b/product_pack/security/ir.model.access.csv @@ -1,5 +1,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_product_pack_line_manager,product.pack.line manager,model_product_pack_line,base.group_sale_manager,1,1,1,1 +access_product_pack_line_manager,product.pack.line manager,model_product_pack_line,sales_team.group_sale_manager,1,1,1,1 access_product_pack_line_all,product.pack.line,model_product_pack_line,,1,0,0,0 access_sale_order_line_pack_line_user,sale_order_line_pack_line_user,model_sale_order_line_pack_line,base.group_user,1,1,1,1 access_sale_order_line_pack_line_all,sale_order_line_pack_line_all,model_sale_order_line_pack_line,,1,0,0,0 diff --git a/product_pack/views/pack_view.xml b/product_pack/views/pack_view.xml deleted file mode 100755 index 3819ffbf487..00000000000 --- a/product_pack/views/pack_view.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - product.template.pack.form - product.template - - - - - - - - - -

You must save first to add pack lines

- -
-
-
-
- - - product.product.pack.form - product.product - - - - - - - - - - - - - - - - - product.pack.line.form - product.pack.line - form - -
- - - - - -
-
-
- - - product.pack.line.tree - product.pack.line - tree - - - - - - - - -
- - diff --git a/product_pack/views/product_pack_line_views.xml b/product_pack/views/product_pack_line_views.xml new file mode 100644 index 00000000000..90af0c8b6e5 --- /dev/null +++ b/product_pack/views/product_pack_line_views.xml @@ -0,0 +1,30 @@ + + + + product.pack.line.form + product.pack.line + form + +
+ + + + + +
+
+
+ + + product.pack.line.tree + product.pack.line + tree + + + + + + + + +
diff --git a/product_pack/views/product_product_views.xml b/product_pack/views/product_product_views.xml new file mode 100644 index 00000000000..3582a1eb148 --- /dev/null +++ b/product_pack/views/product_product_views.xml @@ -0,0 +1,19 @@ + + + + product.product.pack.form + product.product + + + + + + + + + + + + + + diff --git a/product_pack/views/product_template_views.xml b/product_pack/views/product_template_views.xml new file mode 100644 index 00000000000..c18aaa77fb8 --- /dev/null +++ b/product_pack/views/product_template_views.xml @@ -0,0 +1,22 @@ + + + + + product.template.pack.form + product.template + + + + + + + + + +

You must save first to add pack lines

+ +
+
+
+
+
diff --git a/product_pack/views/sale_order_line_pack_line_views.xml b/product_pack/views/sale_order_line_pack_line_views.xml new file mode 100644 index 00000000000..ebafd75bb2c --- /dev/null +++ b/product_pack/views/sale_order_line_pack_line_views.xml @@ -0,0 +1,17 @@ + + + + + sale.line.pack.line.tree + sale.order.line.pack.line + + + + + + + + + + + diff --git a/product_pack/views/sale_view.xml b/product_pack/views/sale_order_line_views.xml similarity index 50% rename from product_pack/views/sale_view.xml rename to product_pack/views/sale_order_line_views.xml index e81cd650c80..f1a61892a33 100644 --- a/product_pack/views/sale_view.xml +++ b/product_pack/views/sale_order_line_views.xml @@ -1,22 +1,5 @@ - - - - - - sale.line.pack.line.tree - sale.order.line.pack.line - - - - - - - - - - - + view.order.line.button sale.order.line @@ -49,23 +32,4 @@ - - - sale.order.form.inherit - sale.order - - - - - -