diff --git a/addons/purchase/views/res_config_settings_views.xml b/addons/purchase/views/res_config_settings_views.xml index 86037167a81..ae98295a2fc 100644 --- a/addons/purchase/views/res_config_settings_views.xml +++ b/addons/purchase/views/res_config_settings_views.xml @@ -56,7 +56,7 @@
+ title="Calls for tenders are when you want to generate requests for quotations with several vendors for a given set of products to compare offers.">
diff --git a/addons/purchase_requisition/__manifest__.py b/addons/purchase_requisition/__manifest__.py index 6681c175d17..4e017b90795 100644 --- a/addons/purchase_requisition/__manifest__.py +++ b/addons/purchase_requisition/__manifest__.py @@ -20,7 +20,6 @@ are agreements you have with vendors to benefit from a predetermined pricing. 'views/product_views.xml', 'views/purchase_views.xml', 'views/purchase_requisition_views.xml', - 'views/res_config_settings_views.xml', 'report/purchase_requisition_report.xml', 'report/report_purchaserequisition.xml', ], diff --git a/addons/purchase_requisition/data/purchase_requisition_data.xml b/addons/purchase_requisition/data/purchase_requisition_data.xml index 0eeee2a5b8b..d684ccb8dd1 100644 --- a/addons/purchase_requisition/data/purchase_requisition_data.xml +++ b/addons/purchase_requisition/data/purchase_requisition_data.xml @@ -6,20 +6,6 @@ 3 none - - Call for Tender - 1 - copy - - - - Call for Tender - purchase.requisition.purchase.tender - TE - 5 - - - Blanket Order purchase.requisition.blanket.order diff --git a/addons/purchase_requisition/data/purchase_requisition_demo.xml b/addons/purchase_requisition/data/purchase_requisition_demo.xml index 7a7e6ae4ec1..50098da1813 100644 --- a/addons/purchase_requisition/data/purchase_requisition_demo.xml +++ b/addons/purchase_requisition/data/purchase_requisition_demo.xml @@ -1,35 +1,31 @@ - - - tenders - - - - - + + + + - - + + - 5 + 100 + 60 - + - - + - + @@ -39,13 +35,15 @@ 60 - 5 + 25 - + + + - + @@ -54,10 +52,8 @@ - 50 - 3 - - - + 60 + 10 + diff --git a/addons/purchase_requisition/models/product.py b/addons/purchase_requisition/models/product.py index aa0528dbda2..b1ea9bc9123 100644 --- a/addons/purchase_requisition/models/product.py +++ b/addons/purchase_requisition/models/product.py @@ -20,15 +20,3 @@ class ProductProduct(models.Model): return sellers.filtered(lambda s: not s.purchase_requisition_id or s.purchase_requisition_id == params['order_id'].requisition_id) else: return sellers - - -class ProductTemplate(models.Model): - _inherit = 'product.template' - - purchase_requisition = fields.Selection( - [('rfq', 'Create a draft purchase order'), - ('tenders', 'Propose a call for tenders')], - string='Procurement', default='rfq', - help="Create a draft purchase order: Based on your product configuration, the system will create a draft " - "purchase order.Propose a call for tender : If the 'purchase_requisition' module is installed and this option " - "is selected, the system will create a draft call for tender.") diff --git a/addons/purchase_requisition/models/purchase_requisition.py b/addons/purchase_requisition/models/purchase_requisition.py index fa7050c7a1f..a2bdef796e0 100644 --- a/addons/purchase_requisition/models/purchase_requisition.py +++ b/addons/purchase_requisition/models/purchase_requisition.py @@ -129,10 +129,7 @@ class PurchaseRequisition(models.Model): self.write({'state': 'in_progress'}) # Set the sequence number regarding the requisition type if self.name == 'New': - if self.is_quantity_copy != 'none': - self.name = self.env['ir.sequence'].next_by_code('purchase.requisition.purchase.tender') - else: - self.name = self.env['ir.sequence'].next_by_code('purchase.requisition.blanket.order') + self.name = self.env['ir.sequence'].next_by_code('purchase.requisition.blanket.order') def action_open(self): self.write({'state': 'open'}) diff --git a/addons/purchase_requisition/report/purchase_requisition_report.xml b/addons/purchase_requisition/report/purchase_requisition_report.xml index 732d9714e09..8e751123dc1 100644 --- a/addons/purchase_requisition/report/purchase_requisition_report.xml +++ b/addons/purchase_requisition/report/purchase_requisition_report.xml @@ -1,12 +1,12 @@ - Call for Tenders + Purchase Agreements purchase.requisition qweb-pdf purchase_requisition.report_purchaserequisitions purchase_requisition.report.report_purchaserequisitions - 'Tender - %s' % (object.name) + 'Purchase Agreement - %s' % (object.name) report diff --git a/addons/purchase_requisition/tests/common.py b/addons/purchase_requisition/tests/common.py index ff6056f0b6c..67072441d6b 100644 --- a/addons/purchase_requisition/tests/common.py +++ b/addons/purchase_requisition/tests/common.py @@ -53,16 +53,15 @@ class TestPurchaseRequisitionCommon(common.TransactionCase): 'uom_id': cls.product_uom_id.id, 'uom_po_id': cls.product_uom_id.id, 'default_code': 'FURN_1118', - 'purchase_requisition': 'tenders', }) # In order to test process of the purchase requisition ,create requisition - cls.requisition1 = cls.env['purchase.requisition'].create({ + cls.bo_requisition = cls.env['purchase.requisition'].create({ 'line_ids': [(0, 0, { 'product_id': cls.product_09.id, 'product_qty': 10.0, 'product_uom_id': cls.product_uom_id.id})] - }) + }) cls.res_partner_1 = cls.env['res.partner'].create({ 'name': 'Wood Corner', diff --git a/addons/purchase_requisition/tests/test_purchase_requisition.py b/addons/purchase_requisition/tests/test_purchase_requisition.py index 3a4b218ab60..0e8d27e8b9a 100644 --- a/addons/purchase_requisition/tests/test_purchase_requisition.py +++ b/addons/purchase_requisition/tests/test_purchase_requisition.py @@ -11,14 +11,13 @@ class TestPurchaseRequisition(TestPurchaseRequisitionCommon): self.assertTrue(self.user_purchase_requisition_user, 'User Should be created') def test_01_cancel_purchase_requisition(self): - self.requisition1.with_user(self.user_purchase_requisition_user).action_cancel() + self.bo_requisition.with_user(self.user_purchase_requisition_user).action_cancel() # Check requisition after cancelled. - self.assertEqual(self.requisition1.state, 'cancel', 'Requisition should be in cancelled state.') + self.assertEqual(self.bo_requisition.state, 'cancel', 'Requisition should be in cancelled state.') # I reset requisition as "New". - self.requisition1.with_user(self.user_purchase_requisition_user).action_draft() + self.bo_requisition.with_user(self.user_purchase_requisition_user).action_draft() # I duplicate requisition. - self.requisition1.with_user(self.user_purchase_requisition_user).copy() - + self.bo_requisition.with_user(self.user_purchase_requisition_user).copy() def test_02_purchase_requisition(self): price_product09 = 34 @@ -42,7 +41,7 @@ class TestPurchaseRequisition(TestPurchaseRequisitionCommon): # confirm the requisition requisition_blanket.action_in_progress() - # Check for both product that the new supplier info(purchase.requisition.vendor_id) is added to the puchase tab + # Check for both product that the new supplier info(purchase.requisition.vendor_id) is added to the purchase tab # and check the quantity seller_partner1 = self.res_partner_1 supplierinfo09 = self.env['product.supplierinfo'].search([ @@ -50,16 +49,16 @@ class TestPurchaseRequisition(TestPurchaseRequisitionCommon): ('product_id', '=', self.product_09.id), ('purchase_requisition_id', '=', requisition_blanket.id), ]) - self.assertEqual(supplierinfo09.partner_id, seller_partner1, 'The supplierinfo is not the good one') - self.assertEqual(supplierinfo09.price, price_product09, 'The supplierinfo is not the good one') + self.assertEqual(supplierinfo09.partner_id, seller_partner1, 'The supplierinfo is not correct') + self.assertEqual(supplierinfo09.price, price_product09, 'The supplierinfo is not correct') supplierinfo13 = self.env['product.supplierinfo'].search([ ('partner_id', '=', seller_partner1.id), ('product_id', '=', self.product_13.id), ('purchase_requisition_id', '=', requisition_blanket.id), ]) - self.assertEqual(supplierinfo13.partner_id, seller_partner1, 'The supplierinfo is not the good one') - self.assertEqual(supplierinfo13.price, price_product13, 'The supplierinfo is not the good one') + self.assertEqual(supplierinfo13.partner_id, seller_partner1, 'The supplierinfo is not correct') + self.assertEqual(supplierinfo13.price, price_product13, 'The supplierinfo is not correct') # Put the requisition in done Status requisition_blanket.action_in_progress() @@ -69,7 +68,7 @@ class TestPurchaseRequisition(TestPurchaseRequisitionCommon): self.assertFalse(self.env['product.supplierinfo'].search([('id', '=', supplierinfo13.id)]), 'The supplier info should be removed') def test_06_purchase_requisition(self): - """ Create a blanquet order for a product and a vendor already linked via + """ Create a blanket order for a product and a vendor already linked via a supplier info""" product = self.env['product.product'].create({ 'name': 'test6', @@ -85,7 +84,7 @@ class TestPurchaseRequisition(TestPurchaseRequisitionCommon): 'partner_id': vendor.id, }) - # create a empty blanquet order + # create an empty blanket order requisition_type = self.env['purchase.requisition.type'].create({ 'name': 'Blanket test', 'quantity_copy': 'none' diff --git a/addons/purchase_requisition/views/product_views.xml b/addons/purchase_requisition/views/product_views.xml index e8609da5b6c..06a57cdcc11 100644 --- a/addons/purchase_requisition/views/product_views.xml +++ b/addons/purchase_requisition/views/product_views.xml @@ -24,18 +24,4 @@ - - - product.template.form.inherit - product.template - - - - - - - - - - diff --git a/addons/purchase_requisition/views/purchase_requisition_views.xml b/addons/purchase_requisition/views/purchase_requisition_views.xml index 223f3d82ee9..a309bdcc8c1 100644 --- a/addons/purchase_requisition/views/purchase_requisition_views.xml +++ b/addons/purchase_requisition/views/purchase_requisition_views.xml @@ -71,17 +71,6 @@ - - Purchase Agreement Types - purchase.requisition.type - {} - tree,kanban,form - - @@ -163,7 +152,7 @@ - @@ -177,7 +166,7 @@
- @@ -289,7 +278,7 @@ - Purchase Agreements + Blanket Orders ir.actions.act_window purchase.requisition tree,kanban,form @@ -299,15 +288,10 @@

Start a new purchase agreement

- Example of purchase agreements include call for tenders and blanket orders. -

- In a call for tenders, you can record the products you need to buy - and generate the creation of RfQs to vendors. Once the tenders have - been registered, you can review and compare them and you can - validate some and cancel others. + An example of a purchase agreement is a blanket order.

For a blanket order, you can record an agreement for a specific period - (e.g. a year) and you order products within this agreement, benefiting + (e.g. a year) and you order products within this agreement to benefit from the negotiated prices.

diff --git a/addons/purchase_requisition/views/res_config_settings_views.xml b/addons/purchase_requisition/views/res_config_settings_views.xml deleted file mode 100644 index 88cdebb21e1..00000000000 --- a/addons/purchase_requisition/views/res_config_settings_views.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - res.config.settings.view.form.inherit.purchase.requisition - res.config.settings - - -
-
-
-
-
-
-
diff --git a/addons/purchase_requisition_stock/data/purchase_requisition_stock_demo.xml b/addons/purchase_requisition_stock/data/purchase_requisition_stock_demo.xml index a7480a3dd80..2527724b896 100644 --- a/addons/purchase_requisition_stock/data/purchase_requisition_stock_demo.xml +++ b/addons/purchase_requisition_stock/data/purchase_requisition_stock_demo.xml @@ -1,7 +1,7 @@ - + diff --git a/addons/purchase_requisition_stock/models/purchase_requisition.py b/addons/purchase_requisition_stock/models/purchase_requisition.py index 1c70f0daa23..1050381b7d5 100644 --- a/addons/purchase_requisition_stock/models/purchase_requisition.py +++ b/addons/purchase_requisition_stock/models/purchase_requisition.py @@ -14,24 +14,6 @@ class PurchaseRequisition(models.Model): picking_type_id = fields.Many2one( 'stock.picking.type', 'Operation Type', required=True, default=_default_picking_type_id, domain="['|',('warehouse_id', '=', False), ('warehouse_id.company_id', '=', company_id)]") - procurement_group_id = fields.Many2one('procurement.group', 'Procurement Group') - - def _prepare_tender_values(self, product_id, product_qty, product_uom, location_id, name, origin, company_id, values): - return { - 'origin': origin, - 'date_end': values['date_planned'], - 'user_id': False, - 'warehouse_id': values.get('warehouse_id') and values['warehouse_id'].id or False, - 'procurement_group_id': values.get('group_id') and values['group_id'].id or False, - 'company_id': company_id.id, - 'line_ids': [(0, 0, { - 'product_id': product_id.id, - 'product_uom_id': product_uom.id, - 'product_qty': product_qty, - 'product_description_variants': values.get('product_description_variants'), - 'move_dest_id': values.get('move_dest_ids') and values['move_dest_ids'][0].id or False - })], - } class PurchaseRequisitionLine(models.Model): diff --git a/addons/purchase_requisition_stock/models/stock.py b/addons/purchase_requisition_stock/models/stock.py index 0e1648ec684..08bcc368a8a 100644 --- a/addons/purchase_requisition_stock/models/stock.py +++ b/addons/purchase_requisition_stock/models/stock.py @@ -1,29 +1,12 @@ # -*- encoding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from collections import defaultdict - -from odoo import api, fields, models +from odoo import fields, models class StockRule(models.Model): _inherit = 'stock.rule' - @api.model - def _run_buy(self, procurements): - requisitions_values_by_company = defaultdict(list) - other_procurements = [] - for procurement, rule in procurements: - if procurement.product_id.purchase_requisition == 'tenders': - values = self.env['purchase.requisition']._prepare_tender_values(*procurement) - values['picking_type_id'] = rule.picking_type_id.id - requisitions_values_by_company[procurement.company_id.id].append(values) - else: - other_procurements.append((procurement, rule)) - for company_id, requisitions_values in requisitions_values_by_company.items(): - self.env['purchase.requisition'].sudo().with_company(company_id).create(requisitions_values) - return super(StockRule, self)._run_buy(other_procurements) - def _prepare_purchase_order(self, company_id, origins, values): res = super(StockRule, self)._prepare_purchase_order(company_id, origins, values) values = values[0] diff --git a/addons/purchase_requisition_stock/tests/test_purchase_requisition_stock.py b/addons/purchase_requisition_stock/tests/test_purchase_requisition_stock.py index d6a63c02140..2e21441b974 100644 --- a/addons/purchase_requisition_stock/tests/test_purchase_requisition_stock.py +++ b/addons/purchase_requisition_stock/tests/test_purchase_requisition_stock.py @@ -9,42 +9,6 @@ from odoo.addons.purchase_requisition.tests.common import TestPurchaseRequisitio class TestPurchaseRequisitionStock(TestPurchaseRequisitionCommon): - def test_01_purchase_requisition_stock(self): - date_planned = fields.Datetime.now() - warehouse = self.env['stock.warehouse'].browse(self.ref('stock.warehouse0')) - self.env['procurement.group'].run([self.env['procurement.group'].Procurement( - self.product_13, - 14, - self.env['uom.uom'].browse(self.ref('uom.product_uom_unit')), - warehouse.lot_stock_id, - '/', - '/', - self.env.company, - { - 'warehouse_id': warehouse, - 'date_planned': date_planned, - } - )]) - # Check requisition details which created after run procurement. - line = self.env['purchase.requisition.line'].search([('product_id', '=', self.product_13.id), ('product_qty', '=', 14.0)]) - requisition = line[0].requisition_id - self.assertEqual(requisition.date_end, date_planned, "End date does not correspond.") - self.assertEqual(len(requisition.line_ids), 1, "Requisition Lines should be one.") - self.assertEqual(line.product_uom_id.id, self.ref('uom.product_uom_unit'), "UOM is not correspond.") - - # Give access rights of Purchase Requisition User to open requisition - # Set tender state to choose tendering line. - self.requisition1.with_user(self.user_purchase_requisition_user).action_in_progress() - self.requisition1.with_user(self.user_purchase_requisition_user).action_open() - - # Vendor send one RFQ so I create a RfQ of that agreement. - PurchaseOrder = self.env['purchase.order'] - purchase_order = PurchaseOrder.new({'partner_id': self.res_partner_1, 'requisition_id': self.requisition1.id}) - purchase_order._onchange_requisition_id() - po_dict = purchase_order._convert_to_write({name: purchase_order[name] for name in purchase_order._cache}) - self.po_requisition = PurchaseOrder.create(po_dict) - self.assertEqual(len(self.po_requisition.order_line), 1, 'Purchase order should have one line') - def test_02_purchase_requisition_stock(self): """Plays with the sequence of regular supplier infos and one created by blanket orders.""" # Product creation