From 0a86ef06cd9d79e9aae97f5e077d2338c8502ae9 Mon Sep 17 00:00:00 2001 From: Florian da Costa Date: Tue, 26 Mar 2024 14:47:20 +0100 Subject: [PATCH 1/4] [IMP] Avoid subcontractor on invoice line without subcontracted product --- account_invoice_subcontractor/models/invoice.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/account_invoice_subcontractor/models/invoice.py b/account_invoice_subcontractor/models/invoice.py index 75f1efc..cc85732 100644 --- a/account_invoice_subcontractor/models/invoice.py +++ b/account_invoice_subcontractor/models/invoice.py @@ -83,7 +83,10 @@ def _compute_invalid_work_amount(self): else: line.invalid_work_amount = line._check_out_invoice_amount() else: - line.invalid_work_amount = False + if line.subcontractor_work_ids: + line.invalid_work_amount = line.price_subtotal + else: + line.invalid_work_amount = False def _check_in_invoice_amount(self): return ( From 3f4fe5585ec79d4210550eda17cb1d9f05a656ce Mon Sep 17 00:00:00 2001 From: Florian da Costa Date: Tue, 26 Mar 2024 17:11:08 +0100 Subject: [PATCH 2/4] [IMP] For supplier invoice from subcontractor, chronology is not an issue and today s date can be chosen instead of latest date of all supplier invoices which can lead to strange/inconsistent cases --- .../models/subcontractor_work.py | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/account_invoice_subcontractor/models/subcontractor_work.py b/account_invoice_subcontractor/models/subcontractor_work.py index cd9dc3e..657ebbf 100644 --- a/account_invoice_subcontractor/models/subcontractor_work.py +++ b/account_invoice_subcontractor/models/subcontractor_work.py @@ -267,12 +267,27 @@ def _prepare_invoice(self): invoice_type = orig_invoice.move_type journal_type = "sale" partner = self.customer_id + original_invoice_date = orig_invoice.invoice_date + last_invoices = self.env["account.move"].search( + [ + ("move_type", "=", invoice_type), + ("company_id", "=", company.id), + ("invoice_date", ">", original_invoice_date), + ("name", "!=", False), + ], + order="invoice_date desc", + ) + if not last_invoices: + invoice_date = original_invoice_date + else: + invoice_date = last_invoices[0].invoice_date elif self.subcontractor_type == "external": invoice_type = ( orig_invoice.move_type == "out_invoice" and "in_invoice" or "in_refund" ) journal_type = "purchase" partner = self.employee_id._get_employee_invoice_partner() + invoice_date = fields.Date.today() if invoice_type in ["out_invoice", "out_refund"]: user = self.env["res.users"].search( [("company_id", "=", company.id)], limit=1 @@ -292,20 +307,6 @@ def _prepare_invoice(self): invoice_vals = self.env["account.move"].play_onchanges( invoice_vals, ["partner_id"] ) - original_invoice_date = orig_invoice.invoice_date - last_invoices = self.env["account.move"].search( - [ - ("move_type", "=", invoice_type), - ("company_id", "=", company.id), - ("invoice_date", ">", original_invoice_date), - ("name", "!=", False), - ], - order="invoice_date desc", - ) - if not last_invoices: - invoice_date = original_invoice_date - else: - invoice_date = last_invoices[0].invoice_date invoice_vals.update( { "invoice_date": invoice_date, From 6ad332a695b70d99189fdb60df56967ccc70796b Mon Sep 17 00:00:00 2001 From: Florian da Costa Date: Tue, 26 Mar 2024 21:50:36 +0100 Subject: [PATCH 3/4] [IMP] Prevent validating a prepaid supplier invoice if the custom account does not contain enough money --- .../models/account_move.py | 5 ++++- .../tests/test_invoicing.py | 14 ++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/project_invoicing_subcontractor/models/account_move.py b/project_invoicing_subcontractor/models/account_move.py index b19b625..ddddf30 100644 --- a/project_invoicing_subcontractor/models/account_move.py +++ b/project_invoicing_subcontractor/models/account_move.py @@ -518,9 +518,12 @@ def _check_invoice_mode_validity(self): ) def _post(self, soft=True): - res = super()._post(soft=soft) for move in self: + if move.subcontractor_state_color == "danger": + raise exceptions.UserError(move.subcontractor_state_message) move._check_invoice_mode_validity() + res = super()._post(soft=soft) + for move in self: if move.is_supplier_prepaid: move._manage_prepaid_lines() move.compute_enought_analytic_amount(partner_id=move.customer_id.id) diff --git a/project_invoicing_subcontractor/tests/test_invoicing.py b/project_invoicing_subcontractor/tests/test_invoicing.py index 190f623..cdba2cb 100644 --- a/project_invoicing_subcontractor/tests/test_invoicing.py +++ b/project_invoicing_subcontractor/tests/test_invoicing.py @@ -216,12 +216,8 @@ def test_prepaid_invoicing_process_same_project(self): self.assertTrue(demo_invoice.to_pay) # set admin invoice one day later to be sure demo invoice has priority - admin_invoice.write({"invoice_date": date.today() + timedelta(days=1)}) - admin_invoice.action_post() - self.env["account.move"].compute_enought_analytic_amount() - self.assertFalse(admin_invoice.to_pay) - self.assertTrue(demo_invoice.to_pay) - + # Add customer invoice so there is enough amount to validate the admin invoice + # but it is not paid customer_invoice2 = self._create_prepaid_customer_invoice( 1.99, self.line_5_2.project_id.analytic_account_id ) @@ -230,6 +226,12 @@ def test_prepaid_invoicing_process_same_project(self): 0.01, self.line_5_2.project_id.analytic_account_id ) customer_invoice3.action_post() + admin_invoice.write({"invoice_date": date.today() + timedelta(days=1)}) + admin_invoice.action_post() + self.env["account.move"].compute_enought_analytic_amount() + self.assertFalse(admin_invoice.to_pay) + self.assertTrue(demo_invoice.to_pay) + self.env["account.payment.register"].with_context( active_ids=customer_invoice2.ids, active_model="account.move" ).create({})._create_payments() From 2c5ec7e520a9b66b7600945bfeca90008eaea762 Mon Sep 17 00:00:00 2001 From: Florian da Costa Date: Wed, 27 Mar 2024 11:49:27 +0100 Subject: [PATCH 4/4] [IMP] Remove invoice date when creating a supplier invoice from subcontractor work. This way, this has to be filled at validation which is good since it should match the date of the supplier s document --- account_invoice_subcontractor/models/subcontractor_work.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/account_invoice_subcontractor/models/subcontractor_work.py b/account_invoice_subcontractor/models/subcontractor_work.py index 657ebbf..f319c7a 100644 --- a/account_invoice_subcontractor/models/subcontractor_work.py +++ b/account_invoice_subcontractor/models/subcontractor_work.py @@ -287,7 +287,7 @@ def _prepare_invoice(self): ) journal_type = "purchase" partner = self.employee_id._get_employee_invoice_partner() - invoice_date = fields.Date.today() + invoice_date = False if invoice_type in ["out_invoice", "out_refund"]: user = self.env["res.users"].search( [("company_id", "=", company.id)], limit=1