|
| 1 | +# Copyright 2024 Ecosoft (<https://ecosoft.co.th>) |
| 2 | +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). |
| 3 | + |
| 4 | +from odoo import _, api, fields, models |
| 5 | +from odoo.exceptions import UserError |
| 6 | + |
| 7 | + |
| 8 | +class SaleOrderLine(models.Model): |
| 9 | + _inherit = "sale.order.line" |
| 10 | + |
| 11 | + spread_id = fields.Many2one("account.spread", string="Spread Board", copy=False) |
| 12 | + spread_check = fields.Selection( |
| 13 | + [ |
| 14 | + ("linked", "Linked"), |
| 15 | + ("unlinked", "Unlinked"), |
| 16 | + ("unavailable", "Unavailable"), |
| 17 | + ], |
| 18 | + compute="_compute_spread_check", |
| 19 | + ) |
| 20 | + |
| 21 | + @api.depends("spread_id", "order_id.state") |
| 22 | + def _compute_spread_check(self): |
| 23 | + for line in self: |
| 24 | + if line.spread_id: |
| 25 | + line.spread_check = "linked" |
| 26 | + elif line.order_id.state == "draft": |
| 27 | + line.spread_check = "unlinked" |
| 28 | + else: |
| 29 | + line.spread_check = "unavailable" |
| 30 | + |
| 31 | + def spread_details(self): |
| 32 | + """Button on the sale lines tree view of the sales order |
| 33 | + form to show the spread form view.""" |
| 34 | + if not self: |
| 35 | + # In case the widget clicked before the creation of the line |
| 36 | + return |
| 37 | + |
| 38 | + if self.spread_id: |
| 39 | + return { |
| 40 | + "name": _("Spread Details"), |
| 41 | + "view_mode": "form", |
| 42 | + "res_model": "account.spread", |
| 43 | + "type": "ir.actions.act_window", |
| 44 | + "target": "current", |
| 45 | + "readonly": False, |
| 46 | + "res_id": self.spread_id.id, |
| 47 | + } |
| 48 | + |
| 49 | + # In case no spread board is linked to the sale line |
| 50 | + # open the wizard to link them |
| 51 | + ctx = dict( |
| 52 | + self.env.context, |
| 53 | + default_sale_line_id=self.id, |
| 54 | + default_company_id=self.order_id.company_id.id, |
| 55 | + allow_spread_planning=self.order_id.company_id.allow_spread_planning, |
| 56 | + ) |
| 57 | + return { |
| 58 | + "name": _("Link Sales Line with Spread Board"), |
| 59 | + "view_mode": "form", |
| 60 | + "res_model": "account.spread.sale.line.link.wizard", |
| 61 | + "type": "ir.actions.act_window", |
| 62 | + "target": "new", |
| 63 | + "context": ctx, |
| 64 | + } |
| 65 | + |
| 66 | + def create_auto_spread(self): |
| 67 | + """Create auto spread table for each sale line, when needed""" |
| 68 | + |
| 69 | + def _filter_line(aline, sline): |
| 70 | + """Find matching template auto line with sale line""" |
| 71 | + if aline.product_id and sline.product_id != aline.product_id: |
| 72 | + return False |
| 73 | + return True |
| 74 | + |
| 75 | + # Skip create new template when create move on spread lines |
| 76 | + if self.env.context.get("skip_create_template"): |
| 77 | + return |
| 78 | + |
| 79 | + for line in self: |
| 80 | + if line.spread_check == "linked": |
| 81 | + continue |
| 82 | + spread_type = "sale" |
| 83 | + spread_auto = self.env["account.spread.template.auto"].search( |
| 84 | + [ |
| 85 | + ("template_id.auto_spread", "=", True), |
| 86 | + ("template_id.spread_type", "=", spread_type), |
| 87 | + ] |
| 88 | + ) |
| 89 | + matched = spread_auto.filtered(lambda a, s=line: _filter_line(a, s)) |
| 90 | + template = matched.mapped("template_id") |
| 91 | + if not template: |
| 92 | + continue |
| 93 | + elif len(template) > 1: |
| 94 | + raise UserError( |
| 95 | + _( |
| 96 | + "Too many auto spread templates (%(len_template)s) matched with the " |
| 97 | + "sale line, %(line_name)s" |
| 98 | + ) |
| 99 | + % {"len_template": len(template), "line_name": line.display_name} |
| 100 | + ) |
| 101 | + # Found auto spread template for this invoice line, create it |
| 102 | + wizard = self.env["account.spread.sale.line.link.wizard"].new( |
| 103 | + { |
| 104 | + "sale_line_id": line.id, |
| 105 | + "company_id": line.company_id.id, |
| 106 | + "spread_action_type": "template", |
| 107 | + "template_id": template.id, |
| 108 | + } |
| 109 | + ) |
| 110 | + wizard.confirm() |
| 111 | + |
| 112 | + def _prepare_invoice_line(self, **optional_values): |
| 113 | + res = super()._prepare_invoice_line(**optional_values) |
| 114 | + # Creating invoice from sales order, ensure same spread account |
| 115 | + if self.spread_id: |
| 116 | + res["spread_id"] = self.spread_id.id |
| 117 | + res["account_id"] = self.spread_id.debit_account_id.id |
| 118 | + return res |
0 commit comments