[FIX] purchase: don't mix PO's lines in generated invoices
If we use the auto-complete feature to add PO's lines to an bill or we select multiple PO's then use 'create bill' button, the generated invoice line will copy the sequence line from the PO's line. This can lead to situation where we will have all the first lines of each PO then all the second, etc, ending with a mix of all PO's in the bill. Example: Purchase order 1 - seq 10 line A - seq 11 line B - seq 12 line C Purchase order 2 - seq 10 line A' - seq 11 line B' - seq 12 line C' Invoice created from those PO's - seq 10 PO1:line A - seq 10 PO2:line A' - seq 11 PO1:line B - seq 11 PO2:line B' - seq 12 PO1:line C - seq 12 PO2:line C' After this PR this PR the lines from the same PO's will be contiguous like: Invoice created from those PO 1 and 2 - seq 10 PO1:line A - seq 11 PO1:line B - seq 12 PO1:line C - seq 13 PO2:line A' - seq 14 PO2:line B' - seq 15 PO2:line C' opw-2749682 closes odoo/odoo#95343 X-original-commit: cafe5c1aff1ca1632ce4924a6b027629c283a5e9 Signed-off-by: Steve Van Essche <svs@odoo.com> Signed-off-by: Beckers Thomas (tbs) <tbs@odoo.com>
This commit is contained in:
@@ -53,8 +53,12 @@ class AccountMove(models.Model):
|
||||
# Copy purchase lines.
|
||||
po_lines = self.purchase_id.order_line - self.line_ids.mapped('purchase_line_id')
|
||||
new_lines = self.env['account.move.line']
|
||||
sequence = max(self.line_ids.mapped('sequence')) + 1 if self.line_ids else 10
|
||||
for line in po_lines.filtered(lambda l: not l.display_type):
|
||||
new_line = new_lines.new(line._prepare_account_move_line(self))
|
||||
line_vals = line._prepare_account_move_line(self)
|
||||
line_vals.update({'sequence': sequence})
|
||||
new_line = new_lines.new(line_vals)
|
||||
sequence += 1
|
||||
new_line.account_id = new_line._get_computed_account()
|
||||
new_line._onchange_price_subtotal()
|
||||
new_lines += new_line
|
||||
|
||||
@@ -541,6 +541,7 @@ class PurchaseOrder(models.Model):
|
||||
|
||||
# 1) Prepare invoice vals and clean-up the section lines
|
||||
invoice_vals_list = []
|
||||
sequence = 10
|
||||
for order in self:
|
||||
if order.invoice_status != 'to invoice':
|
||||
continue
|
||||
@@ -556,9 +557,15 @@ class PurchaseOrder(models.Model):
|
||||
continue
|
||||
if not float_is_zero(line.qty_to_invoice, precision_digits=precision):
|
||||
if pending_section:
|
||||
invoice_vals['invoice_line_ids'].append((0, 0, pending_section._prepare_account_move_line()))
|
||||
line_vals = pending_section._prepare_account_move_line()
|
||||
line_vals.update({'sequence': sequence})
|
||||
invoice_vals['invoice_line_ids'].append((0, 0, line_vals))
|
||||
sequence += 1
|
||||
pending_section = None
|
||||
invoice_vals['invoice_line_ids'].append((0, 0, line._prepare_account_move_line()))
|
||||
line_vals = line._prepare_account_move_line()
|
||||
line_vals.update({'sequence': sequence})
|
||||
invoice_vals['invoice_line_ids'].append((0, 0, line_vals))
|
||||
sequence += 1
|
||||
invoice_vals_list.append(invoice_vals)
|
||||
|
||||
if not invoice_vals_list:
|
||||
|
||||
@@ -327,3 +327,75 @@ class TestPurchaseToInvoice(AccountTestInvoicingCommon):
|
||||
|
||||
aml = self.env['account.move.line'].search([('purchase_line_id', '=', purchase_order.order_line.id)])
|
||||
self.assertRecordValues(aml, [{'analytic_account_id': analytic_account_manual.id}])
|
||||
|
||||
def test_sequence_invoice_lines_from_multiple_purchases(self):
|
||||
"""Test if the invoice lines are sequenced by purchase order when creating an invoice
|
||||
from multiple selected po's"""
|
||||
purchase_orders = self.env['purchase.order']
|
||||
|
||||
for _ in range(3):
|
||||
pol_vals = [
|
||||
(0, 0, {
|
||||
'name': self.product_order.name,
|
||||
'product_id': self.product_order.id,
|
||||
'product_qty': 10.0,
|
||||
'product_uom': self.product_order.uom_id.id,
|
||||
'price_unit': self.product_order.list_price,
|
||||
'taxes_id': False,
|
||||
'sequence': sequence_number,
|
||||
}) for sequence_number in range(10, 13)]
|
||||
purchase_order = self.env['purchase.order'].with_context(tracking_disable=True).create({
|
||||
'partner_id': self.partner_a.id,
|
||||
'order_line': pol_vals,
|
||||
})
|
||||
purchase_order.button_confirm()
|
||||
purchase_orders |= purchase_order
|
||||
|
||||
action = purchase_orders.action_create_invoice()
|
||||
invoice = self.env['account.move'].browse(action['res_id'])
|
||||
|
||||
expected_purchase = [
|
||||
purchase_orders[0], purchase_orders[0], purchase_orders[0],
|
||||
purchase_orders[1], purchase_orders[1], purchase_orders[1],
|
||||
purchase_orders[2], purchase_orders[2], purchase_orders[2],
|
||||
]
|
||||
for line in invoice.invoice_line_ids.sorted('sequence'):
|
||||
self.assertEqual(line.purchase_order_id, expected_purchase.pop(0))
|
||||
|
||||
def test_sequence_autocomplete_invoice(self):
|
||||
"""Test if the invoice lines are sequenced by purchase order when using the autocomplete
|
||||
feature on a bill to add lines from po's"""
|
||||
purchase_orders = self.env['purchase.order']
|
||||
|
||||
for _ in range(3):
|
||||
pol_vals = [
|
||||
(0, 0, {
|
||||
'name': self.product_order.name,
|
||||
'product_id': self.product_order.id,
|
||||
'product_qty': 10.0,
|
||||
'product_uom': self.product_order.uom_id.id,
|
||||
'price_unit': self.product_order.list_price,
|
||||
'taxes_id': False,
|
||||
'sequence': sequence_number,
|
||||
}) for sequence_number in range(10, 13)]
|
||||
purchase_order = self.env['purchase.order'].with_context(tracking_disable=True).create({
|
||||
'partner_id': self.partner_a.id,
|
||||
'order_line': pol_vals,
|
||||
})
|
||||
purchase_order.button_confirm()
|
||||
purchase_orders |= purchase_order
|
||||
|
||||
move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
|
||||
PurchaseBillUnion = self.env['purchase.bill.union']
|
||||
move_form.purchase_vendor_bill_id = PurchaseBillUnion.browse(-purchase_orders[0].id)
|
||||
move_form.purchase_vendor_bill_id = PurchaseBillUnion.browse(-purchase_orders[1].id)
|
||||
move_form.purchase_vendor_bill_id = PurchaseBillUnion.browse(-purchase_orders[2].id)
|
||||
invoice = move_form.save()
|
||||
|
||||
expected_purchase = [
|
||||
purchase_orders[0], purchase_orders[0], purchase_orders[0],
|
||||
purchase_orders[1], purchase_orders[1], purchase_orders[1],
|
||||
purchase_orders[2], purchase_orders[2], purchase_orders[2],
|
||||
]
|
||||
for line in invoice.invoice_line_ids.sorted('sequence'):
|
||||
self.assertEqual(line.purchase_order_id, expected_purchase.pop(0))
|
||||
|
||||
Reference in New Issue
Block a user