Skip to content

Commit

Permalink
[14.0][IMP] account_invoice_report_grouped_by_picking: Show section a…
Browse files Browse the repository at this point in the history
…nd notes at the end of invoice
  • Loading branch information
manuelregidor committed Apr 3, 2024
1 parent b33a456 commit b87a36e
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 3 deletions.
27 changes: 25 additions & 2 deletions account_invoice_report_grouped_by_picking/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ class AccountMove(models.Model):
@api.model
def _sort_grouped_lines(self, lines_dic):
min_date = datetime.datetime.min
return sorted(
dictionary = sorted(
lines_dic,
key=lambda x: (
(
x["picking"].date or min_date,
x["picking"].date_done or x["picking"].date or min_date,
x.get("is_last_section_notes", False),
)
),
)
return dictionary

def _get_signed_quantity_done(self, invoice_line, move, sign):
"""Hook method. Usage example:
Expand Down Expand Up @@ -70,15 +72,33 @@ def lines_grouped_by_picking(self):
so_dict = {x.sale_id: x for x in self.picking_ids if x.sale_id}
# Now group by picking by direct link or via same SO as picking's one
previous_section = previous_note = False
last_section_notes = []
for line in self.invoice_line_ids.sorted(
lambda ln: (-ln.sequence, ln.date, ln.move_name, -ln.id), reverse=True
):
if line.display_type == "line_section":
previous_section = line
last_section_notes.append(
{
"picking": picking_obj,
"line": line,
"qty": 0.0,
"is_last_section_notes": True,
}
)
continue
if line.display_type == "line_note":
previous_note = line
last_section_notes.append(
{
"picking": picking_obj,
"line": line,
"qty": 0.0,
"is_last_section_notes": True,
}
)
continue
last_section_notes = []
has_returned_qty = False
remaining_qty = line.quantity
for move in line.move_line_ids:
Expand Down Expand Up @@ -135,4 +155,7 @@ def lines_grouped_by_picking(self):
{"picking": key[0], "line": key[1], "quantity": value}
for key, value in picking_dict.items()
]
return no_picking + self._sort_grouped_lines(with_picking)
lines_to_sort = with_picking
if last_section_notes:
lines_to_sort += last_section_notes
return no_picking + self._sort_grouped_lines(lines_to_sort)
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,62 @@ def test_account_invoice_group_picking_refund_without_return(self):
self.assertEqual(tbody.count(self.sale.name), 1)
# information about pickings is printed
self.assertTrue(picking.name in tbody)

def test_account_invoice_group_picking_note_section_end(self):
# confirm quotation
self.sale.action_confirm()
# deliver lines2
picking = self.sale.picking_ids[:1]
picking.action_confirm()
picking.move_line_ids.write({"qty_done": 1})
picking._action_done()
# invoice sales
invoice = self.sale._create_invoices()
groups = invoice.lines_grouped_by_picking()
self.assertEqual(len(groups), 2)
invoice.write(
{
"invoice_line_ids": [
(
0,
0,
{
"name": "Note",
"display_type": "line_note",
},
),
(
0,
0,
{
"name": "Section",
"display_type": "line_section",
},
),
],
}
)
groups = invoice.lines_grouped_by_picking()
self.assertEqual(len(groups), 4)
self.assertTrue(groups[0].get("is_last_section_notes", False))
self.assertTrue(groups[1].get("is_last_section_notes", False))
self.assertFalse(groups[2].get("is_last_section_notes", False))
self.assertFalse(groups[3].get("is_last_section_notes", False))
invoice.invoice_line_ids.filtered(
lambda a: a.product_id == self.product
).with_context(check_move_validity=False).write({"quantity": 3})
invoice.invoice_line_ids.filtered(
lambda a: a.product_id == self.service
).with_context(check_move_validity=False).write({"quantity": 4})
groups = invoice.lines_grouped_by_picking()
self.assertEqual(len(groups), 6)
self.assertFalse(groups[0].get("is_last_section_notes", False))
self.assertFalse(groups[0]["picking"])
self.assertFalse(groups[1].get("is_last_section_notes", False))
self.assertFalse(groups[1]["picking"])
self.assertTrue(groups[2].get("is_last_section_notes", False))
self.assertTrue(groups[3].get("is_last_section_notes", False))
self.assertFalse(groups[4].get("is_last_section_notes", False))
self.assertTrue(groups[4]["picking"])
self.assertFalse(groups[5].get("is_last_section_notes", False))
self.assertTrue(groups[5]["picking"])
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,17 @@
<t t-set="l" t-value="lines_group['line']" />
<t t-set="line" t-value="lines_group['line']" />
<t t-set="picking" t-value="lines_group['picking']" />
<t
t-set="next_line"
t-value="[lines_grouped[i + 1] for i, x in enumerate(lines_grouped) if x == lines_group and i &lt; len(lines_grouped) - 1] or [False]"
/>
<t
t-set="next_picking"
t-value="[lines_grouped[i + 1]['picking'] for i, x in enumerate(lines_grouped) if x == lines_group and i &lt; len(lines_grouped) - 1] or [False]"
/>
<!-- Avoid to show original subtotal -->
<t t-set="line_last" t-value="False" />
<t t-set="line_index" t-value="0" />

<t t-if="picking != last_picking">
<t t-set="last_picking" t-value="picking" />
<tr t-if="picking">
Expand Down Expand Up @@ -121,6 +124,21 @@
<t t-set="subtotal" t-value="0.0" />
</tr>
</xpath>
<!-- Append subtotal after notes and sections at the end of the invoice-->
<xpath expr="//t[@name='account_invoice_line_accountable']/.." position="after">
<tr
t-if="lines_group.get('is_last_section_notes') and (not next_line or not next_line[0].get('is_last_section_notes')) and subtotal"
>
<td colspan="10" class="text-right">
<strong>Subtotal: </strong>
<strong
t-esc="subtotal"
t-options='{"widget": "monetary", "display_currency": o.currency_id}'
/>
</td>
<t t-set="subtotal" t-value="0.0" />
</tr>
</xpath>
<xpath expr="//td/span[@t-field='line.price_total']" position="attributes">
<attribute name="t-if">lines_group['quantity'] == l.quantity</attribute>
</xpath>
Expand Down

0 comments on commit b87a36e

Please sign in to comment.