From b4fe66899a1fae908182a3a54752387af65148f4 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Tue, 21 Oct 2014 17:25:09 +0200 Subject: [PATCH 01/15] minimal work to make tests pass in v8 --- .../__init__.py | 0 .../__openerp__.py | 2 +- .../i18n/en_US.po | 0 .../i18n/framework_agreement_sourcing.pot | 0 .../model/__init__.py | 0 .../model/logistic_requisition.py | 0 .../logistic_requisition_cost_estimate.py | 0 .../model/logistic_requisition_source.py | 8 +- .../model/purchase.py | 0 .../model/sale_order.py | 0 .../security/ir.model.access.csv | 0 .../tests/__init__.py | 0 .../tests/common.py | 129 ++++++++++-------- .../tests/test_agreement_souce_line_to_po.py | 5 +- ...test_logistic_order_line_to_source_line.py | 0 .../view/requisition_view.xml | 0 .../wizard/__init__.py | 0 .../logistic_requisition_source_create_po.py | 3 +- ...stic_requisition_source_create_po_view.xml | 0 19 files changed, 78 insertions(+), 69 deletions(-) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/__init__.py (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/__openerp__.py (99%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/i18n/en_US.po (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/i18n/framework_agreement_sourcing.pot (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/model/__init__.py (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/model/logistic_requisition.py (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/model/logistic_requisition_cost_estimate.py (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/model/logistic_requisition_source.py (98%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/model/purchase.py (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/model/sale_order.py (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/security/ir.model.access.csv (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/tests/__init__.py (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/tests/common.py (54%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/tests/test_agreement_souce_line_to_po.py (97%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/tests/test_logistic_order_line_to_source_line.py (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/view/requisition_view.xml (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/wizard/__init__.py (100%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/wizard/logistic_requisition_source_create_po.py (99%) rename {__unported__/framework_agreement_sourcing => framework_agreement_sourcing}/wizard/logistic_requisition_source_create_po_view.xml (100%) diff --git a/__unported__/framework_agreement_sourcing/__init__.py b/framework_agreement_sourcing/__init__.py similarity index 100% rename from __unported__/framework_agreement_sourcing/__init__.py rename to framework_agreement_sourcing/__init__.py diff --git a/__unported__/framework_agreement_sourcing/__openerp__.py b/framework_agreement_sourcing/__openerp__.py similarity index 99% rename from __unported__/framework_agreement_sourcing/__openerp__.py rename to framework_agreement_sourcing/__openerp__.py index 62c03bdc..df9714c9 100644 --- a/__unported__/framework_agreement_sourcing/__openerp__.py +++ b/framework_agreement_sourcing/__openerp__.py @@ -59,7 +59,7 @@ ], 'demo': [], 'test': [], - 'installable': False, + 'installable': True, 'auto_install': False, 'license': 'AGPL-3', 'application': False, diff --git a/__unported__/framework_agreement_sourcing/i18n/en_US.po b/framework_agreement_sourcing/i18n/en_US.po similarity index 100% rename from __unported__/framework_agreement_sourcing/i18n/en_US.po rename to framework_agreement_sourcing/i18n/en_US.po diff --git a/__unported__/framework_agreement_sourcing/i18n/framework_agreement_sourcing.pot b/framework_agreement_sourcing/i18n/framework_agreement_sourcing.pot similarity index 100% rename from __unported__/framework_agreement_sourcing/i18n/framework_agreement_sourcing.pot rename to framework_agreement_sourcing/i18n/framework_agreement_sourcing.pot diff --git a/__unported__/framework_agreement_sourcing/model/__init__.py b/framework_agreement_sourcing/model/__init__.py similarity index 100% rename from __unported__/framework_agreement_sourcing/model/__init__.py rename to framework_agreement_sourcing/model/__init__.py diff --git a/__unported__/framework_agreement_sourcing/model/logistic_requisition.py b/framework_agreement_sourcing/model/logistic_requisition.py similarity index 100% rename from __unported__/framework_agreement_sourcing/model/logistic_requisition.py rename to framework_agreement_sourcing/model/logistic_requisition.py diff --git a/__unported__/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py b/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py similarity index 100% rename from __unported__/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py rename to framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py diff --git a/__unported__/framework_agreement_sourcing/model/logistic_requisition_source.py b/framework_agreement_sourcing/model/logistic_requisition_source.py similarity index 98% rename from __unported__/framework_agreement_sourcing/model/logistic_requisition_source.py rename to framework_agreement_sourcing/model/logistic_requisition_source.py index a0bf19d6..7e3aac69 100644 --- a/__unported__/framework_agreement_sourcing/model/logistic_requisition_source.py +++ b/framework_agreement_sourcing/model/logistic_requisition_source.py @@ -19,17 +19,15 @@ # ############################################################################## from itertools import chain + from openerp.osv import orm, fields from openerp.tools.translate import _ -from openerp.addons.framework_agreement.model.framework_agreement import\ - FrameworkAgreementObservable from openerp.addons.framework_agreement.utils import id_boilerplate - AGR_PROC = 'fw_agreement' -class logistic_requisition_source(orm.Model, FrameworkAgreementObservable): +class logistic_requisition_source(orm.Model): """Adds support of framework agreement to source line""" _inherit = "logistic.requisition.source" @@ -112,7 +110,7 @@ def _prepare_purchase_order(self, cr, uid, line, po_pricelist, context=None): data['fiscal_position'] = position data['origin'] = requisition.name data['date_order'] = requisition.date - # data['name'] = requisition.name + data['name'] = requisition.name data['consignee_id'] = requisition.consignee_id.id data['incoterm_id'] = requisition.incoterm_id.id data['incoterm_address'] = requisition.incoterm_address diff --git a/__unported__/framework_agreement_sourcing/model/purchase.py b/framework_agreement_sourcing/model/purchase.py similarity index 100% rename from __unported__/framework_agreement_sourcing/model/purchase.py rename to framework_agreement_sourcing/model/purchase.py diff --git a/__unported__/framework_agreement_sourcing/model/sale_order.py b/framework_agreement_sourcing/model/sale_order.py similarity index 100% rename from __unported__/framework_agreement_sourcing/model/sale_order.py rename to framework_agreement_sourcing/model/sale_order.py diff --git a/__unported__/framework_agreement_sourcing/security/ir.model.access.csv b/framework_agreement_sourcing/security/ir.model.access.csv similarity index 100% rename from __unported__/framework_agreement_sourcing/security/ir.model.access.csv rename to framework_agreement_sourcing/security/ir.model.access.csv diff --git a/__unported__/framework_agreement_sourcing/tests/__init__.py b/framework_agreement_sourcing/tests/__init__.py similarity index 100% rename from __unported__/framework_agreement_sourcing/tests/__init__.py rename to framework_agreement_sourcing/tests/__init__.py diff --git a/__unported__/framework_agreement_sourcing/tests/common.py b/framework_agreement_sourcing/tests/common.py similarity index 54% rename from __unported__/framework_agreement_sourcing/tests/common.py rename to framework_agreement_sourcing/tests/common.py index 6dd96189..917fe3de 100644 --- a/__unported__/framework_agreement_sourcing/tests/common.py +++ b/framework_agreement_sourcing/tests/common.py @@ -33,9 +33,15 @@ def setUp(self): """ super(CommonSourcingSetUp, self).setUp() self.commonsetUp() + + # classic API self.requisition_model = self.registry('logistic.requisition') self.requisition_line_model = self.registry('logistic.requisition.line') self.source_line_model = self.registry('logistic.requisition.source') + + # new API + self.Requisition = self.env['logistic.requisition'] + self.make_common_agreements() self.make_common_requisition() @@ -49,8 +55,6 @@ def make_common_requisition(self): 'date_delivery': start_date, 'date': start_date, 'user_id': self.uid, - 'budget_holder_id': self.uid, - 'finance_officer_id': self.uid, 'pricelist_id': self.ref('product.list0'), } agr_line = { @@ -58,14 +62,14 @@ def make_common_requisition(self): 'requested_qty': 100, 'requested_uom_id': self.ref('product.product_uom_unit'), 'date_delivery': self.now.strftime(DEFAULT_SERVER_DATE_FORMAT), - 'budget_tot_price': 100000000, + 'description': '/', } product_line = { 'product_id': self.ref('product.product_product_7'), 'requested_qty': 10, 'requested_uom_id': self.ref('product.product_uom_unit'), 'date_delivery': self.now.strftime(DEFAULT_SERVER_DATE_FORMAT), - 'budget_tot_price': 100000000, + 'description': '/', } other_line = { @@ -73,18 +77,14 @@ def make_common_requisition(self): 'requested_qty': 1, 'requested_uom_id': self.ref('product.product_uom_unit'), 'date_delivery': self.now.strftime(DEFAULT_SERVER_DATE_FORMAT), - 'budget_tot_price': 100000000, + 'description': '/', } - - requisition_id = logistic_requisition.create(self, req) - logistic_requisition.add_line(self, requisition_id, - agr_line) - logistic_requisition.add_line(self, requisition_id, - product_line) - logistic_requisition.add_line(self, requisition_id, - other_line) - self.requisition = self.requisition_model.browse(self.cr, self.uid, requisition_id) + self.requisition = self.Requisition.create(req) + self.requisition.onchange_consignee_id() + logistic_requisition.add_line(self, self.requisition, agr_line) + logistic_requisition.add_line(self, self.requisition, product_line) + logistic_requisition.add_line(self, self.requisition, other_line) def make_common_agreements(self): """Create two default agreements. @@ -106,50 +106,61 @@ def make_common_agreements(self): end_date = self.now + timedelta(days=20) end_date = end_date.strftime(DEFAULT_SERVER_DATE_FORMAT) # Agreement 1 - agr_id = self.agreement_model.create(cr, uid, - {'supplier_id': self.supplier_id, - 'product_id': self.product_id, - 'start_date': start_date, - 'end_date': end_date, - 'draft': False, - 'delay': 5, - 'quantity': 2000}) - - pl_id = self.agreement_pl_model.create(cr, uid, - {'framework_agreement_id': agr_id, - 'currency_id': self.ref('base.EUR')}) - self.agreement_line_model.create(cr, uid, - {'framework_agreement_pricelist_id': pl_id, - 'quantity': 0, - 'price': 77.0}) - - self.agreement_line_model.create(cr, uid, - {'framework_agreement_pricelist_id': pl_id, - 'quantity': 1000, - 'price': 30.0}) - - self.cheap_on_high_agreement = self.agreement_model.browse(cr, uid, agr_id) + agr_id = self.agreement_model.create({ + 'supplier_id': self.supplier_id, + 'product_id': self.product_id, + 'start_date': start_date, + 'end_date': end_date, + 'draft': False, + 'delay': 5, + 'quantity': 2000, + }).id + + pl_id = self.agreement_pl_model.create({ + 'framework_agreement_id': agr_id, + 'currency_id': self.ref('base.EUR') + }).id + + self.agreement_line_model.create({ + 'framework_agreement_pricelist_id': pl_id, + 'quantity': 0, + 'price': 77.0, + }) + + self.agreement_line_model.create({ + 'framework_agreement_pricelist_id': pl_id, + 'quantity': 1000, + 'price': 30.0, + }) + + self.cheap_on_high_agreement = self.agreement_model.browse(agr_id) # Agreement 2 - agr_id = self.agreement_model.create(cr, uid, - {'supplier_id': self.ref('base.res_partner_3'), - 'product_id': self.product_id, - 'start_date': start_date, - 'end_date': end_date, - 'draft': False, - 'delay': 5, - 'quantity': 1200}) - - pl_id = self.agreement_pl_model.create(cr, uid, - {'framework_agreement_id': agr_id, - 'currency_id': self.ref('base.EUR')}) - - self.agreement_line_model.create(cr, uid, - {'framework_agreement_pricelist_id': pl_id, - 'quantity': 0, - 'price': 50.0}) - self.agreement_line_model.create(cr, uid, - {'framework_agreement_pricelist_id': pl_id, - 'quantity': 1000, - 'price': 45.0}) - self.cheap_on_low_agreement = self.agreement_model.browse(cr, uid, agr_id) + agr_id = self.agreement_model.create({ + 'supplier_id': self.ref('base.res_partner_3'), + 'product_id': self.product_id, + 'start_date': start_date, + 'end_date': end_date, + 'draft': False, + 'delay': 5, + 'quantity': 1200, + }).id + + pl_id = self.agreement_pl_model.create({ + 'framework_agreement_id': agr_id, + 'currency_id': self.ref('base.EUR'), + }).id + + self.agreement_line_model.create({ + 'framework_agreement_pricelist_id': pl_id, + 'quantity': 0, + 'price': 50.0, + }) + + self.agreement_line_model.create({ + 'framework_agreement_pricelist_id': pl_id, + 'quantity': 1000, + 'price': 45.0, + }) + + self.cheap_on_low_agreement = self.agreement_model.browse(agr_id) diff --git a/__unported__/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py b/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py similarity index 97% rename from __unported__/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py rename to framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py index cdaae23d..f415774e 100644 --- a/__unported__/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py +++ b/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py @@ -60,8 +60,9 @@ def test_01_transform_source_to_agreement(self): context={'active_ids': active_ids}) wiz = self.wiz_model.browse(self.cr, self.uid, wiz_id) - po_id = wiz.action_create_agreement_po_requisition( - context={'active_ids': active_ids} + + po_id = self.wiz_model.action_create_agreement_po_requisition( + cr, uid, [wiz_id], context={'active_ids': active_ids} )['res_id'] self.assertTrue(po_id) supplier = self.lta_source.framework_agreement_id.supplier_id diff --git a/__unported__/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py b/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py similarity index 100% rename from __unported__/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py rename to framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py diff --git a/__unported__/framework_agreement_sourcing/view/requisition_view.xml b/framework_agreement_sourcing/view/requisition_view.xml similarity index 100% rename from __unported__/framework_agreement_sourcing/view/requisition_view.xml rename to framework_agreement_sourcing/view/requisition_view.xml diff --git a/__unported__/framework_agreement_sourcing/wizard/__init__.py b/framework_agreement_sourcing/wizard/__init__.py similarity index 100% rename from __unported__/framework_agreement_sourcing/wizard/__init__.py rename to framework_agreement_sourcing/wizard/__init__.py diff --git a/__unported__/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py b/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py similarity index 99% rename from __unported__/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py rename to framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py index 9a796484..0c3ef60e 100644 --- a/__unported__/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py +++ b/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py @@ -18,7 +18,6 @@ # along with this program. If not, see . # ############################################################################## - from openerp.osv import orm, fields from openerp.tools.translate import _ @@ -59,7 +58,7 @@ def default_get(self, cr, uid, fields_list, context=None): uid, line.requisition_id.pricelist_id.currency_id.id, context=context - ) + ).id defaults['pricelist_id'] = pricelist_id frwk_ids = fmwk_price_obj.search( diff --git a/__unported__/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po_view.xml b/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po_view.xml similarity index 100% rename from __unported__/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po_view.xml rename to framework_agreement_sourcing/wizard/logistic_requisition_source_create_po_view.xml From abbebb03577e1b2b28fa789c1f166325726aed76 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Wed, 22 Oct 2014 18:19:22 +0200 Subject: [PATCH 02/15] autopep8 --- framework_agreement_sourcing/__openerp__.py | 6 ++-- .../model/logistic_requisition.py | 16 +++++---- .../logistic_requisition_cost_estimate.py | 8 +++-- .../model/logistic_requisition_source.py | 35 +++++++++++-------- .../model/purchase.py | 10 +++--- .../model/sale_order.py | 6 ++-- framework_agreement_sourcing/tests/common.py | 3 +- .../tests/test_agreement_souce_line_to_po.py | 18 ++++++---- ...test_logistic_order_line_to_source_line.py | 28 +++++++++------ .../logistic_requisition_source_create_po.py | 26 +++++++------- 10 files changed, 92 insertions(+), 64 deletions(-) diff --git a/framework_agreement_sourcing/__openerp__.py b/framework_agreement_sourcing/__openerp__.py index df9714c9..f17f33a5 100644 --- a/framework_agreement_sourcing/__openerp__.py +++ b/framework_agreement_sourcing/__openerp__.py @@ -53,9 +53,9 @@ """, 'website': 'http://www.camptocamp.com', 'data': [ - 'view/requisition_view.xml', - 'wizard/logistic_requisition_source_create_po_view.xml', - 'security/ir.model.access.csv' + 'view/requisition_view.xml', + 'wizard/logistic_requisition_source_create_po_view.xml', + 'security/ir.model.access.csv' ], 'demo': [], 'test': [], diff --git a/framework_agreement_sourcing/model/logistic_requisition.py b/framework_agreement_sourcing/model/logistic_requisition.py index 941fd977..581e0beb 100644 --- a/framework_agreement_sourcing/model/logistic_requisition.py +++ b/framework_agreement_sourcing/model/logistic_requisition.py @@ -25,13 +25,14 @@ class logistic_requisition_line(orm.Model): + """Override to enable generation of source line""" _inherit = "logistic.requisition.line" def _prepare_line_source(self, cr, uid, line, - qty=None, agreement=None, - context=None): + qty=None, agreement=None, + context=None): """Prepare data dict for source line creation. If an agreement is given, the procurement_method will be an LTA (AGR_PROC). Otherwise, if it's a stockable product we'll go to tender @@ -55,12 +56,13 @@ def _prepare_line_source(self, cr, uid, line, res['framework_agreement_id'] = False if agreement: if not agreement.product_id.id == line.product_id.id: - raise ValueError("Product mismatch for agreement and requisition line") + raise ValueError( + "Product mismatch for agreement and requisition line") res['framework_agreement_id'] = agreement.id res['procurement_method'] = AGR_PROC else: if line.product_id.type == 'product': - res['procurement_method'] = 'procurement' + res['procurement_method'] = 'procurement' else: res['procurement_method'] = 'other' return res @@ -188,9 +190,9 @@ def make_source_line(self, cr, uid, line, force_qty=None, agreement=None, contex qty = force_qty if force_qty else line.requested_qty src_obj = self.pool['logistic.requisition.source'] vals = self._prepare_line_source(cr, uid, line, - qty=qty, - agreement=agreement, - context=None) + qty=qty, + agreement=agreement, + context=None) return src_obj.create(cr, uid, vals, context=context) def _generate_source_line(self, cr, uid, line, context=None): diff --git a/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py b/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py index 5ef8a208..cb655a16 100644 --- a/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py +++ b/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py @@ -24,11 +24,11 @@ class logistic_requisition_cost_estimate(orm.Model): + """Add update of agreement price""" _inherit = "logistic.requisition.cost.estimate" - def _prepare_cost_estimate_line(self, cr, uid, sourcing, context=None): """Override in order to update agreement source line @@ -64,7 +64,8 @@ def _link_po_lines_to_so_lines(self, cr, uid, so, sources, context=None): _('Please add one')) for po_line in po_lines: key = po_line.product_id.id if po_line.product_id else False - po_line.write({'sale_order_line_id': product_dict.get(key, default)}) + po_line.write( + {'sale_order_line_id': product_dict.get(key, default)}) def cost_estimate(self, cr, uid, ids, context=None): """Override to link PO to cost_estimate$ @@ -95,5 +96,6 @@ def cost_estimate(self, cr, uid, ids, context=None): po_model.write(cr, uid, list(po_ids), {'sale_id': so_id, 'sale_flow': 'direct_delivery'}) - self._link_po_lines_to_so_lines(cr, uid, order, sources, context=context) + self._link_po_lines_to_so_lines( + cr, uid, order, sources, context=context) return res diff --git a/framework_agreement_sourcing/model/logistic_requisition_source.py b/framework_agreement_sourcing/model/logistic_requisition_source.py index 7e3aac69..30e89da7 100644 --- a/framework_agreement_sourcing/model/logistic_requisition_source.py +++ b/framework_agreement_sourcing/model/logistic_requisition_source.py @@ -1,4 +1,4 @@ - # -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- ############################################################################## # # Author: Nicolas Bessi @@ -28,6 +28,7 @@ class logistic_requisition_source(orm.Model): + """Adds support of framework agreement to source line""" _inherit = "logistic.requisition.source" @@ -73,7 +74,7 @@ def _get_purchase_line_id(self, cr, uid, ids, field_name, arg, context=None): res[line.id] = False return res - #------------------ adapting source line to po ----------------------------- + #------------------ adapting source line to po --------------------------- def _company(self, cr, uid, context): """Return company id @@ -118,7 +119,7 @@ def _prepare_purchase_order(self, cr, uid, line, po_pricelist, context=None): return data def _prepare_purchase_order_line(self, cr, uid, po_id, line, - po_supplier, po_pricelist, context=None): + po_supplier, po_pricelist, context=None): """Prepare the dict of values to create the PO Line from args. :param integer po_id: ids of purchase.order @@ -134,7 +135,8 @@ def _prepare_purchase_order_line(self, cr, uid, po_id, line, currency = po_pricelist.currency_id if line.framework_agreement_id: - price = line.framework_agreement_id.get_price(line.proposed_qty, currency=currency) + price = line.framework_agreement_id.get_price( + line.proposed_qty, currency=currency) lead_time = line.framework_agreement_id.delay supplier = line.framework_agreement_id.supplier_id data['framework_agreement_id'] = line.framework_agreement_id.id @@ -160,7 +162,7 @@ def _prepare_purchase_order_line(self, cr, uid, po_id, line, data['product_qty'] = line.proposed_qty data['product_id'] = line.proposed_product_id.id data['product_uom'] = line.proposed_uom_id.id - data['lr_source_line_id']= line.id + data['lr_source_line_id'] = line.id data['product_lead_time'] = lead_time data['price_unit'] = price data['name'] = line.proposed_product_id.name @@ -194,20 +196,21 @@ def _make_po_from_source_lines(self, cr, uid, main_source, other_sources, supplier = main_source.framework_agreement_id.supplier_id to_curr = pricelist.currency_id.id po_vals = self._prepare_purchase_order(cr, uid, main_source, - pricelist, context=context) + pricelist, context=context) po_id = po_obj.create(cr, uid, po_vals, context=context) other_sources = other_sources if other_sources else [] for source in chain([main_source], other_sources): line_vals = self._prepare_purchase_order_line(cr, uid, po_id, - source, supplier, - pricelist, context=context) + source, supplier, + pricelist, context=context) po_l_obj.create(cr, uid, line_vals, context=context) # TODO: Update LRS unit_cost from po line, with currency conversion from_curr = source.requisition_id.currency_id.id # Compute from bid currency to LRS currency price = currency_obj.compute(cr, uid, from_curr, to_curr, - line_vals['price_unit'], False) - source.write({'framework_agreement_po_id': po_id, 'unit_cost':price}) + line_vals['price_unit'], False) + source.write( + {'framework_agreement_po_id': po_id, 'unit_cost': price}) return po_id def make_purchase_order(self, cr, uid, ids, pricelist, context=None): @@ -230,7 +233,7 @@ def make_purchase_order(self, cr, uid, ids, pricelist, context=None): # LRS of type LTA (framework agreement) agreement_sources = [] # LRS of type other - other_sources = [] + other_sources = [] for source in sources: if source.procurement_method == AGR_PROC: agreement_sources.append(source) @@ -259,7 +262,7 @@ def _is_sourced_other(self, cr, uid, source, context=None): tender_ok = self._is_sourced_procurement(cr, uid, source, context=context) agr_ok = self._is_sourced_fw_agreement(cr, uid, source, - context=context) + context=context) return (tender_ok or agr_ok) def _is_sourced_fw_agreement(self, cr, uid, source, context=None): @@ -270,12 +273,13 @@ def _is_sourced_fw_agreement(self, cr, uid, source, context=None): """ po_line_obj = self.pool['purchase.order.line'] sources_ids = po_line_obj.search(cr, uid, - [('lr_source_line_id', '=', source.id)], + [('lr_source_line_id', '=', source.id) + ], context=context) # predicate return bool(sources_ids) - #---------------OpenERP tedious onchange management ------------------------ + #---------------OpenERP tedious onchange management ---------------------- def _get_date(self, cr, uid, requision_line_id, context=None): """helper to retrive date to be used by framework agreement @@ -362,7 +366,8 @@ def onchange_product_id(self, cr, uid, ids, method, req_line_id, value = {'proposed_uom_id': ''} if proposed_product_id: prod_obj = self.pool.get('product.product') - prod = prod_obj.browse(cr, uid, proposed_product_id, context=context) + prod = prod_obj.browse( + cr, uid, proposed_product_id, context=context) value = { 'proposed_uom_id': prod.uom_id.id, } diff --git a/framework_agreement_sourcing/model/purchase.py b/framework_agreement_sourcing/model/purchase.py index 0301467c..d3bde806 100644 --- a/framework_agreement_sourcing/model/purchase.py +++ b/framework_agreement_sourcing/model/purchase.py @@ -20,17 +20,19 @@ ############################################################################## from openerp.osv import orm + class purchase_order(orm.Model): + """ Override action_confirm to set quantity bid if LTA """ _inherit = "purchase.order" - def action_confirm(self, cr, uid, ids, context=None): - super(purchase_order_line, self).action_confirm(cr, uid, ids, context=context) + super(purchase_order_line, self).action_confirm( + cr, uid, ids, context=context) for element in self.browse(cr, uid, ids, context=context): if not element.quantity_bid and not element.framework_agreement_id: - self.write(cr, uid, ids, {'quantity_bid': element.product_qty}, context=context) + self.write( + cr, uid, ids, {'quantity_bid': element.product_qty}, context=context) return True - diff --git a/framework_agreement_sourcing/model/sale_order.py b/framework_agreement_sourcing/model/sale_order.py index e5099dbe..09fd38fc 100644 --- a/framework_agreement_sourcing/model/sale_order.py +++ b/framework_agreement_sourcing/model/sale_order.py @@ -24,6 +24,7 @@ class sale_order_line(orm.Model): + """Pass agreement PO into state confirmed when SO is confirmed""" _inherit = "sale.order.line" @@ -45,9 +46,10 @@ def source_valid(source): lines = self.browse(cr, uid, ids, context=context) source_ids = [x.logistic_requisition_source_id.id for x in lines - if source_valid(x.logistic_requisition_source_id)] + if source_valid(x.logistic_requisition_source_id)] po_line_ids = po_line_model.search(cr, uid, - [('lr_source_line_id', 'in', source_ids)], + [('lr_source_line_id', + 'in', source_ids)], context=context) po_lines = po_line_model.read(cr, uid, po_line_ids, ['order_id'], load='_classic_write') diff --git a/framework_agreement_sourcing/tests/common.py b/framework_agreement_sourcing/tests/common.py index 917fe3de..c3bba3b7 100644 --- a/framework_agreement_sourcing/tests/common.py +++ b/framework_agreement_sourcing/tests/common.py @@ -36,7 +36,8 @@ def setUp(self): # classic API self.requisition_model = self.registry('logistic.requisition') - self.requisition_line_model = self.registry('logistic.requisition.line') + self.requisition_line_model = self.registry( + 'logistic.requisition.line') self.source_line_model = self.registry('logistic.requisition.source') # new API diff --git a/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py b/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py index f415774e..5794f47b 100644 --- a/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py +++ b/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py @@ -29,7 +29,8 @@ def setUp(self): cr, uid = self.cr, self.uid lines = self.requisition.line_ids agr_line = None - self.wiz_model = self.registry('logistic.requisition.source.create.agr.po') + self.wiz_model = self.registry( + 'logistic.requisition.source.create.agr.po') for line in lines: if line.product_id == self.cheap_on_low_agreement.product_id: agr_line = line @@ -41,7 +42,8 @@ def setUp(self): for line in lines: if (line.product_id.id == self.product_id or line.product_id.type == 'service'): - lid = self.requisition_line_model._generate_source_line(cr, uid, line) + lid = self.requisition_line_model._generate_source_line( + cr, uid, line) source_ids += lid self.assertTrue(len(source_ids) == 2) self.source_lines = self.source_line_model.browse(cr, uid, source_ids) @@ -72,7 +74,8 @@ def test_01_transform_source_to_agreement(self): date_order = self.lta_source.requisition_id.date date_delivery = self.lta_source.requisition_id.date_delivery self.assertEqual(po.partner_id, supplier) - self.assertEqual(po.pricelist_id, supplier.property_product_pricelist_purchase) + self.assertEqual( + po.pricelist_id, supplier.property_product_pricelist_purchase) self.assertEqual(po.date_order, date_order) self.assertEqual(po.dest_address_id, add) self.assertEqual(po.consignee_id, consignee) @@ -83,7 +86,8 @@ def test_01_transform_source_to_agreement(self): po_line = next(x for x in po.order_line if x.product_id == self.lta_source.framework_agreement_id.product_id) self.assertEqual(po_line.product_qty, self.lta_source.proposed_qty) - self.assertEqual(po_line.product_id, self.lta_source.proposed_product_id) + self.assertEqual( + po_line.product_id, self.lta_source.proposed_product_id) self.assertEqual(po_line.product_qty, self.lta_source.proposed_qty) self.assertEqual(po_line.product_uom, self.lta_source.proposed_uom_id) self.assertAlmostEqual(po_line.price_unit, 50.0) @@ -93,8 +97,10 @@ def test_01_transform_source_to_agreement(self): po_line = next(x for x in po.order_line if x.product_id == self.other_source.proposed_product_id) self.assertEqual(po_line.product_qty, self.other_source.proposed_qty) - self.assertEqual(po_line.product_id, self.other_source.proposed_product_id) + self.assertEqual( + po_line.product_id, self.other_source.proposed_product_id) self.assertEqual(po_line.product_qty, self.other_source.proposed_qty) - self.assertEqual(po_line.product_uom, self.other_source.proposed_uom_id) + self.assertEqual( + po_line.product_uom, self.other_source.proposed_uom_id) self.assertAlmostEqual(po_line.price_unit, 1.0) self.assertEqual(po_line.lr_source_line_id, self.other_source) diff --git a/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py b/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py index 1ce135e3..ef05b946 100644 --- a/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py +++ b/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py @@ -36,9 +36,11 @@ def test_01_enough_qty_on_first_agr(self): self.assertTrue(agr_line) agr_line.write({'requested_qty': 400}) agr_line.refresh() - to_validate_ids = self.requisition_line_model._generate_source_line(cr, uid, agr_line) + to_validate_ids = self.requisition_line_model._generate_source_line( + cr, uid, agr_line) self.assertTrue(len(to_validate_ids) == 1) - to_validate = self.source_line_model.browse(cr, uid, to_validate_ids[0]) + to_validate = self.source_line_model.browse( + cr, uid, to_validate_ids[0]) self.assertEqual(to_validate.procurement_method, AGR_PROC) self.assertAlmostEqual(to_validate.unit_cost, 0.0) self.assertEqual(to_validate.proposed_qty, 400) @@ -55,9 +57,11 @@ def test_02_enough_qty_on_high_agr(self): self.assertTrue(agr_line) agr_line.write({'requested_qty': 1500}) agr_line.refresh() - to_validate_ids = self.requisition_line_model._generate_source_line(cr, uid, agr_line) + to_validate_ids = self.requisition_line_model._generate_source_line( + cr, uid, agr_line) self.assertTrue(len(to_validate_ids) == 1) - to_validate = self.source_line_model.browse(cr, uid, to_validate_ids[0]) + to_validate = self.source_line_model.browse( + cr, uid, to_validate_ids[0]) self.assertEqual(to_validate.procurement_method, AGR_PROC) self.assertAlmostEqual(to_validate.unit_cost, 0.0) self.assertEqual(to_validate.proposed_qty, 1500) @@ -74,14 +78,15 @@ def test_03_not_enough_qty_on_high_agreement(self): self.assertTrue(agr_line) agr_line.write({'requested_qty': 2400}) agr_line.refresh() - to_validate_ids = self.requisition_line_model._generate_source_line(cr, uid, agr_line) + to_validate_ids = self.requisition_line_model._generate_source_line( + cr, uid, agr_line) self.assertTrue(len(to_validate_ids) == 2) # We validate generated line to_validates = self.source_line_model.browse(cr, uid, to_validate_ids) # high_line # idiom taken from Python cookbook high_line = next((x for x in to_validates - if x.framework_agreement_id == self.cheap_on_high_agreement), None) + if x.framework_agreement_id == self.cheap_on_high_agreement), None) self.assertTrue(high_line, msg="High agreement was not used") self.assertEqual(high_line.procurement_method, AGR_PROC) self.assertEqual(high_line.proposed_qty, 2000) @@ -89,7 +94,7 @@ def test_03_not_enough_qty_on_high_agreement(self): # low_line low_line = next((x for x in to_validates - if x.framework_agreement_id == self.cheap_on_low_agreement), None) + if x.framework_agreement_id == self.cheap_on_low_agreement), None) self.assertTrue(low_line, msg="Low agreement was not used") self.assertEqual(low_line.procurement_method, AGR_PROC) self.assertEqual(low_line.proposed_qty, 400) @@ -110,14 +115,15 @@ def test_03_not_enough_qty_on_all_agreemenst(self): self.assertTrue(agr_line) agr_line.write({'requested_qty': 5000}) agr_line.refresh() - to_validate_ids = self.requisition_line_model._generate_source_line(cr, uid, agr_line) + to_validate_ids = self.requisition_line_model._generate_source_line( + cr, uid, agr_line) self.assertTrue(len(to_validate_ids) == 3) # We validate generated line to_validates = self.source_line_model.browse(cr, uid, to_validate_ids) # high_line # idiom taken from Python cookbook high_line = next((x for x in to_validates - if x.framework_agreement_id == self.cheap_on_high_agreement), None) + if x.framework_agreement_id == self.cheap_on_high_agreement), None) self.assertTrue(high_line, msg="High agreement was not used") self.assertEqual(high_line.procurement_method, AGR_PROC) self.assertEqual(high_line.proposed_qty, 2000) @@ -125,7 +131,7 @@ def test_03_not_enough_qty_on_all_agreemenst(self): # low_line low_line = next((x for x in to_validates - if x.framework_agreement_id == self.cheap_on_low_agreement), None) + if x.framework_agreement_id == self.cheap_on_low_agreement), None) self.assertTrue(low_line, msg="Low agreement was not used") self.assertEqual(low_line.procurement_method, AGR_PROC) self.assertEqual(low_line.proposed_qty, 1200) @@ -133,6 +139,6 @@ def test_03_not_enough_qty_on_all_agreemenst(self): # Tender line tender_line = next((x for x in to_validates - if not x.framework_agreement_id), None) + if not x.framework_agreement_id), None) self.assertTrue(tender_line, msg="Tender line was not generated") self.assertNotEqual(tender_line.procurement_method, AGR_PROC) diff --git a/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py b/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py index 0c3ef60e..5c6031e9 100644 --- a/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py +++ b/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py @@ -21,14 +21,15 @@ from openerp.osv import orm, fields from openerp.tools.translate import _ + class logistic_requisition_source_po_creator(orm.TransientModel): _name = 'logistic.requisition.source.create.agr.po' _columns = { 'pricelist_id': fields.many2one('product.pricelist', - string='Pricelist / Currency', - required=True), + string='Pricelist / Currency', + required=True), 'framework_currency_ids': fields.many2many('framework.agreement.pricelist', rel='framework_agr_id_po_create_rel', string='Available Currency', @@ -48,17 +49,17 @@ def default_get(self, cr, uid, fields_list, context=None): line_ids = context['active_ids'] pricelist_id = None line = next((x for x in line_obj.browse(cr, uid, line_ids, context=context) - if x.framework_agreement_id), None) + if x.framework_agreement_id), None) if not line: raise orm.except_orm(_('No sourcing line with agreement selected'), _('Please correct selection')) pricelist_id = line_obj._get_purchase_pricelist_from_currency( - cr, - uid, - line.requisition_id.pricelist_id.currency_id.id, - context=context - ).id + cr, + uid, + line.requisition_id.pricelist_id.currency_id.id, + context=context + ).id defaults['pricelist_id'] = pricelist_id frwk_ids = fmwk_price_obj.search( @@ -73,7 +74,7 @@ def _make_purchase_order(self, cr, uid, pricelist, source_ids, context=None): """Create PO from source line ids""" lr_model = self.pool['logistic.requisition.source'] po_id = lr_model.make_purchase_order(cr, uid, source_ids, - pricelist, context=context) + pricelist, context=context) return po_id def action_create_agreement_po_requisition(self, cr, uid, ids, context=None): @@ -81,15 +82,16 @@ def action_create_agreement_po_requisition(self, cr, uid, ids, context=None): act_obj = self.pool['ir.actions.act_window'] source_ids = context['active_ids'] form = self.browse(cr, uid, ids, context=context)[0] - pricelist=form.pricelist_id + pricelist = form.pricelist_id - available_currency = [x.currency_id for x in form.framework_currency_ids] + available_currency = [ + x.currency_id for x in form.framework_currency_ids] if available_currency and pricelist.currency_id not in available_currency: raise orm.except_orm(_('User Error'), _( 'You must chose a pricelist that is in the same currency ' 'than one of the available in the framework agreement.')) po_id = self._make_purchase_order(cr, uid, pricelist, source_ids, - context=context) + context=context) # TODO : update LRS price from PO depending on the chosen currency res = act_obj.for_xml_id(cr, uid, From b25532f217de3f65a09cc99016e7d6ed5a35bbd1 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Wed, 22 Oct 2014 18:31:46 +0200 Subject: [PATCH 03/15] manual lint --- .../model/logistic_requisition.py | 52 ++++---- .../logistic_requisition_cost_estimate.py | 3 +- .../model/logistic_requisition_source.py | 111 ++++++++++-------- .../model/purchase.py | 7 +- .../model/sale_order.py | 3 +- framework_agreement_sourcing/tests/common.py | 4 +- .../tests/test_agreement_souce_line_to_po.py | 8 +- ...test_logistic_order_line_to_source_line.py | 15 ++- .../logistic_requisition_source_create_po.py | 24 ++-- 9 files changed, 128 insertions(+), 99 deletions(-) diff --git a/framework_agreement_sourcing/model/logistic_requisition.py b/framework_agreement_sourcing/model/logistic_requisition.py index 581e0beb..2b1e7e9c 100644 --- a/framework_agreement_sourcing/model/logistic_requisition.py +++ b/framework_agreement_sourcing/model/logistic_requisition.py @@ -19,7 +19,6 @@ # ############################################################################## from collections import namedtuple -from openerp.tools.translate import _ from openerp.osv import orm from .logistic_requisition_source import AGR_PROC @@ -116,7 +115,8 @@ def _best_company_price(cr, uid, agreement, qty): return agreements def _generate_lines_from_agreements(self, cr, uid, container, line, - agreements, qty, currency=None, context=None): + agreements, qty, currency=None, + context=None): """Generate 1/n source line(s) for one requisition line. This is done using available agreements. @@ -147,23 +147,27 @@ def _generate_lines_from_agreements(self, cr, uid, container, line, to_consume = qty if avail_sold >= 0 else avail source_id = self.make_source_line(cr, uid, line, force_qty=to_consume, - agreement=current_agr, context=context) + agreement=current_agr, + context=context) container.append(source_id) difference = qty - to_consume if difference: - return self._generate_lines_from_agreements(cr, uid, container, line, - agreements, difference, + return self._generate_lines_from_agreements(cr, uid, container, + line, agreements, + difference, context=context) else: return 0 - def _source_lines_for_agreements(self, cr, uid, line, agreements, currency=None, context=None): + def _source_lines_for_agreements(self, cr, uid, line, agreements, + currency=None, context=None): """Generate 1/n source line(s) for one requisition line This is done using available agreements. We first look for cheapeast agreement. - Then if no more quantity are available and there is still remaining needs - we look for next cheapest agreement or we create a tender source line + Then if no more quantity are available and there is still remaining + needs we look for next cheapest agreement or we create a tender source + line :param line: requisition line browse record :returns: (generated line ids, remaining qty not covered by agreement) @@ -172,12 +176,15 @@ def _source_lines_for_agreements(self, cr, uid, line, agreements, currency=None, Sourced = namedtuple('Sourced', ['generated', 'remaining']) qty = line.requested_qty generated = [] - remaining_qty = self._generate_lines_from_agreements(cr, uid, generated, - line, agreements, qty, - currency=currency, context=context) + remaining_qty = self._generate_lines_from_agreements(cr, uid, + generated, line, + agreements, qty, + currency=currency, + context=context) return Sourced(generated, remaining_qty) - def make_source_line(self, cr, uid, line, force_qty=None, agreement=None, context=None): + def make_source_line(self, cr, uid, line, force_qty=None, agreement=None, + context=None): """Generate a source line from a requisition line, see _prepare_line_source for details. @@ -198,9 +205,9 @@ def make_source_line(self, cr, uid, line, force_qty=None, agreement=None, contex def _generate_source_line(self, cr, uid, line, context=None): """Generate one or n source line(s) per requisition line. - Depending on the available resources. If there is framework agreement(s) - running we generate one or n source line using agreements otherwise we generate one - source line using tender process + Depending on the available resources. If there is framework + agreement(s) running we generate one or n source line using agreements + otherwise we generate one source line using tender process :param line: browse record of origin logistic.request @@ -213,16 +220,17 @@ def _generate_source_line(self, cr, uid, line, context=None): date = line.requisition_id.date currency = line.currency_id product_id = line.product_id.id - agreements = agr_obj.get_all_product_agreements(cr, uid, product_id, date, + agreements = agr_obj.get_all_product_agreements(cr, uid, product_id, + date, context=context) generated_lines = [] if agreements: - line_ids, missing_qty = self._source_lines_for_agreements(cr, uid, line, - agreements, currency=currency) + line_ids, missing_qty = self._source_lines_for_agreements( + cr, uid, line, agreements, currency=currency) generated_lines.extend(line_ids) if missing_qty: - generated_lines.append(self.make_source_line(cr, uid, line, - force_qty=missing_qty)) + generated_lines.append(self.make_source_line( + cr, uid, line, force_qty=missing_qty)) else: generated_lines.append(self.make_source_line(cr, uid, line)) @@ -238,8 +246,8 @@ def _do_confirm(self, cr, uid, ids, context=None): # this should probably be in logistic_requisition module # providing a mechanism to allow each type of sourcing method # to generate source line - res = super(logistic_requisition_line, self)._do_confirm(cr, uid, ids, - context=context) + res = super(logistic_requisition_line, self)._do_confirm( + cr, uid, ids, context=context) for line_br in self.browse(cr, uid, ids, context=context): self._generate_source_line(cr, uid, line_br, context=context) return res diff --git a/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py b/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py index cb655a16..0f4ba4bf 100644 --- a/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py +++ b/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py @@ -90,7 +90,8 @@ def cost_estimate(self, cr, uid, ids, context=None): # gain of perfo will not worth readability loss # for such small data set sources = [x.logistic_requisition_source_id for x in order.order_line - if x and x.logistic_requisition_source_id.procurement_method == AGR_PROC] + if x and x.logistic_requisition_source_id.procurement_method + == AGR_PROC] po_ids = set(x.purchase_line_id.order_id.id for x in sources if x.purchase_line_id) po_model.write(cr, uid, list(po_ids), diff --git a/framework_agreement_sourcing/model/logistic_requisition_source.py b/framework_agreement_sourcing/model/logistic_requisition_source.py index 30e89da7..c78bd0aa 100644 --- a/framework_agreement_sourcing/model/logistic_requisition_source.py +++ b/framework_agreement_sourcing/model/logistic_requisition_source.py @@ -33,58 +33,62 @@ class logistic_requisition_source(orm.Model): _inherit = "logistic.requisition.source" - _columns = {'framework_agreement_id': fields.many2one('framework.agreement', - 'Agreement'), - 'framework_agreement_po_id': fields.many2one('purchase.order', - 'Agreement Purchase'), - 'supplier_id': fields.related('framework_agreement_id', 'supplier_id', - type='many2one', relation='res.partner', - string='Agreement Supplier')} + _columns = { + 'framework_agreement_id': fields.many2one('framework.agreement', + 'Agreement'), + 'framework_agreement_po_id': fields.many2one('purchase.order', + 'Agreement Purchase'), + 'supplier_id': fields.related('framework_agreement_id', 'supplier_id', + type='many2one', relation='res.partner', + string='Agreement Supplier')} def _get_procur_method_hook(self, cr, uid, context=None): - """Adds framework agreement as a procurement method in selection field""" - res = super(logistic_requisition_source, self)._get_procur_method_hook(cr, uid, - context=context) + """Adds framework agreement as a procurement method in selection + field""" + res = super(logistic_requisition_source, self)._get_procur_method_hook( + cr, uid, context=context) res.append((AGR_PROC, 'Framework agreement')) return res - def _get_purchase_line_id(self, cr, uid, ids, field_name, arg, context=None): + def _get_purchase_line_id(self, cr, uid, ids, field_name, arg, + context=None): """For each source line, get the related purchase order line For more detail please refer to function fields documentation """ po_line_model = self.pool['purchase.order.line'] - res = super(logistic_requisition_source, self)._get_purchase_line_id(cr, uid, ids, - field_name, - arg, - context=context) + res = super(logistic_requisition_source, self)._get_purchase_line_id( + cr, uid, ids, field_name, arg, context=context) for line in self.browse(cr, uid, ids, context=context): if line.procurement_method == AGR_PROC: - po_l_ids = po_line_model.search(cr, uid, - [('lr_source_line_id', '=', line.id), - ('state', '!=', 'cancel')], - context=context) + po_l_ids = po_line_model.search(cr, uid, [ + ('lr_source_line_id', '=', line.id), + ('state', '!=', 'cancel') + ], context=context) if po_l_ids: if len(po_l_ids) > 1: - raise orm.except_orm(_('Many Purchase order lines found for %s') % line.name, - _('Please cancel uneeded one')) + raise orm.except_orm( + _('Many Purchase order lines found for %s') + % line.name, + _('Please cancel uneeded one')) res[line.id] = po_l_ids[0] else: res[line.id] = False return res - #------------------ adapting source line to po --------------------------- + # ----------------- adapting source line to po -------------------------- def _company(self, cr, uid, context): """Return company id :returns: company id """ - return self.pool['res.company']._company_default_get(cr, uid, self._name, - context=context) + return self.pool['res.company']._company_default_get( + cr, uid, self._name, context=context) - def _prepare_purchase_order(self, cr, uid, line, po_pricelist, context=None): + def _prepare_purchase_order(self, cr, uid, line, po_pricelist, + context=None): """Prepare the dict of values to create the PO from a source line. @@ -145,18 +149,19 @@ def _prepare_purchase_order_line(self, cr, uid, po_id, line, lead_time = 0 price = 0.0 if po_pricelist: - price = pl_model.price_get(cr, uid, - [po_pricelist.id], - line.proposed_product_id.id, - line.proposed_qty or 1.0, - po_supplier.id, - {'uom': line.proposed_uom_id.id})[po_pricelist.id] + price = pl_model.price_get( + cr, uid, + [po_pricelist.id], + line.proposed_product_id.id, + line.proposed_qty or 1.0, + po_supplier.id, + {'uom': line.proposed_uom_id.id})[po_pricelist.id] if not price: price = line.proposed_product_id.standard_price or 1.00 taxes_ids = line.proposed_product_id.supplier_taxes_id - taxes = acc_pos_obj.map_tax(cr, uid, supplier.property_account_position, - taxes_ids) + taxes = acc_pos_obj.map_tax( + cr, uid, supplier.property_account_position, taxes_ids) data['order_id'] = po_id data['product_qty'] = line.proposed_qty @@ -202,7 +207,8 @@ def _make_po_from_source_lines(self, cr, uid, main_source, other_sources, for source in chain([main_source], other_sources): line_vals = self._prepare_purchase_order_line(cr, uid, po_id, source, supplier, - pricelist, context=context) + pricelist, + context=context) po_l_obj.create(cr, uid, line_vals, context=context) # TODO: Update LRS unit_cost from po line, with currency conversion from_curr = source.requisition_id.currency_id.id @@ -240,20 +246,24 @@ def make_purchase_order(self, cr, uid, ids, pricelist, context=None): elif source.procurement_method == 'other': other_sources.append(source) else: - raise orm.except_orm(_('Source line must be of type other or agreement'), - _('Please correct selection')) + raise orm.except_orm( + _('Source line must be of type other or agreement'), + _('Please correct selection')) main_source = agreement_sources[0] if agreement_sources else False if len(agreement_sources) > 1: raise orm.except_orm(_('There should be only one agreement line'), _('Please correct selection')) if not main_source: - raise orm.except_orm(_('There should be at least one agreement line'), - _('Please correct selection')) - fback = main_source.framework_agreement_id.supplier_id.property_product_pricelist_purchase + raise orm.except_orm( + _('There should be at least one agreement line'), + _('Please correct selection')) + + supplier = main_source.framework_agreement_id.supplier_id + fback = supplier.property_product_pricelist_purchase pricelist = pricelist if pricelist else fback - po_id = self._make_po_from_source_lines(cr, uid, main_source, - other_sources, pricelist, context=None) + po_id = self._make_po_from_source_lines( + cr, uid, main_source, other_sources, pricelist, context=None) return po_id def _is_sourced_other(self, cr, uid, source, context=None): @@ -279,7 +289,7 @@ def _is_sourced_fw_agreement(self, cr, uid, source, context=None): # predicate return bool(sources_ids) - #---------------OpenERP tedious onchange management ---------------------- + # ---------------OpenERP tedious onchange management ---------------------- def _get_date(self, cr, uid, requision_line_id, context=None): """helper to retrive date to be used by framework agreement @@ -297,8 +307,9 @@ def _get_date(self, cr, uid, requision_line_id, context=None): return current.requisition_id.date or now @id_boilerplate - def onchange_sourcing_method(self, cr, uid, ids, method, req_line_id, proposed_product_id, - proposed_qty=0, context=None): + def onchange_sourcing_method(self, cr, uid, ids, method, req_line_id, + proposed_product_id, proposed_qty=0, + context=None): """ Called when source method is set on a source line. @@ -314,12 +325,9 @@ def onchange_sourcing_method(self, cr, uid, ids, method, req_line_id, proposed_p currency = line_source.currency_id agreement_obj = self.pool['framework.agreement'] date = self._get_date(cr, uid, req_line_id, context=context) - agreement, enough_qty = agreement_obj.get_cheapest_agreement_for_qty(cr, uid, - proposed_product_id, - date, - proposed_qty, - currency=currency, - context=context) + agreement, enough_qty = agreement_obj.get_cheapest_agreement_for_qty( + cr, uid, proposed_product_id, date, proposed_qty, + currency=currency, context=context) if not agreement: return res price = agreement.get_price(proposed_qty, currency=currency) @@ -389,4 +397,5 @@ def onchange_agreement(self, cr, uid, ids, agreement_id, req_line_id, qty, date = self._get_date(cr, uid, req_line_id, context=context) return self.onchange_agreement_obs(cr, uid, ids, agreement_id, qty, date, proposed_product_id, - currency=currency, price_field='dummy') + currency=currency, + price_field='dummy') diff --git a/framework_agreement_sourcing/model/purchase.py b/framework_agreement_sourcing/model/purchase.py index d3bde806..054fcbfd 100644 --- a/framework_agreement_sourcing/model/purchase.py +++ b/framework_agreement_sourcing/model/purchase.py @@ -29,10 +29,11 @@ class purchase_order(orm.Model): _inherit = "purchase.order" def action_confirm(self, cr, uid, ids, context=None): - super(purchase_order_line, self).action_confirm( + super(purchase_order, self).action_confirm( cr, uid, ids, context=context) for element in self.browse(cr, uid, ids, context=context): if not element.quantity_bid and not element.framework_agreement_id: - self.write( - cr, uid, ids, {'quantity_bid': element.product_qty}, context=context) + self.write(cr, uid, ids, { + 'quantity_bid': element.product_qty + }, context=context) return True diff --git a/framework_agreement_sourcing/model/sale_order.py b/framework_agreement_sourcing/model/sale_order.py index 09fd38fc..3f229020 100644 --- a/framework_agreement_sourcing/model/sale_order.py +++ b/framework_agreement_sourcing/model/sale_order.py @@ -32,7 +32,8 @@ class sale_order_line(orm.Model): def button_confirm(self, cr, uid, ids, context=None): """Override confirmation of request of cotation to support LTA - Related PO generated by agreement source line will be passed to state confirm. + Related PO generated by agreement source line will be passed to state + confirm. """ def source_valid(source): diff --git a/framework_agreement_sourcing/tests/common.py b/framework_agreement_sourcing/tests/common.py index c3bba3b7..f8860746 100644 --- a/framework_agreement_sourcing/tests/common.py +++ b/framework_agreement_sourcing/tests/common.py @@ -22,7 +22,8 @@ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT import openerp.tests.common as test_common from openerp.addons.logistic_requisition.tests import logistic_requisition -from openerp.addons.framework_agreement.tests.common import BaseAgreementTestMixin +from openerp.addons.framework_agreement.tests.common \ + import BaseAgreementTestMixin class CommonSourcingSetUp(test_common.TransactionCase, BaseAgreementTestMixin): @@ -101,7 +102,6 @@ def make_common_agreements(self): """ - cr, uid = self.cr, self.uid start_date = self.now + timedelta(days=10) start_date = start_date.strftime(DEFAULT_SERVER_DATE_FORMAT) end_date = self.now + timedelta(days=20) diff --git a/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py b/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py index 5794f47b..25db8720 100644 --- a/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py +++ b/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py @@ -61,8 +61,6 @@ def test_01_transform_source_to_agreement(self): wiz_id = self.wiz_model.create(self.cr, self.uid, {}, context={'active_ids': active_ids}) - wiz = self.wiz_model.browse(self.cr, self.uid, wiz_id) - po_id = self.wiz_model.action_create_agreement_po_requisition( cr, uid, [wiz_id], context={'active_ids': active_ids} )['res_id'] @@ -84,7 +82,8 @@ def test_01_transform_source_to_agreement(self): self.assertEqual(len(po.order_line), 2) po_line = next(x for x in po.order_line - if x.product_id == self.lta_source.framework_agreement_id.product_id) + if x.product_id == + self.lta_source.framework_agreement_id.product_id) self.assertEqual(po_line.product_qty, self.lta_source.proposed_qty) self.assertEqual( po_line.product_id, self.lta_source.proposed_product_id) @@ -95,7 +94,8 @@ def test_01_transform_source_to_agreement(self): self.assertEqual(po_line.date_planned, date_delivery) po_line = next(x for x in po.order_line - if x.product_id == self.other_source.proposed_product_id) + if x.product_id == + self.other_source.proposed_product_id) self.assertEqual(po_line.product_qty, self.other_source.proposed_qty) self.assertEqual( po_line.product_id, self.other_source.proposed_product_id) diff --git a/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py b/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py index ef05b946..b5ae9284 100644 --- a/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py +++ b/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py @@ -86,7 +86,8 @@ def test_03_not_enough_qty_on_high_agreement(self): # high_line # idiom taken from Python cookbook high_line = next((x for x in to_validates - if x.framework_agreement_id == self.cheap_on_high_agreement), None) + if x.framework_agreement_id == + self.cheap_on_high_agreement), None) self.assertTrue(high_line, msg="High agreement was not used") self.assertEqual(high_line.procurement_method, AGR_PROC) self.assertEqual(high_line.proposed_qty, 2000) @@ -94,14 +95,16 @@ def test_03_not_enough_qty_on_high_agreement(self): # low_line low_line = next((x for x in to_validates - if x.framework_agreement_id == self.cheap_on_low_agreement), None) + if x.framework_agreement_id == + self.cheap_on_low_agreement), None) self.assertTrue(low_line, msg="Low agreement was not used") self.assertEqual(low_line.procurement_method, AGR_PROC) self.assertEqual(low_line.proposed_qty, 400) self.assertAlmostEqual(low_line.unit_cost, 0.0) def test_03_not_enough_qty_on_all_agreemenst(self): - """Test that we have generate correct line when not enough qty on all agreements + """Test that we have generate correct line when not enough qty on all + agreements That means last source line must be of type other or procurement """ @@ -123,7 +126,8 @@ def test_03_not_enough_qty_on_all_agreemenst(self): # high_line # idiom taken from Python cookbook high_line = next((x for x in to_validates - if x.framework_agreement_id == self.cheap_on_high_agreement), None) + if x.framework_agreement_id == + self.cheap_on_high_agreement), None) self.assertTrue(high_line, msg="High agreement was not used") self.assertEqual(high_line.procurement_method, AGR_PROC) self.assertEqual(high_line.proposed_qty, 2000) @@ -131,7 +135,8 @@ def test_03_not_enough_qty_on_all_agreemenst(self): # low_line low_line = next((x for x in to_validates - if x.framework_agreement_id == self.cheap_on_low_agreement), None) + if x.framework_agreement_id == + self.cheap_on_low_agreement), None) self.assertTrue(low_line, msg="Low agreement was not used") self.assertEqual(low_line.procurement_method, AGR_PROC) self.assertEqual(low_line.proposed_qty, 1200) diff --git a/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py b/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py index 5c6031e9..fffa2415 100644 --- a/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py +++ b/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py @@ -30,10 +30,11 @@ class logistic_requisition_source_po_creator(orm.TransientModel): 'pricelist_id': fields.many2one('product.pricelist', string='Pricelist / Currency', required=True), - 'framework_currency_ids': fields.many2many('framework.agreement.pricelist', - rel='framework_agr_id_po_create_rel', - string='Available Currency', - readonly=True) + 'framework_currency_ids': fields.many2many( + 'framework.agreement.pricelist', + rel='framework_agr_id_po_create_rel', + string='Available Currency', + readonly=True) } def default_get(self, cr, uid, fields_list, context=None): @@ -48,8 +49,9 @@ def default_get(self, cr, uid, fields_list, context=None): fmwk_price_obj = self.pool.get('framework.agreement.pricelist') line_ids = context['active_ids'] pricelist_id = None - line = next((x for x in line_obj.browse(cr, uid, line_ids, context=context) - if x.framework_agreement_id), None) + line = next((x for x in line_obj.browse(cr, uid, line_ids, + context=context) if + x.framework_agreement_id), None) if not line: raise orm.except_orm(_('No sourcing line with agreement selected'), _('Please correct selection')) @@ -70,23 +72,25 @@ def default_get(self, cr, uid, fields_list, context=None): defaults['framework_currency_ids'] = frwk_ids return defaults - def _make_purchase_order(self, cr, uid, pricelist, source_ids, context=None): + def _make_purchase_order(self, cr, uid, pricelist, source_ids, + context=None): """Create PO from source line ids""" lr_model = self.pool['logistic.requisition.source'] po_id = lr_model.make_purchase_order(cr, uid, source_ids, pricelist, context=context) return po_id - def action_create_agreement_po_requisition(self, cr, uid, ids, context=None): + def action_create_agreement_po_requisition(self, cr, uid, ids, + context=None): """ Implement buttons that create PO from selected source lines""" act_obj = self.pool['ir.actions.act_window'] source_ids = context['active_ids'] form = self.browse(cr, uid, ids, context=context)[0] pricelist = form.pricelist_id - available_currency = [ + available_curr = [ x.currency_id for x in form.framework_currency_ids] - if available_currency and pricelist.currency_id not in available_currency: + if available_curr and pricelist.currency_id not in available_curr: raise orm.except_orm(_('User Error'), _( 'You must chose a pricelist that is in the same currency ' 'than one of the available in the framework agreement.')) From 5368348bae48d7d0b157b9190ec8e5646cb34228 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Wed, 29 Oct 2014 11:01:39 +0100 Subject: [PATCH 04/15] bump version --- framework_agreement_sourcing/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework_agreement_sourcing/__openerp__.py b/framework_agreement_sourcing/__openerp__.py index f17f33a5..efa55595 100644 --- a/framework_agreement_sourcing/__openerp__.py +++ b/framework_agreement_sourcing/__openerp__.py @@ -19,7 +19,7 @@ # ############################################################################## {'name': 'Framework agreement integration in sourcing', - 'version': '0.1', + 'version': '1.0', 'author': 'Camptocamp', 'maintainer': 'Camptocamp', 'category': 'NGO', From b850c52e5c12ecc8de56f001b4d453f9f7426e3a Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Wed, 29 Oct 2014 11:32:51 +0100 Subject: [PATCH 05/15] typo in manifest --- framework_agreement_sourcing/__openerp__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework_agreement_sourcing/__openerp__.py b/framework_agreement_sourcing/__openerp__.py index efa55595..d670dbdb 100644 --- a/framework_agreement_sourcing/__openerp__.py +++ b/framework_agreement_sourcing/__openerp__.py @@ -34,8 +34,8 @@ agreement will be used as source for the concerned source lines of your request. -In this case tender flow is byassed and confirmed PO will be generated -when logistic requisition is confirmed. +In this case the tender flow is bypassed and confirmed PO will be generated +when the logistic requisition is confirmed. When confirming Logistic request sourcing lines are generating. Generation process will look up all agreements with remaining quantity From ac56efd86358e1b41a9f729a3993eb70cc1b91d3 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Wed, 29 Oct 2014 14:58:42 +0100 Subject: [PATCH 06/15] adapt tests to changes in the LR module --- framework_agreement_sourcing/tests/common.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework_agreement_sourcing/tests/common.py b/framework_agreement_sourcing/tests/common.py index f8860746..e6f8455a 100644 --- a/framework_agreement_sourcing/tests/common.py +++ b/framework_agreement_sourcing/tests/common.py @@ -83,7 +83,8 @@ def make_common_requisition(self): } self.requisition = self.Requisition.create(req) - self.requisition.onchange_consignee_id() + self.requisition.onchange_consignee_id_set_country_id() + self.requisition.onchange_consignee_id_set_consignee_shipping_id() logistic_requisition.add_line(self, self.requisition, agr_line) logistic_requisition.add_line(self, self.requisition, product_line) logistic_requisition.add_line(self, self.requisition, other_line) From f8dfd6aa39fb7eedea00837323a0395a5dd70a4a Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Wed, 29 Oct 2014 16:53:50 +0100 Subject: [PATCH 07/15] adapt to changes in models Specifically, the field logistic_requisition_source_id is not there anymore. --- .../logistic_requisition_cost_estimate.py | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py b/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py index 0f4ba4bf..cec4bbab 100644 --- a/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py +++ b/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py @@ -82,21 +82,29 @@ def cost_estimate(self, cr, uid, ids, context=None): """ so_model = self.pool['sale.order'] po_model = self.pool['purchase.order'] + + assert len(ids) == 1 + + wizard = self.browse(cr, uid, ids, context=context) + res = super(logistic_requisition_cost_estimate, self).cost_estimate(cr, uid, ids, context=context) so_id = res['res_id'] order = so_model.browse(cr, uid, so_id, context=context) - # Can be optimized with a SQL or a search but - # gain of perfo will not worth readability loss - # for such small data set - sources = [x.logistic_requisition_source_id for x in order.order_line - if x and x.logistic_requisition_source_id.procurement_method - == AGR_PROC] + + sources = [] + + for lrl in wizard.line_ids: + for source in lrl.source_ids: + if source.procurement_method == AGR_PROC: + sources.append(source) + po_ids = set(x.purchase_line_id.order_id.id for x in sources if x.purchase_line_id) - po_model.write(cr, uid, list(po_ids), - {'sale_id': so_id, - 'sale_flow': 'direct_delivery'}) - self._link_po_lines_to_so_lines( - cr, uid, order, sources, context=context) + if po_ids: + po_model.write(cr, uid, list(po_ids), + {'sale_id': so_id, + 'sale_flow': 'direct_delivery'}) + self._link_po_lines_to_so_lines( + cr, uid, order, sources, context=context) return res From 74e7e1b12cbebae82411b1515414c0d99ee44d7c Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Thu, 30 Oct 2014 14:04:17 +0100 Subject: [PATCH 08/15] fix validation of a cost estimate --- .../model/sale_order.py | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/framework_agreement_sourcing/model/sale_order.py b/framework_agreement_sourcing/model/sale_order.py index 3f229020..4eedf682 100644 --- a/framework_agreement_sourcing/model/sale_order.py +++ b/framework_agreement_sourcing/model/sale_order.py @@ -30,33 +30,48 @@ class sale_order_line(orm.Model): _inherit = "sale.order.line" def button_confirm(self, cr, uid, ids, context=None): - """Override confirmation of request of cotation to support LTA + """Override confirmation of request of quotation to support LTA Related PO generated by agreement source line will be passed to state - confirm. + draft_po. """ + POL = self.pool['purchase.order.line'] + LRL = self.pool['logistic.requisition.line'] + wf_service = netsvc.LocalService("workflow") + def source_valid(source): if source and source.procurement_method == AGR_PROC: return True return False + result = super(sale_order_line, self).button_confirm(cr, uid, ids, context=context) - po_line_model = self.pool['purchase.order.line'] - po_model = self.pool['purchase.order'] - - lines = self.browse(cr, uid, ids, context=context) - source_ids = [x.logistic_requisition_source_id.id for x in lines - if source_valid(x.logistic_requisition_source_id)] - po_line_ids = po_line_model.search(cr, uid, - [('lr_source_line_id', - 'in', source_ids)], - context=context) - po_lines = po_line_model.read(cr, uid, po_line_ids, ['order_id'], - load='_classic_write') - po_ids = set(x['order_id'] for x in po_lines) - wf_service = netsvc.LocalService("workflow") - for po in po_model.browse(cr, uid, list(po_ids), context=context): - wf_service.trg_validate(uid, 'purchase.order', po.id, + + order_lines = self.browse(cr, uid, ids, context=context) + + so_ids = list(set((l.order_id.id for l in order_lines))) + + lrl_ids = LRL.search(cr, uid, [ + ('cost_estimate_id', 'in', so_ids) + ], context=context) + + sources = [] + + for lrl in LRL.browse(cr, uid, lrl_ids, context=context): + sources.append(lrl.source_ids) + + source_ids = [source.id for source in sources if source_valid(source)] + + po_line_ids = POL.search(cr, uid, [ + ('lr_source_line_id', 'in', source_ids) + ], context=context) + + po_lines = POL.browse(cr, uid, po_line_ids, context=context) + + po_ids = list(set((l.order_id.id for l in po_lines))) + + for po_id in po_ids: + wf_service.trg_validate(uid, 'purchase.order', po_id, 'draft_po', cr) return result From d15dadea93d76a394db270c640e0fff15f0f746f Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Thu, 30 Oct 2014 14:29:29 +0100 Subject: [PATCH 09/15] do not override function field for purchase line It does not seem to make much difference from the original one in logistic_requisition. --- .../model/logistic_requisition_source.py | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/framework_agreement_sourcing/model/logistic_requisition_source.py b/framework_agreement_sourcing/model/logistic_requisition_source.py index c78bd0aa..49cd9e36 100644 --- a/framework_agreement_sourcing/model/logistic_requisition_source.py +++ b/framework_agreement_sourcing/model/logistic_requisition_source.py @@ -50,33 +50,6 @@ def _get_procur_method_hook(self, cr, uid, context=None): res.append((AGR_PROC, 'Framework agreement')) return res - def _get_purchase_line_id(self, cr, uid, ids, field_name, arg, - context=None): - """For each source line, get the related purchase order line - - For more detail please refer to function fields documentation - - """ - po_line_model = self.pool['purchase.order.line'] - res = super(logistic_requisition_source, self)._get_purchase_line_id( - cr, uid, ids, field_name, arg, context=context) - for line in self.browse(cr, uid, ids, context=context): - if line.procurement_method == AGR_PROC: - po_l_ids = po_line_model.search(cr, uid, [ - ('lr_source_line_id', '=', line.id), - ('state', '!=', 'cancel') - ], context=context) - if po_l_ids: - if len(po_l_ids) > 1: - raise orm.except_orm( - _('Many Purchase order lines found for %s') - % line.name, - _('Please cancel uneeded one')) - res[line.id] = po_l_ids[0] - else: - res[line.id] = False - return res - # ----------------- adapting source line to po -------------------------- def _company(self, cr, uid, context): """Return company id From 2b467fba44f2780f1f1624ae78eba1a4850b8ab6 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Thu, 30 Oct 2014 14:34:20 +0100 Subject: [PATCH 10/15] remove onchange agreement The agreement field should already have a domain: no need to check with an onchange that a consistent choice is made. --- .../model/logistic_requisition_source.py | 13 ------------- .../view/requisition_view.xml | 3 +-- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/framework_agreement_sourcing/model/logistic_requisition_source.py b/framework_agreement_sourcing/model/logistic_requisition_source.py index 49cd9e36..9efa8b26 100644 --- a/framework_agreement_sourcing/model/logistic_requisition_source.py +++ b/framework_agreement_sourcing/model/logistic_requisition_source.py @@ -359,16 +359,3 @@ def onchange_product_id(self, cr, uid, ids, method, req_line_id, proposed_product_id, proposed_qty=proposed_qty, context=context) - - @id_boilerplate - def onchange_agreement(self, cr, uid, ids, agreement_id, req_line_id, qty, - proposed_product_id, context=None): - line_source = self.browse(cr, uid, ids, context=context) - if not proposed_product_id or not agreement_id: - return {} - currency = line_source.currency_id - date = self._get_date(cr, uid, req_line_id, context=context) - return self.onchange_agreement_obs(cr, uid, ids, agreement_id, qty, - date, proposed_product_id, - currency=currency, - price_field='dummy') diff --git a/framework_agreement_sourcing/view/requisition_view.xml b/framework_agreement_sourcing/view/requisition_view.xml index 5077e66b..9c59e0d2 100644 --- a/framework_agreement_sourcing/view/requisition_view.xml +++ b/framework_agreement_sourcing/view/requisition_view.xml @@ -11,8 +11,7 @@ + 'invisible': [('procurement_method', '!=', 'fw_agreement')]}" /> Date: Thu, 30 Oct 2014 14:42:27 +0100 Subject: [PATCH 11/15] lint --- .../model/logistic_requisition_cost_estimate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py b/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py index cec4bbab..eec3dfd3 100644 --- a/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py +++ b/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py @@ -103,7 +103,7 @@ def cost_estimate(self, cr, uid, ids, context=None): if x.purchase_line_id) if po_ids: po_model.write(cr, uid, list(po_ids), - {'sale_id': so_id, + {'sale_id': so_id, 'sale_flow': 'direct_delivery'}) self._link_po_lines_to_so_lines( cr, uid, order, sources, context=context) From 4ee9b15e6979deca1d13bca6fe9d592cef8c7937 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Fri, 31 Oct 2014 09:27:25 +0100 Subject: [PATCH 12/15] cost estimate is a wizard: treat is as such --- framework_agreement_sourcing/model/__init__.py | 1 - framework_agreement_sourcing/wizard/__init__.py | 1 + .../cost_estimate.py} | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename framework_agreement_sourcing/{model/logistic_requisition_cost_estimate.py => wizard/cost_estimate.py} (98%) diff --git a/framework_agreement_sourcing/model/__init__.py b/framework_agreement_sourcing/model/__init__.py index 2c8ce2b2..67f706cc 100644 --- a/framework_agreement_sourcing/model/__init__.py +++ b/framework_agreement_sourcing/model/__init__.py @@ -22,4 +22,3 @@ from . import logistic_requisition_source from . import purchase from . import sale_order -from . import logistic_requisition_cost_estimate diff --git a/framework_agreement_sourcing/wizard/__init__.py b/framework_agreement_sourcing/wizard/__init__.py index 44ad4a7e..8f71d597 100644 --- a/framework_agreement_sourcing/wizard/__init__.py +++ b/framework_agreement_sourcing/wizard/__init__.py @@ -18,4 +18,5 @@ # along with this program. If not, see . # ############################################################################## +from . import cost_estimate from . import logistic_requisition_source_create_po diff --git a/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py b/framework_agreement_sourcing/wizard/cost_estimate.py similarity index 98% rename from framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py rename to framework_agreement_sourcing/wizard/cost_estimate.py index eec3dfd3..51b0e31f 100644 --- a/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py +++ b/framework_agreement_sourcing/wizard/cost_estimate.py @@ -23,7 +23,7 @@ from .logistic_requisition_source import AGR_PROC -class logistic_requisition_cost_estimate(orm.Model): +class logistic_requisition_cost_estimate(orm.TransientModel): """Add update of agreement price""" From 9cb731c00bfc58c3a64b92fc3aa5140968fead43 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Fri, 31 Oct 2014 09:28:37 +0100 Subject: [PATCH 13/15] update copyright --- framework_agreement_sourcing/wizard/cost_estimate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework_agreement_sourcing/wizard/cost_estimate.py b/framework_agreement_sourcing/wizard/cost_estimate.py index 51b0e31f..0104d2ad 100644 --- a/framework_agreement_sourcing/wizard/cost_estimate.py +++ b/framework_agreement_sourcing/wizard/cost_estimate.py @@ -2,7 +2,7 @@ ############################################################################## # # Author: Nicolas Bessi -# Copyright 2013 Camptocamp SA +# Copyright 2013, 2014 Camptocamp SA # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as From c78e9e13d8eeaf258007e0fe74b3f45a09240190 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Fri, 31 Oct 2014 09:59:07 +0100 Subject: [PATCH 14/15] factor out a constant that is just a little string --- .../model/logistic_requisition.py | 5 ++--- .../model/logistic_requisition_source.py | 12 +++++------- framework_agreement_sourcing/model/sale_order.py | 3 +-- .../test_logistic_order_line_to_source_line.py | 15 +++++++-------- .../wizard/cost_estimate.py | 5 ++--- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/framework_agreement_sourcing/model/logistic_requisition.py b/framework_agreement_sourcing/model/logistic_requisition.py index 2b1e7e9c..cba2255c 100644 --- a/framework_agreement_sourcing/model/logistic_requisition.py +++ b/framework_agreement_sourcing/model/logistic_requisition.py @@ -20,7 +20,6 @@ ############################################################################## from collections import namedtuple from openerp.osv import orm -from .logistic_requisition_source import AGR_PROC class logistic_requisition_line(orm.Model): @@ -33,7 +32,7 @@ def _prepare_line_source(self, cr, uid, line, qty=None, agreement=None, context=None): """Prepare data dict for source line creation. If an agreement - is given, the procurement_method will be an LTA (AGR_PROC). + is given, the procurement_method will be an LTA ('fw_agreement'). Otherwise, if it's a stockable product we'll go to tender by setting procurement_method as 'procurement'. Finally marke the rest as 'other'. Those are default value that can be changed afterward @@ -58,7 +57,7 @@ def _prepare_line_source(self, cr, uid, line, raise ValueError( "Product mismatch for agreement and requisition line") res['framework_agreement_id'] = agreement.id - res['procurement_method'] = AGR_PROC + res['procurement_method'] = 'fw_agreement' else: if line.product_id.type == 'product': res['procurement_method'] = 'procurement' diff --git a/framework_agreement_sourcing/model/logistic_requisition_source.py b/framework_agreement_sourcing/model/logistic_requisition_source.py index 9efa8b26..7959ae7d 100644 --- a/framework_agreement_sourcing/model/logistic_requisition_source.py +++ b/framework_agreement_sourcing/model/logistic_requisition_source.py @@ -24,8 +24,6 @@ from openerp.tools.translate import _ from openerp.addons.framework_agreement.utils import id_boilerplate -AGR_PROC = 'fw_agreement' - class logistic_requisition_source(orm.Model): @@ -47,7 +45,7 @@ def _get_procur_method_hook(self, cr, uid, context=None): field""" res = super(logistic_requisition_source, self)._get_procur_method_hook( cr, uid, context=context) - res.append((AGR_PROC, 'Framework agreement')) + res.append(('fw_agreement', 'Framework agreement')) return res # ----------------- adapting source line to po -------------------------- @@ -214,7 +212,7 @@ def make_purchase_order(self, cr, uid, ids, pricelist, context=None): # LRS of type other other_sources = [] for source in sources: - if source.procurement_method == AGR_PROC: + if source.procurement_method == 'fw_agreement': agreement_sources.append(source) elif source.procurement_method == 'other': other_sources.append(source) @@ -293,7 +291,7 @@ def onchange_sourcing_method(self, cr, uid, ids, method, req_line_id, """ line_source = self.browse(cr, uid, ids, context=context) res = {'value': {'framework_agreement_id': False}} - if (method != AGR_PROC or not proposed_product_id): + if (method != 'fw_agreement' or not proposed_product_id): return res currency = line_source.currency_id agreement_obj = self.pool['framework.agreement'] @@ -321,7 +319,7 @@ def onchange_quantity(self, cr, uid, ids, method, req_line_id, qty, proposed_product_id, context=None): """Raise a warning if agreed qty is not sufficient""" line_source = self.browse(cr, uid, ids, context=context) - if (method != AGR_PROC or not proposed_product_id): + if (method != 'fw_agreement' or not proposed_product_id): return {} currency = line_source.currency_id date = self._get_date(cr, uid, req_line_id, context=context) @@ -342,7 +340,7 @@ def onchange_product_id(self, cr, uid, ids, method, req_line_id, and raise quantity warning. """ - if method != AGR_PROC: + if method != 'fw_agreement': if proposed_product_id: value = {'proposed_uom_id': ''} if proposed_product_id: diff --git a/framework_agreement_sourcing/model/sale_order.py b/framework_agreement_sourcing/model/sale_order.py index 4eedf682..f58d7238 100644 --- a/framework_agreement_sourcing/model/sale_order.py +++ b/framework_agreement_sourcing/model/sale_order.py @@ -20,7 +20,6 @@ ############################################################################## from openerp import netsvc from openerp.osv import orm -from .logistic_requisition_source import AGR_PROC class sale_order_line(orm.Model): @@ -41,7 +40,7 @@ def button_confirm(self, cr, uid, ids, context=None): wf_service = netsvc.LocalService("workflow") def source_valid(source): - if source and source.procurement_method == AGR_PROC: + if source and source.procurement_method == 'fw_agreement': return True return False diff --git a/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py b/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py index b5ae9284..cff73171 100644 --- a/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py +++ b/framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py @@ -18,7 +18,6 @@ # along with this program. If not, see . # ############################################################################## -from ..model.logistic_requisition_source import AGR_PROC from .common import CommonSourcingSetUp @@ -41,7 +40,7 @@ def test_01_enough_qty_on_first_agr(self): self.assertTrue(len(to_validate_ids) == 1) to_validate = self.source_line_model.browse( cr, uid, to_validate_ids[0]) - self.assertEqual(to_validate.procurement_method, AGR_PROC) + self.assertEqual(to_validate.procurement_method, 'fw_agreement') self.assertAlmostEqual(to_validate.unit_cost, 0.0) self.assertEqual(to_validate.proposed_qty, 400) @@ -62,7 +61,7 @@ def test_02_enough_qty_on_high_agr(self): self.assertTrue(len(to_validate_ids) == 1) to_validate = self.source_line_model.browse( cr, uid, to_validate_ids[0]) - self.assertEqual(to_validate.procurement_method, AGR_PROC) + self.assertEqual(to_validate.procurement_method, 'fw_agreement') self.assertAlmostEqual(to_validate.unit_cost, 0.0) self.assertEqual(to_validate.proposed_qty, 1500) @@ -89,7 +88,7 @@ def test_03_not_enough_qty_on_high_agreement(self): if x.framework_agreement_id == self.cheap_on_high_agreement), None) self.assertTrue(high_line, msg="High agreement was not used") - self.assertEqual(high_line.procurement_method, AGR_PROC) + self.assertEqual(high_line.procurement_method, 'fw_agreement') self.assertEqual(high_line.proposed_qty, 2000) self.assertAlmostEqual(high_line.unit_cost, 0.0) @@ -98,7 +97,7 @@ def test_03_not_enough_qty_on_high_agreement(self): if x.framework_agreement_id == self.cheap_on_low_agreement), None) self.assertTrue(low_line, msg="Low agreement was not used") - self.assertEqual(low_line.procurement_method, AGR_PROC) + self.assertEqual(low_line.procurement_method, 'fw_agreement') self.assertEqual(low_line.proposed_qty, 400) self.assertAlmostEqual(low_line.unit_cost, 0.0) @@ -129,7 +128,7 @@ def test_03_not_enough_qty_on_all_agreemenst(self): if x.framework_agreement_id == self.cheap_on_high_agreement), None) self.assertTrue(high_line, msg="High agreement was not used") - self.assertEqual(high_line.procurement_method, AGR_PROC) + self.assertEqual(high_line.procurement_method, 'fw_agreement') self.assertEqual(high_line.proposed_qty, 2000) self.assertAlmostEqual(high_line.unit_cost, 0.0) @@ -138,7 +137,7 @@ def test_03_not_enough_qty_on_all_agreemenst(self): if x.framework_agreement_id == self.cheap_on_low_agreement), None) self.assertTrue(low_line, msg="Low agreement was not used") - self.assertEqual(low_line.procurement_method, AGR_PROC) + self.assertEqual(low_line.procurement_method, 'fw_agreement') self.assertEqual(low_line.proposed_qty, 1200) self.assertAlmostEqual(low_line.unit_cost, 0.0) @@ -146,4 +145,4 @@ def test_03_not_enough_qty_on_all_agreemenst(self): tender_line = next((x for x in to_validates if not x.framework_agreement_id), None) self.assertTrue(tender_line, msg="Tender line was not generated") - self.assertNotEqual(tender_line.procurement_method, AGR_PROC) + self.assertNotEqual(tender_line.procurement_method, 'fw_agreement') diff --git a/framework_agreement_sourcing/wizard/cost_estimate.py b/framework_agreement_sourcing/wizard/cost_estimate.py index 0104d2ad..35db2011 100644 --- a/framework_agreement_sourcing/wizard/cost_estimate.py +++ b/framework_agreement_sourcing/wizard/cost_estimate.py @@ -20,7 +20,6 @@ ############################################################################## from openerp.osv import orm from openerp.tools.translate import _ -from .logistic_requisition_source import AGR_PROC class logistic_requisition_cost_estimate(orm.TransientModel): @@ -37,7 +36,7 @@ def _prepare_cost_estimate_line(self, cr, uid, sourcing, context=None): self)._prepare_cost_estimate_line(cr, uid, sourcing, context=context) - if sourcing.procurement_method == AGR_PROC: + if sourcing.procurement_method == 'fw_agreement': res['type'] = 'make_to_order' res['sale_flow'] = 'direct_delivery' return res @@ -96,7 +95,7 @@ def cost_estimate(self, cr, uid, ids, context=None): for lrl in wizard.line_ids: for source in lrl.source_ids: - if source.procurement_method == AGR_PROC: + if source.procurement_method == 'fw_agreement': sources.append(source) po_ids = set(x.purchase_line_id.order_id.id for x in sources From e953984dc5e4d9ef3d0d86f9a3e213a8edb14e82 Mon Sep 17 00:00:00 2001 From: Leonardo Pistone Date: Fri, 31 Oct 2014 11:16:21 +0100 Subject: [PATCH 15/15] fix typos in manifest --- framework_agreement_sourcing/__openerp__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework_agreement_sourcing/__openerp__.py b/framework_agreement_sourcing/__openerp__.py index d670dbdb..078f47ea 100644 --- a/framework_agreement_sourcing/__openerp__.py +++ b/framework_agreement_sourcing/__openerp__.py @@ -37,12 +37,12 @@ In this case the tender flow is bypassed and confirmed PO will be generated when the logistic requisition is confirmed. -When confirming Logistic request sourcing lines are generating. +When confirming Logistic request sourcing lines are generated. Generation process will look up all agreements with remaining quantity and use them one after the other. We will first choose cheapest agreements with price in negociated currency even -if they are cheaper in other currences. +if they are cheaper in other currencies. Then we will choose remaining agreements ordered by price converted in company currency.