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.
This commit is contained in:
parent
dd76c00ec1
commit
4c5b55a7dd
5 changed files with 155 additions and 49 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -2,25 +2,18 @@
|
|||
<odoo>
|
||||
<template id="report_invoice_document_inherit_shipping" inherit_id="account.report_invoice_document">
|
||||
<xpath expr="//div[@id='informations']" position="inside">
|
||||
<t t-if="o._get_delivery_info()">
|
||||
<div class="col-auto col-3 mw-100 mb-2" name="shipping_info">
|
||||
<strong>Shipping Information:</strong>
|
||||
<p class="m-0">
|
||||
<strong>Carrier: </strong>
|
||||
<span t-esc="o._get_delivery_info()['carrier_name']"/>
|
||||
</p>
|
||||
<t t-if="o._get_delivery_info()['tracking_ref']">
|
||||
<p class="m-0">
|
||||
<strong>Tracking: </strong>
|
||||
<span t-esc="o._get_delivery_info()['tracking_ref']"/>
|
||||
</p>
|
||||
</t>
|
||||
<p class="m-0">
|
||||
<strong>Billing Mode: </strong>
|
||||
<span t-esc="o._get_delivery_info()['invoice_policy']"/>
|
||||
</p>
|
||||
</div>
|
||||
</t>
|
||||
<div class="col-auto col-3 mw-100 mb-2" name="carrier" t-if="o.picking_id.carrier_id">
|
||||
<strong>Carrier: </strong>
|
||||
<span t-field="o.picking_id.carrier_id.name"/>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" name="tracking" t-if="o.picking_id.carrier_tracking_ref">
|
||||
<strong>Tracking: </strong>
|
||||
<span t-field="o.picking_id.carrier_tracking_ref"/>
|
||||
</div>
|
||||
<div class="col-auto col-3 mw-100 mb-2" name="delivery_billing_mode" t-if="o.picking_id.delivery_billing_mode">
|
||||
<strong>Billing Mode: </strong>
|
||||
<span t-field="o.picking_id.delivery_billing_mode"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
|
|||
Loading…
Reference in a new issue