diff --git a/account_invoice_subcontractor/__manifest__.py b/account_invoice_subcontractor/__manifest__.py index 84751b1..d21626e 100644 --- a/account_invoice_subcontractor/__manifest__.py +++ b/account_invoice_subcontractor/__manifest__.py @@ -16,6 +16,7 @@ ], "data": [ "data/cron_data.xml", + "data/mail_data.xml", "security/security.xml", "security/ir.model.access.csv", "views/hr_employee_view.xml", diff --git a/account_invoice_subcontractor/data/mail_data.xml b/account_invoice_subcontractor/data/mail_data.xml new file mode 100644 index 0000000..5b20e94 --- /dev/null +++ b/account_invoice_subcontractor/data/mail_data.xml @@ -0,0 +1,25 @@ + + + + + External subcontractor invoice template + {{ (object.user_id.email or '') }} + Nouvelle facture sous traitance Akretion + {{ object.partner_id.id }} + + + {{ object.partner_id.lang }} + + + + + diff --git a/account_invoice_subcontractor/models/account_move.py b/account_invoice_subcontractor/models/account_move.py index 6623df8..41a6248 100644 --- a/account_invoice_subcontractor/models/account_move.py +++ b/account_invoice_subcontractor/models/account_move.py @@ -36,6 +36,7 @@ class AccountMove(models.Model): readonly=True, prefetch=False, ) + subcontractor_sent = fields.Boolean() @api.depends( "invoice_line_ids", diff --git a/account_invoice_subcontractor/models/hr_employee.py b/account_invoice_subcontractor/models/hr_employee.py index b7cfece..2ac3e41 100644 --- a/account_invoice_subcontractor/models/hr_employee.py +++ b/account_invoice_subcontractor/models/hr_employee.py @@ -24,6 +24,7 @@ def _get_subcontractor_type(self): required=True, default="internal", ) + auto_generate_invoice = fields.Boolean(string="Création facture automatique") def _get_employee_invoice_partner(self): self.ensure_one() diff --git a/account_invoice_subcontractor/models/subcontractor_work.py b/account_invoice_subcontractor/models/subcontractor_work.py index 0ae81b4..e5e0a38 100644 --- a/account_invoice_subcontractor/models/subcontractor_work.py +++ b/account_invoice_subcontractor/models/subcontractor_work.py @@ -331,7 +331,9 @@ def _prepare_invoice_line(self, invoice): def _get_subcontractor_invoicing_group(self): groups = OrderedDict() for sub in self.sorted("invoice_date"): - if sub.subcontractor_type == "internal": + if sub.subcontractor_type == "internal" or self.env.context.get( + "invoice_create_cron" + ): key = (sub.employee_id.id, sub.invoice_id.id) elif sub.subcontractor_type == "external": key = (sub.employee_id.id, False) @@ -383,11 +385,19 @@ def invoice_from_work(self): def _scheduler_action_subcontractor_invoice_create(self, days=7): date_filter = date.today() - timedelta(days=days) + # The order is used to start cron by external subcontractor because the user + # and company changes for internal subcontractors subcontractors = self.env["hr.employee"].search( [ + "|", + "&", ("subcontractor_type", "=", "internal"), ("subcontractor_company_id", "!=", False), - ] + "&", + ("subcontractor_type", "=", "external"), + ("auto_generate_invoice", "=", True), + ], + order="subcontractor_type", ) # Need to search on all subcontractor work # because of the filter on date invoice @@ -395,29 +405,53 @@ def _scheduler_action_subcontractor_invoice_create(self, days=7): [ ("invoice_id.invoice_date", "<=", date_filter), ("subcontractor_invoice_line_id", "=", False), + "|", ("subcontractor_type", "=", "internal"), + "&", + ("subcontractor_type", "=", "external"), + ("employee_id.auto_generate_invoice", "=", True), ("state", "in", ["posted", "paid"]), ], ) + template = self.env.ref( + "account_invoice_subcontractor.external_subcontractor_invoice_email_template" + ) + # Send validation email to old draft external subcontractor invoices + invoices = self.env["account.move"].search( + [ + ("subcontractor_sent", "=", False), + ("partner_id", "in", subcontractors.user_id.partner_id.ids), + ("state", "=", "draft"), + ("create_date", "<=", date_filter), + ] + ) + for draft_invoice in invoices: + template.send_mail(draft_invoice.id) + draft_invoice.subcontractor_sent = True for subcontractor in subcontractors: - dest_company = subcontractor.subcontractor_company_id - user = subcontractor.user_id - subcontractor_works = ( - self.with_user(user) - .with_company(dest_company) - .search( - [ - ("id", "in", all_works.ids), - ("employee_id", "=", subcontractor.id), - ], - ) + if subcontractor.subcontractor_type == "internal": + dest_company = subcontractor.subcontractor_company_id + user = subcontractor.user_id + self = self.with_user(user).with_company(dest_company) + else: + # Used to group by invoice also for external in case of the cron + self = self.with_context(invoice_create_cron=True) + subcontractor_works = self.search( + [ + ("id", "in", all_works.ids), + ("employee_id", "=", subcontractor.id), + ], ) sub_ids = subcontractor_works.ids sub_name = subcontractor.name _logger.info(f"{sub_ids} lines found for subcontractor {sub_name}") invoices = subcontractor_works.invoice_from_work() for invoice in invoices: - invoice.action_post() + if subcontractor.subcontractor_type == "internal": + invoice.action_post() + else: + template.send_mail(invoice.id) + invoice.subcontractor_sent = True # if old_company: # user.company_id = old_company.id return True diff --git a/account_invoice_subcontractor/views/hr_employee_view.xml b/account_invoice_subcontractor/views/hr_employee_view.xml index b2c7153..54b5501 100644 --- a/account_invoice_subcontractor/views/hr_employee_view.xml +++ b/account_invoice_subcontractor/views/hr_employee_view.xml @@ -14,6 +14,10 @@ name="subcontractor_company_id" attrs="{'required': [('subcontractor_type', '=', 'internal'), ('active', '=', True)], 'invisible': [('subcontractor_type','!=', 'internal')]}" /> +