From 4c5b55a7dd9177894e691a973be37e3271484f73 Mon Sep 17 00:00:00 2001 From: Marc Durepos Date: Tue, 11 Feb 2025 14:27:50 -0500 Subject: [PATCH] Fixes to purchase_customer_requisition and shipping info on cust. inv. purchase_customer_requisition: * Make sure to check the validity (state + dates) on purchase requisitions being selected for PO lines. shipping_information_on_customer_invoice: * Rework how the picking is selected, going through the sale lines related to the invoice lines instead of the non-existing picking_id field previously coded. --- .../models/purchase_order_line.py | 4 + .../tests/test_purchase_order.py | 115 +++++++++++++++++- .../__manifest__.py | 22 ++-- .../models/account_move.py | 32 +++-- .../views/report_invoice.xml | 31 ++--- 5 files changed, 155 insertions(+), 49 deletions(-) diff --git a/purchase_customer_requisition/models/purchase_order_line.py b/purchase_customer_requisition/models/purchase_order_line.py index 3a2a851..3926713 100644 --- a/purchase_customer_requisition/models/purchase_order_line.py +++ b/purchase_customer_requisition/models/purchase_order_line.py @@ -53,6 +53,7 @@ class PurchaseOrderLine(models.Model): def _compute_requisition_id(self): for line in self: customer = line._get_customer() + order_date = line.order_id.date_order domain = [ "|", ("requisition_id.vendor_id", "=", line.order_id.partner_id.id), @@ -62,6 +63,9 @@ class PurchaseOrderLine(models.Model): line.order_id.partner_id.id, ), ("product_id", "=", line.product_id.id), + ("requisition_id.state", "=", "confirmed"), + ("requisition_id.date_start", "<=", order_date), + ("requisition_id.date_end", ">=", order_date), ] requisition = self.order_id.requisition_id if customer: diff --git a/purchase_customer_requisition/tests/test_purchase_order.py b/purchase_customer_requisition/tests/test_purchase_order.py index 62a9590..87d06b0 100644 --- a/purchase_customer_requisition/tests/test_purchase_order.py +++ b/purchase_customer_requisition/tests/test_purchase_order.py @@ -89,7 +89,7 @@ class TestPurchaseOrder(TransactionCase): "date_end": fields.Date.today() + timedelta(days=265), } ) - cls.agreement_1.action_confirm() + cls.agreement_2.action_confirm() def test_one_purchase_order_line_gets_correct_agreement(self): sale_order = self.env["sale.order"].create( @@ -175,3 +175,116 @@ class TestPurchaseOrder(TransactionCase): line.requisition_id = False self.assertEqual(purchase_order.order_line[0].price_unit, 3000) + + def test_requisition_selection_state_and_validity(self): + """Test that requisitions are only selected if they are confirmed and currently valid.""" + # Create a draft requisition + draft_agreement = self.env["purchase.requisition"].create( + { + "vendor_id": self.supplier.id, + "customer_ids": [Command.set([self.client_1.id])], + "line_ids": [ + Command.create( + { + "product_id": self.product_1.id, + "product_qty": 100, + "price_unit": 4000, + } + ), + ], + "date_start": fields.Date.today() - timedelta(days=100), + "date_end": fields.Date.today() + timedelta(days=265), + } + ) + + # Create an expired requisition + expired_agreement = self.env["purchase.requisition"].create( + { + "vendor_id": self.supplier.id, + "customer_ids": [Command.set([self.client_1.id])], + "line_ids": [ + Command.create( + { + "product_id": self.product_1.id, + "product_qty": 100, + "price_unit": 5000, + } + ), + ], + "date_start": fields.Date.today() - timedelta(days=200), + "date_end": fields.Date.today() - timedelta(days=100), + } + ) + expired_agreement.action_confirm() + + # Create a future requisition + future_agreement = self.env["purchase.requisition"].create( + { + "vendor_id": self.supplier.id, + "customer_ids": [Command.set([self.client_1.id])], + "line_ids": [ + Command.create( + { + "product_id": self.product_1.id, + "product_qty": 100, + "price_unit": 6000, + } + ), + ], + "date_start": fields.Date.today() + timedelta(days=100), + "date_end": fields.Date.today() + timedelta(days=200), + } + ) + future_agreement.action_confirm() + + # Create and confirm a sale order + sale_order = self.env["sale.order"].create( + { + "partner_id": self.client_1.id, + "order_line": [ + Command.create( + { + "product_id": self.product_1.id, + "product_uom_qty": 50, + } + ) + ], + } + ) + sale_order.action_confirm() + + # Verify that the purchase order line gets the correct agreement (agreement_1) + purchase_order = sale_order._get_purchase_orders()[0] + purchase_line = purchase_order.order_line[0] + + # Should select agreement_1 which is confirmed and currently valid + self.assertEqual( + purchase_line.requisition_id, + self.agreement_1, + "Purchase order line should select the confirmed and currently valid agreement", + ) + self.assertEqual( + purchase_line.price_unit, + 1000, + "Purchase order line should have the price from the valid agreement", + ) + + # The other agreements should not be selected because: + # - draft_agreement is not confirmed + # - expired_agreement is outside its validity dates + # - future_agreement hasn't started yet + self.assertNotEqual( + purchase_line.requisition_id, + draft_agreement, + "Draft agreement should not be selected", + ) + self.assertNotEqual( + purchase_line.requisition_id, + expired_agreement, + "Expired agreement should not be selected", + ) + self.assertNotEqual( + purchase_line.requisition_id, + future_agreement, + "Future agreement should not be selected", + ) diff --git a/shipping_information_on_customer_invoice/__manifest__.py b/shipping_information_on_customer_invoice/__manifest__.py index 19a3877..5cd29b8 100644 --- a/shipping_information_on_customer_invoice/__manifest__.py +++ b/shipping_information_on_customer_invoice/__manifest__.py @@ -1,19 +1,19 @@ { - 'name': 'Shipping Information on Customer Invoice', - 'version': '18.0.0.1', - 'category': 'Accounting', - 'summary': 'Add shipping carrier information on customer invoices', - 'description': """ + "name": "Shipping Information on Customer Invoice", + "version": "18.0.0.1", + "category": "Accounting", + "summary": "Add shipping carrier information on customer invoices", + "description": """ This module adds shipping carrier information to customer invoices: * Carrier name * Tracking number * Billing mode """, - 'depends': ['account', 'delivery'], - 'data': [ - 'views/report_invoice.xml', + "depends": ["account", "delivery", "delivery_carrier_partner_account"], + "data": [ + "views/report_invoice.xml", ], - 'installable': True, - 'auto_install': False, - 'license': 'LGPL-3', + "installable": True, + "auto_install": False, + "license": "LGPL-3", } diff --git a/shipping_information_on_customer_invoice/models/account_move.py b/shipping_information_on_customer_invoice/models/account_move.py index 5ec2c0d..8419923 100644 --- a/shipping_information_on_customer_invoice/models/account_move.py +++ b/shipping_information_on_customer_invoice/models/account_move.py @@ -1,21 +1,17 @@ from odoo import api, fields, models -class AccountMove(models.Model): - _inherit = 'account.move' - def _get_delivery_info(self): - """Get the delivery information for the invoice.""" - self.ensure_one() - if self.move_type != 'out_invoice': - return False - - deliveries = self.picking_ids.filtered(lambda p: p.carrier_id) - if not deliveries: - return False - - carrier = deliveries[0].carrier_id - return { - 'carrier_name': carrier.name, - 'tracking_ref': deliveries[0].carrier_tracking_ref or '', - 'invoice_policy': dict(carrier._fields['invoice_policy'].selection).get(carrier.invoice_policy, carrier.invoice_policy), - } +class AccountMove(models.Model): + _inherit = "account.move" + + picking_id = fields.One2many( + comodel_name="stock.picking", + string="Pickings", + compute="_compute_picking_id", + ) + + @api.depends("invoice_line_ids.sale_line_ids.move_ids.picking_id") + def _compute_picking_id(self): + for move in self: + pickings = move.invoice_line_ids.mapped("sale_line_ids.move_ids.picking_id") + move.picking_id = pickings and pickings[0] or False diff --git a/shipping_information_on_customer_invoice/views/report_invoice.xml b/shipping_information_on_customer_invoice/views/report_invoice.xml index b1855d0..28eff1f 100644 --- a/shipping_information_on_customer_invoice/views/report_invoice.xml +++ b/shipping_information_on_customer_invoice/views/report_invoice.xml @@ -2,25 +2,18 @@