From c28863fe8171466683176d4e39ac98c024493f43 Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Thu, 26 Feb 2015 16:42:54 +0100 Subject: [PATCH 1/2] fix test file name and test name --- framework_agreement_sourcing/tests/__init__.py | 3 +-- ...souce_line_to_po.py => test_agreement_source_line_to_po.py} | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) rename framework_agreement_sourcing/tests/{test_agreement_souce_line_to_po.py => test_agreement_source_line_to_po.py} (99%) diff --git a/framework_agreement_sourcing/tests/__init__.py b/framework_agreement_sourcing/tests/__init__.py index ef60dce7..14f44b8f 100644 --- a/framework_agreement_sourcing/tests/__init__.py +++ b/framework_agreement_sourcing/tests/__init__.py @@ -14,7 +14,6 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from . import common from . import test_logistic_order_line_to_source_line -from . import test_agreement_souce_line_to_po +from . import test_agreement_source_line_to_po from . import test_check_sourcing diff --git a/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py b/framework_agreement_sourcing/tests/test_agreement_source_line_to_po.py similarity index 99% rename from framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py rename to framework_agreement_sourcing/tests/test_agreement_source_line_to_po.py index f9a22d5a..c0906ae6 100644 --- a/framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py +++ b/framework_agreement_sourcing/tests/test_agreement_source_line_to_po.py @@ -115,7 +115,7 @@ def test_01_transform_source_to_agreement_wh_dest(self): self.assertAlmostEqual(po_line.price_unit, 1.0) self.assertEqual(po_line.lr_source_line_id, self.other_source) - def test_01_transform_source_to_agreement_dropshipping(self): + def test_02_transform_source_to_agreement_dropshipping(self): """Test transformation of an agreement source line into PO""" cr, uid = self.cr, self.uid From 93ddb1ff1727edaf2de6753ff0bb2c9f2ce898ce Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Thu, 26 Feb 2015 17:28:26 +0100 Subject: [PATCH 2/2] new addon framework_agreement_sourcing_stock_route_transit --- .travis.yml | 6 +- .../README.rst | 28 +++ .../__init__.py | 1 + .../__openerp__.py | 37 ++++ .../model/__init__.py | 1 + .../model/logistic_requisition_source.py | 40 +++++ .../model/logistic_requisition_source.py | 36 ++++ .../tests/__init__.py | 1 + .../tests/test_agreement_source_line_to_po.py | 160 ++++++++++++++++++ 9 files changed, 308 insertions(+), 2 deletions(-) create mode 100644 framework_agreement_sourcing_stock_route_transit/README.rst create mode 100644 framework_agreement_sourcing_stock_route_transit/__init__.py create mode 100644 framework_agreement_sourcing_stock_route_transit/__openerp__.py create mode 100644 framework_agreement_sourcing_stock_route_transit/model/__init__.py create mode 100644 framework_agreement_sourcing_stock_route_transit/model/logistic_requisition_source.py create mode 100644 framework_agreement_sourcing_stock_route_transit/model/logistic_requisition_source.py create mode 100644 framework_agreement_sourcing_stock_route_transit/tests/__init__.py create mode 100644 framework_agreement_sourcing_stock_route_transit/tests/test_agreement_source_line_to_po.py diff --git a/.travis.yml b/.travis.yml index 76398676..5c17cf35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,10 @@ python: env: - VERSION="8.0" LINT_CHECK="1" - - VERSION="8.0" ODOO_REPO="odoo/odoo" EXCLUDE="logistic_consignee" LINT_CHECK="0" - - VERSION="8.0" ODOO_REPO="OCA/OCB" EXCLUDE="logistic_consignee" LINT_CHECK="0" + - VERSION="8.0" ODOO_REPO="odoo/odoo" EXCLUDE="logistic_consignee,framework_agreement_sourcing_stock_route_transit" LINT_CHECK="0" + - VERSION="8.0" ODOO_REPO="OCA/OCB" EXCLUDE="logistic_consignee,framework_agreement_sourcing_stock_route_transit" LINT_CHECK="0" + - VERSION="8.0" ODOO_REPO="odoo/odoo" INCLUDE="framework_agreement_sourcing_stock_route_transit" LINT_CHECK="0" + - VERSION="8.0" ODOO_REPO="OCA/OCB" INCLUDE="framework_agreement_sourcing_stock_route_transit" LINT_CHECK="0" - VERSION="8.0" ODOO_REPO="odoo/odoo" INCLUDE="logistic_consignee" LINT_CHECK="0" - VERSION="8.0" ODOO_REPO="OCA/OCB" INCLUDE="logistic_consignee" LINT_CHECK="0" diff --git a/framework_agreement_sourcing_stock_route_transit/README.rst b/framework_agreement_sourcing_stock_route_transit/README.rst new file mode 100644 index 00000000..85f3e03c --- /dev/null +++ b/framework_agreement_sourcing_stock_route_transit/README.rst @@ -0,0 +1,28 @@ +Framework Agreement Sourcing with Transit management +==================================================== + +This module ensures that the framework agreement sourcing purchases made in +dropshipping mode will go through the transit locations when +`stock_route_transit` (from https://github.com/OCA/stock-logistics-workflow/) +is installed. + +Credits +======= + +Contributors +------------ + +* Alexandre Fayolle + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/framework_agreement_sourcing_stock_route_transit/__init__.py b/framework_agreement_sourcing_stock_route_transit/__init__.py new file mode 100644 index 00000000..9186ee3a --- /dev/null +++ b/framework_agreement_sourcing_stock_route_transit/__init__.py @@ -0,0 +1 @@ +from . import model diff --git a/framework_agreement_sourcing_stock_route_transit/__openerp__.py b/framework_agreement_sourcing_stock_route_transit/__openerp__.py new file mode 100644 index 00000000..b5dcb288 --- /dev/null +++ b/framework_agreement_sourcing_stock_route_transit/__openerp__.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Alexandre Fayolle +# Copyright 2015 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 +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{'name': 'Sourcing for Framework Agreement with Transit routes', + 'version': '0.1', + 'author': 'Camptocamp', + 'maintainer': 'Camptocamp', + 'category': 'NGO', + 'complexity': 'normal', + 'depends': ['framework_agreement_sourcing', 'stock_route_transit'], + 'website': 'http://www.camptocamp.com', + 'data': [ + ], + 'demo': [], + 'test': [], + 'installable': True, + 'auto_install': True, + 'license': 'AGPL-3', + 'application': False, + } diff --git a/framework_agreement_sourcing_stock_route_transit/model/__init__.py b/framework_agreement_sourcing_stock_route_transit/model/__init__.py new file mode 100644 index 00000000..459991b5 --- /dev/null +++ b/framework_agreement_sourcing_stock_route_transit/model/__init__.py @@ -0,0 +1 @@ +from . import logistic_requisition_source diff --git a/framework_agreement_sourcing_stock_route_transit/model/logistic_requisition_source.py b/framework_agreement_sourcing_stock_route_transit/model/logistic_requisition_source.py new file mode 100644 index 00000000..fc573755 --- /dev/null +++ b/framework_agreement_sourcing_stock_route_transit/model/logistic_requisition_source.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Nicolas Bessi +# Copyright 2013-2015 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 +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.osv import orm + +class LogisticRequisitionSource(orm.Model): + _inherit = "logistic.requisition.source" + + def _prepare_purchase_order(self, cr, uid, + line, po_pricelist, context=None): + """change the destination location and route + of the generated purchase order""" + _super = super(LogisticRequisitionSource, self) + res = _super._prepare_purchase_order(cr, uid, + line, po_pricelist, + context=context) + ref = IrModelData = self.pool['ir.model.data'].xmlid_to_res_id + transit_location_id = ref(cr, uid, 'stock_route_transit.transit_outgoing') + res['location_id'] = transit_location_id + pick_type_id = ref(cr, uid, 'stock_dropshipping.picking_type_dropship') + res['picking_type_id'] = pick_type_id + return res diff --git a/framework_agreement_sourcing_stock_route_transit/model/logistic_requisition_source.py b/framework_agreement_sourcing_stock_route_transit/model/logistic_requisition_source.py new file mode 100644 index 00000000..76e7880b --- /dev/null +++ b/framework_agreement_sourcing_stock_route_transit/model/logistic_requisition_source.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Nicolas Bessi +# Copyright 2013-2015 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 +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp import models, api + +class LogisticRequisitionSource(models.Model): + _inherit = "logistic.requisition.source" + + def _prepare_purchase_order(self, line, po_pricelist): + """change the destination location and route + of the generated purchase order""" + _super = super(LogisticRequisitionSource, self) + res = _super._prepare_purchase_order(line, po_pricelist) + transit_location = self.env.ref('stock_route_transit.transit_outgoing') + res['location_id'] = transit_location.id + pick_type = self.env.ref('stock_dropshipping.picking_type_dropship') + res['picking_type_id'] = pick_type.id + return res diff --git a/framework_agreement_sourcing_stock_route_transit/tests/__init__.py b/framework_agreement_sourcing_stock_route_transit/tests/__init__.py new file mode 100644 index 00000000..0a238b99 --- /dev/null +++ b/framework_agreement_sourcing_stock_route_transit/tests/__init__.py @@ -0,0 +1 @@ +from . import test_agreement_source_line_to_po diff --git a/framework_agreement_sourcing_stock_route_transit/tests/test_agreement_source_line_to_po.py b/framework_agreement_sourcing_stock_route_transit/tests/test_agreement_source_line_to_po.py new file mode 100644 index 00000000..2549c6a8 --- /dev/null +++ b/framework_agreement_sourcing_stock_route_transit/tests/test_agreement_source_line_to_po.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Nicolas Bessi +# Copyright 2013-2015 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 +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +import openerp.addons.framework_agreement_sourcing.tests as fa_sourcing_test + +base_test = fa_sourcing_test.test_agreement_source_line_to_po + +class TestSourceToPoTransit(base_test.TestSourceToPo): + + def setUp(self): + # we generate a source line + super(TestSourceToPoTransit, self).setUp() + StockWarehouse = self.env['stock.warehouse'] + warehouse_id = self.ref('stock.warehouse0') + warehouse = StockWarehouse.browse(warehouse_id) + warehouse.write({'reception_steps': 'transit_three_steps', + 'delivery_steps': 'pick_pack_ship_transit'}) + + def test_01_transform_source_to_agreement_wh_dest(self): + """Test transformation of an LRS sourced by FA to PO delivering to WH""" + cr, uid = self.cr, self.uid + + # Set destination address + partner_vals = { + 'name': 'Warehouse address', + } + partner_wh = self.env['res.partner'].create(partner_vals) + warehouse_id = self.ref('stock.warehouse0') + warehouse = self.env['stock.warehouse'].browse(warehouse_id) + warehouse.partner_id = partner_wh + picking_type_wh = warehouse.transit_in_type_id + self.agr_line.consignee_shipping_id = partner_wh + + self.assertTrue(self.lta_source, 'no lta source found') + self.lta_source.refresh() + active_ids = [x.id for x in self.source_lines] + wiz_ctx = {'active_model': 'logistic.requisition.source', + 'active_ids': active_ids} + wiz_id = self.wiz_model.create(self.cr, self.uid, {}, + context=wiz_ctx) + + po_id = self.wiz_model.action_create_agreement_po_requisition( + cr, uid, [wiz_id], context=wiz_ctx)['res_id'] + self.assertTrue(po_id, "no PO created") + supplier = self.lta_source.framework_agreement_id.supplier_id + add = self.lta_source.requisition_id.consignee_shipping_id + consignee = self.lta_source.requisition_id.consignee_id + po = self.registry('purchase.order').browse(cr, uid, po_id) + 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.date_order, date_order) + self.assertEqual(po.dest_address_id, add) + self.assertEqual(po.picking_type_id.id, picking_type_wh) + self.assertEqual(po.consignee_id, consignee) + self.assertEqual(po.state, 'draftpo') + self.assertNotEqual(po.name, self.requisition.name) + 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) + 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_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) + self.assertEqual(po_line.lr_source_line_id, self.lta_source) + 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) + 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_qty, self.other_source.proposed_qty) + 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) + + def test_02_transform_source_to_agreement_dropshipping(self): + """Test transformation of an LRS sourced by FA to PO dropshipping""" + cr, uid = self.cr, self.uid + + # Set destination address + partner_dropship = self.ref('base.res_partner_12') + self.agr_line.consignee_shipping_id = partner_dropship + + self.assertTrue(self.lta_source, 'no lta source found') + self.lta_source.refresh() + active_ids = [x.id for x in self.source_lines] + wiz_ctx = {'active_model': 'logistic.requisition.source', + 'active_ids': active_ids} + wiz_id = self.wiz_model.create(self.cr, self.uid, {}, context=wiz_ctx) + + po_id = self.wiz_model.action_create_agreement_po_requisition( + cr, uid, [wiz_id], context=wiz_ctx)['res_id'] + self.assertTrue(po_id, "no PO created") + supplier = self.lta_source.framework_agreement_id.supplier_id + add = self.lta_source.requisition_id.consignee_shipping_id + consignee = self.lta_source.requisition_id.consignee_id + po = self.registry('purchase.order').browse(cr, uid, po_id) + 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.date_order, date_order) + self.assertEqual(po.dest_address_id, add) + self.assertEqual(po.picking_type_id.name, 'Dropship') + self.assertEqual(po.consignee_id, consignee) + self.assertEqual(po.state, 'draftpo') + self.assertNotEqual(po.name, self.requisition.name) + 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) + 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_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) + self.assertEqual(po_line.lr_source_line_id, self.lta_source) + 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) + 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_qty, self.other_source.proposed_qty) + 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)