diff --git a/subscription_oca/models/sale_subscription.py b/subscription_oca/models/sale_subscription.py index 250f97a006..b24eacb9d2 100644 --- a/subscription_oca/models/sale_subscription.py +++ b/subscription_oca/models/sale_subscription.py @@ -45,6 +45,9 @@ class SaleSubscription(models.Model): required=True, string="Subscription template", ) + template_invoicing_mode = fields.Selection( + related="template_id.invoicing_mode", readonly=True + ) code = fields.Char( string="Reference", default=lambda self: self.env["ir.sequence"].next_by_code("sale.subscription"), @@ -321,35 +324,53 @@ def generate_invoice(self): if self.template_id.invoicing_mode != "draft": invoice.action_post() if self.template_id.invoicing_mode == "invoice_send": - mail_template = self.template_id.invoice_mail_template_id - invoice.with_context(force_send=True).message_post_with_template( - mail_template.id, - composition_mode="comment", - email_layout_xmlid="mail.mail_notification_paynow", - ) + self.send_invoice(invoice) invoice_number = invoice.name message_body = ( "%s %s" % (msg_static, invoice.id, invoice_number) ) - if self.template_id.invoicing_mode == "sale_and_invoice": + elif self.template_id.invoicing_mode in ["sale_draft"]: + self.create_sale_order() + + elif self.template_id.invoicing_mode in ["sale_confirmed"]: + order_id = self.create_sale_order() + order_id.action_confirm() + + elif self.template_id.invoicing_mode in [ + "sale_and_invoice", + "sale_and_invoice_draft", + "sale_and_invoice_send", + ]: order_id = self.create_sale_order() order_id.action_done() new_invoice = order_id._create_invoices() - new_invoice.action_post() + self.write({"invoice_ids": [(4, new_invoice.id)]}) + if self.template_id.invoicing_mode == "sale_and_invoice": + new_invoice.action_post() new_invoice.invoice_origin = order_id.name + ", " + self.name invoice_number = new_invoice.name message_body = ( "%s %s" % (msg_static, new_invoice.id, invoice_number) ) + if self.template_id.invoicing_mode == "sale_and_invoice_send": + self.send_invoice(new_invoice) if not invoice_number: invoice_number = _("To validate") message_body = "%s %s" % (msg_static, invoice_number) self.calculate_recurring_next_date(self.recurring_next_date) self.message_post(body=message_body) + def send_invoice(self, invoice): + mail_template = self.template_id.invoice_mail_template_id + invoice.with_context(force_send=True).message_post_with_template( + mail_template.id, + composition_mode="comment", + email_layout_xmlid="mail.mail_notification_paynow", + ) + def manual_invoice(self): invoice_id = self.create_invoice() self.calculate_recurring_next_date(self.recurring_next_date) @@ -369,6 +390,43 @@ def manual_invoice(self): "context": context, } + def manual_sale_order(self): + order = self.create_sale_order() + msg_static = _("Created Sale Order with reference") + message_body = ( + "%s %s" + % (msg_static, order.id, order.name) + ) + self.message_post(body=message_body) + return { + "name": self.name, + "view_type": "form", + "view_mode": "form", + "res_model": "sale.order", + "res_id": order.id, + "type": "ir.actions.act_window", + } + + def manual_invoice_and_sale_order(self): + order_id = self.manual_sale_order()["res_id"] + order = self.env["sale.order"].browse(order_id) + order.action_done() + new_invoice = order._create_invoices() + if self.template_invoicing_mode in [ + "sale_and_invoice", + "sale_and_invoice_send", + ]: + new_invoice.action_post() + new_invoice.invoice_origin = order.name + ", " + self.name + invoice_number = new_invoice.name + msg_static = _("Created invoice with reference") + message_body = ( + "%s %s" + % (msg_static, new_invoice.id, invoice_number) + ) + self.message_post(body=message_body) + return order, new_invoice + @api.depends("invoice_ids", "sale_order_ids.invoice_ids") def _compute_account_invoice_ids_count(self): for record in self: diff --git a/subscription_oca/models/sale_subscription_template.py b/subscription_oca/models/sale_subscription_template.py index df89f401b0..b69d5e1c30 100644 --- a/subscription_oca/models/sale_subscription_template.py +++ b/subscription_oca/models/sale_subscription_template.py @@ -34,7 +34,11 @@ class SaleSubscriptionTemplate(models.Model): ("draft", "Draft"), ("invoice", "Invoice"), ("invoice_send", "Invoice & send"), - ("sale_and_invoice", "Sale order & Invoice"), + ("sale_and_invoice", "Sale Order & Invoice"), + ("sale_and_invoice_draft", "Sale Order & Invoice Draft"), + ("sale_and_invoice_send", "Sale Order & Invoice send"), + ("sale_draft", "Sale Order Draft"), + ("sale_confirmed", "Sale Order Confirmed"), ], ) code = fields.Char() diff --git a/subscription_oca/tests/test_subscription_oca.py b/subscription_oca/tests/test_subscription_oca.py index d16708e3bc..af577b09b6 100644 --- a/subscription_oca/tests/test_subscription_oca.py +++ b/subscription_oca/tests/test_subscription_oca.py @@ -65,6 +65,9 @@ def setUpClass(cls): cls.product_1.taxes_id = [(6, 0, cls.tax_10pc_incl.ids)] cls.product_2 = cls.env.ref("product.product_product_2") cls.product_2.subscribable = True + cls.product_3 = cls.env.ref("product.product_product_3") + cls.product_3.subscribable = True + cls.product_3.invoice_policy = "order" cls.country = cls.env["res.country"].search([], limit=1) cls.fiscal = cls.env["account.fiscal.position"].create( @@ -104,6 +107,27 @@ def setUpClass(cls): "recurring_rule_type": "days", } ) + cls.tmpl_sale_draft = cls.create_sub_template( + { + "recurring_rule_boundary": "unlimited", + "invoicing_mode": "sale_draft", + "recurring_rule_type": "days", + } + ) + cls.tmpl_sale_confirmed = cls.create_sub_template( + { + "recurring_rule_boundary": "unlimited", + "invoicing_mode": "sale_confirmed", + "recurring_rule_type": "days", + } + ) + cls.tmpl_sale_and_invoice_send = cls.create_sub_template( + { + "recurring_rule_boundary": "unlimited", + "invoicing_mode": "sale_and_invoice_send", + "recurring_rule_type": "days", + } + ) cls.stage = cls.env["sale.subscription.stage"].create( { @@ -173,6 +197,36 @@ def setUpClass(cls): "journal_id": cls.cash_journal.id, } ) + cls.sub_sale_draft = cls.create_sub( + { + "template_id": cls.tmpl_sale_draft.id, + "pricelist_id": cls.pricelist2.id, + "date_start": fields.Date.today() - relativedelta(days=100), + "recurring_next_date": fields.Date.today(), + "in_progress": True, + "journal_id": cls.sale_journal.id, + } + ) + cls.sub_sale_confirmed = cls.create_sub( + { + "template_id": cls.tmpl_sale_confirmed.id, + "pricelist_id": cls.pricelist2.id, + "date_start": fields.Date.today() - relativedelta(days=100), + "recurring_next_date": fields.Date.today(), + "in_progress": True, + "journal_id": cls.sale_journal.id, + } + ) + cls.sub_sale_and_invoice_send = cls.create_sub( + { + "template_id": cls.tmpl_sale_and_invoice_send.id, + "pricelist_id": cls.pricelist2.id, + "date_start": fields.Date.today() - relativedelta(days=100), + "recurring_next_date": fields.Date.today(), + "in_progress": True, + "journal_id": cls.sale_journal.id, + } + ) cls.sub_line = cls.create_sub_line(cls.sub1) cls.sub_line2 = cls.env["sale.subscription.line"].create( @@ -191,6 +245,11 @@ def setUpClass(cls): cls.sub_line52 = cls.create_sub_line(cls.sub5, cls.product_2.id) cls.sub_line71 = cls.create_sub_line(cls.sub7) cls.sub_line72 = cls.create_sub_line(cls.sub7, cls.product_2.id) + cls.sub_line_sd = cls.create_sub_line(cls.sub_sale_draft, cls.product_3.id) + cls.sub_line_sc = cls.create_sub_line(cls.sub_sale_confirmed, cls.product_3.id) + cls.sub_line_sais = cls.create_sub_line( + cls.sub_sale_and_invoice_send, cls.product_3.id + ) cls.close_reason = cls.env["sale.subscription.close.reason"].create( { @@ -503,13 +562,35 @@ def test_subscription_oca_sub8_workflow_portal(self): with self.assertRaises(exceptions.AccessError): subscription.partner_id = self.partner_2 + def test_subscription_oca_sub_sale_draft_workflow(self): + res = self._collect_all_sub_test_results(self.sub_sale_draft) + self.assertEqual(res[4], 900.0) + self.sub_sale_draft.manual_sale_order() + self.sub_sale_draft.manual_invoice_and_sale_order() + + def test_subscription_oca_sub_sale_confirmed_workflow(self): + res = self._collect_all_sub_test_results(self.sub_sale_confirmed) + self.assertEqual(res[4], 900.0) + self.sub_sale_confirmed.manual_sale_order() + self.sub_sale_confirmed.manual_invoice_and_sale_order() + + def test_subscription_oca_sub_sale_and_invoice_send_workflow(self): + res = self._collect_all_sub_test_results(self.sub_sale_and_invoice_send) + self.assertEqual(res[4], 900.0) + self.sub_sale_and_invoice_send.manual_sale_order() + self.sub_sale_and_invoice_send.manual_invoice_and_sale_order() + + def test_subscription_oca_sub_sale_and_invoice_send_workflow_2(self): + self.sub_sale_and_invoice_send.generate_invoice() + self.assertEqual(len(self.sub_sale_and_invoice_send.invoice_ids), 1) + def test_subscription_oca_sub_stage(self): # sale.subscription.stage self.stage._check_lot_product() # should not raise def test_x_subscription_oca_pricelist_related(self): res = self.partner.read(["subscription_count", "subscription_ids"]) - self.assertEqual(res[0]["subscription_count"], 8) + self.assertEqual(res[0]["subscription_count"], 11) res = self.partner.action_view_subscription_ids() self.assertIsInstance(res, dict) sale_order = self.sub1.create_sale_order() diff --git a/subscription_oca/views/sale_subscription_template_views.xml b/subscription_oca/views/sale_subscription_template_views.xml index d683c55b7b..d353842fbc 100644 --- a/subscription_oca/views/sale_subscription_template_views.xml +++ b/subscription_oca/views/sale_subscription_template_views.xml @@ -82,7 +82,8 @@ diff --git a/subscription_oca/views/sale_subscription_views.xml b/subscription_oca/views/sale_subscription_views.xml index 4279143483..0fe774e8c4 100644 --- a/subscription_oca/views/sale_subscription_views.xml +++ b/subscription_oca/views/sale_subscription_views.xml @@ -12,6 +12,23 @@ name="manual_invoice" type="object" class="btn-primary" + attrs="{'invisible': [('template_invoicing_mode', 'not in', ['draft','invoice','invoice_send'])]}" + /> + +