[FIX] sale_stock: display lots on invoices
When printing an invoice with tracked products, if there are several
invoices linked to the sale order, the displayed lots may be incorrect
To reproduce the issue:
(Need sale_management)
1. In Settings, enable "Display Lots & Serial Numbers on Invoices"
2. Create two products P01, P02:
- Storable
- Tracked by lot
3. Update their quantity (>1)
4. Create and confirm a SO with 1 x P01 and 1 x P02
5. Deliver the products one by one
6. From the SO, create an invoice INV01
7. On INV01, remove the line associated to P02
8. Post INV01
9. From the SO, create and post the second invoice INV02
10. Print one of the invoices
Error: [1] When printing INV01 (which only contains P01), the lot of P02
is also displayed. [2] When printing INV02 (which only contains P02),
the lot of PO02 is not displayed
When rendering an invoice, `_get_invoiced_lot_values` is called and
provides all data about invoiced lots. However, there are two issues:
- [1] it considers all related SML, even the ones related to a product
not present in the invoice
- [2] when computing the date of the last invoice, it uses the same date
for all products in the invoice although it could be different depending
on the product.
OPW-2637107
closes odoo/odoo#83047
X-original-commit: 9ffd4a9c5755af241a7acc98bc97c790dbb1b84d
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
This commit is contained in:
@@ -31,8 +31,9 @@ class AccountMove(models.Model):
|
||||
if self.state == 'draft':
|
||||
return res
|
||||
|
||||
sale_orders = self.mapped('invoice_line_ids.sale_line_ids.order_id')
|
||||
stock_move_lines = sale_orders.mapped('picking_ids.move_ids.move_line_ids')
|
||||
sale_lines = self.invoice_line_ids.sale_line_ids
|
||||
sale_orders = sale_lines.order_id
|
||||
stock_move_lines = sale_lines.move_ids.filtered(lambda r: r.state == 'done').move_line_ids
|
||||
|
||||
# Get the other customer invoices and refunds.
|
||||
ordered_invoice_ids = sale_orders.mapped('invoice_ids')\
|
||||
@@ -48,27 +49,33 @@ class AccountMove(models.Model):
|
||||
break
|
||||
i += 1
|
||||
|
||||
# Get the previous invoice if any.
|
||||
# Get the previous invoices if any.
|
||||
previous_invoices = ordered_invoice_ids[:self_index]
|
||||
last_invoice = previous_invoices[-1] if len(previous_invoices) else None
|
||||
|
||||
# Get the incoming and outgoing sml between self.invoice_date and the previous invoice (if any).
|
||||
# Get the incoming and outgoing sml between self.invoice_date and the previous invoice (if any) of the related product.
|
||||
write_dates = [wd for wd in self.invoice_line_ids.mapped('write_date') if wd]
|
||||
self_datetime = max(write_dates) if write_dates else None
|
||||
last_write_dates = last_invoice and [wd for wd in last_invoice.invoice_line_ids.mapped('write_date') if wd]
|
||||
last_invoice_datetime = max(last_write_dates) if last_write_dates else None
|
||||
last_invoice_datetime = dict()
|
||||
for product in self.invoice_line_ids.product_id:
|
||||
last_invoice = previous_invoices.filtered(lambda inv: product in inv.invoice_line_ids.product_id)
|
||||
last_invoice = last_invoice[-1] if last_invoice else None
|
||||
last_write_dates = last_invoice and [wd for wd in last_invoice.invoice_line_ids.mapped('write_date') if wd]
|
||||
last_invoice_datetime[product] = max(last_write_dates) if last_write_dates else None
|
||||
|
||||
def _filter_incoming_sml(ml):
|
||||
if ml.state == 'done' and ml.location_id.usage == 'customer' and ml.lot_id:
|
||||
if last_invoice_datetime:
|
||||
return last_invoice_datetime <= ml.date <= self_datetime
|
||||
last_date = last_invoice_datetime.get(ml.product_id)
|
||||
if last_date:
|
||||
return last_date <= ml.date <= self_datetime
|
||||
else:
|
||||
return ml.date <= self_datetime
|
||||
return False
|
||||
|
||||
def _filter_outgoing_sml(ml):
|
||||
if ml.state == 'done' and ml.location_dest_id.usage == 'customer' and ml.lot_id:
|
||||
if last_invoice_datetime:
|
||||
return last_invoice_datetime <= ml.date <= self_datetime
|
||||
last_date = last_invoice_datetime.get(ml.product_id)
|
||||
if last_date:
|
||||
return last_date <= ml.date <= self_datetime
|
||||
else:
|
||||
return ml.date <= self_datetime
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user