From bc3a7c373a479ee1662d3c2ab19bd7973b0b1ad2 Mon Sep 17 00:00:00 2001 From: "Aung Ko Ko Lin (Quartile)" <45355704+AungKoKoLin1997@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:19:16 +0700 Subject: [PATCH] [4157][ADD] purchase_budget_line (#89) [4157][ADD] purchase_budget_line#89 --- purchase_budget_line/README.rst | 58 +++ purchase_budget_line/__init__.py | 1 + purchase_budget_line/__manifest__.py | 18 + purchase_budget_line/i18n/ja.po | 331 ++++++++++++++ purchase_budget_line/models/__init__.py | 4 + purchase_budget_line/models/budget_code.py | 77 ++++ .../models/purchase_budget_line.py | 58 +++ purchase_budget_line/models/purchase_order.py | 30 ++ .../models/purchase_order_line.py | 59 +++ purchase_budget_line/readme/DESCRIPTION.md | 3 + .../security/ir.model.access.csv | 6 + .../static/description/index.html | 412 ++++++++++++++++++ .../views/budget_code_views.xml | 96 ++++ .../views/purchase_budget_line_views.xml | 124 ++++++ .../views/purchase_order_views.xml | 88 ++++ .../odoo/addons/purchase_budget_line | 1 + setup/purchase_budget_line/setup.py | 6 + 17 files changed, 1372 insertions(+) create mode 100644 purchase_budget_line/README.rst create mode 100644 purchase_budget_line/__init__.py create mode 100644 purchase_budget_line/__manifest__.py create mode 100644 purchase_budget_line/i18n/ja.po create mode 100644 purchase_budget_line/models/__init__.py create mode 100644 purchase_budget_line/models/budget_code.py create mode 100644 purchase_budget_line/models/purchase_budget_line.py create mode 100644 purchase_budget_line/models/purchase_order.py create mode 100644 purchase_budget_line/models/purchase_order_line.py create mode 100644 purchase_budget_line/readme/DESCRIPTION.md create mode 100644 purchase_budget_line/security/ir.model.access.csv create mode 100644 purchase_budget_line/static/description/index.html create mode 100644 purchase_budget_line/views/budget_code_views.xml create mode 100644 purchase_budget_line/views/purchase_budget_line_views.xml create mode 100644 purchase_budget_line/views/purchase_order_views.xml create mode 120000 setup/purchase_budget_line/odoo/addons/purchase_budget_line create mode 100644 setup/purchase_budget_line/setup.py diff --git a/purchase_budget_line/README.rst b/purchase_budget_line/README.rst new file mode 100644 index 00000000..0dd9e7d7 --- /dev/null +++ b/purchase_budget_line/README.rst @@ -0,0 +1,58 @@ +==================== +Purchase Budget Line +==================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:2545788a9ec264d3c5b22d08b893b510774d4d4e598fdfcf5ea8f09e387b0049 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-qrtl%2Faxls--custom-lightgray.png?logo=github + :target: https://github.com/qrtl/axls-custom/tree/16.0/purchase_budget_line + :alt: qrtl/axls-custom + +|badge1| |badge2| |badge3| + +This module adds the purchase budget line model whose records are linked +to the purchase order line with one2many relationship (multiple budget +lines per order line). It aims to help manage the CBS information +effectively. + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Quartile Limited + +Maintainers +----------- + +This module is part of the `qrtl/axls-custom `_ project on GitHub. + +You are welcome to contribute. diff --git a/purchase_budget_line/__init__.py b/purchase_budget_line/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/purchase_budget_line/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/purchase_budget_line/__manifest__.py b/purchase_budget_line/__manifest__.py new file mode 100644 index 00000000..9c0830d0 --- /dev/null +++ b/purchase_budget_line/__manifest__.py @@ -0,0 +1,18 @@ +# Copyright 2024 Quartile (https://www.quartile.co) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +{ + "name": "Purchase Budget Line", + "version": "16.0.1.0.0", + "author": "Quartile Limited", + "website": "https://www.quartile.co", + "category": "Purchase", + "license": "AGPL-3", + "depends": ["purchase"], + "data": [ + "security/ir.model.access.csv", + "views/budget_code_views.xml", + "views/purchase_budget_line_views.xml", + "views/purchase_order_views.xml", + ], + "installable": True, +} diff --git a/purchase_budget_line/i18n/ja.po b/purchase_budget_line/i18n/ja.po new file mode 100644 index 00000000..1435e850 --- /dev/null +++ b/purchase_budget_line/i18n/ja.po @@ -0,0 +1,331 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_budget_line +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-08-16 05:42+0000\n" +"PO-Revision-Date: 2024-08-16 05:42+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_order_line_budget_line_form +msgid " / " +msgstr "" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__active +msgid "Active" +msgstr "有効" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__analytic_account_id +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_budget_code_search +msgid "Analytic Account" +msgstr "分析勘定" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_budget_code_form +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_budget_code_search +msgid "Archived" +msgstr "アーカイブ済" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__invoice_ids +msgid "Bills" +msgstr "請求書" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__budget_code_id +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_order__budget_code_ids +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_order_line__budget_code_ids +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_budget_code_search +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "Budget Code" +msgstr "予算コード" + +#. module: purchase_budget_line +#: model:ir.actions.act_window,name:purchase_budget_line.action_budget_code +#: model:ir.ui.menu,name:purchase_budget_line.budget_code_menu +msgid "Budget Codes" +msgstr "予算コード" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_order_line__budget_line_ids +msgid "Budget Line" +msgstr "予算明細" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_order__budget_qty_inconsistency_warning +msgid "Budget Qty Inconsistency Warning" +msgstr "予算数量不整合警告" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_order_line__budget_qty +msgid "Budget Quantity" +msgstr "予算数量" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__budget_price_unit +msgid "Budget Unit Price" +msgstr "予算単価" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "Cancelled" +msgstr "取消済" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__child_ids +msgid "Child Budget Codes" +msgstr "子予算コード" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__code +msgid "Code" +msgstr "コード" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__complete_code +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_budget_code_search +msgid "Complete Code" +msgstr "完全コード" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__complete_name_en +msgid "Complete Name En" +msgstr "完全名称(英)" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__complete_name_ja +msgid "Complete Name Ja" +msgstr "完全名称(日)" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__create_uid +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__create_uid +msgid "Created by" +msgstr "作成者" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__create_date +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__create_date +msgid "Created on" +msgstr "作成日" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__currency_id +msgid "Currency" +msgstr "通貨" + +#. module: purchase_budget_line +#: model:ir.model.fields,help:purchase_budget_line.field_purchase_budget_line__date_planned +msgid "" +"Delivery date expected from vendor. This date respectively defaults to " +"vendor pricelist lead time then today's date." +msgstr "" + +#. module: purchase_budget_line +#: model:ir.model.fields,help:purchase_budget_line.field_purchase_budget_line__date_order +msgid "" +"Depicts the date within which the Quotation should be confirmed and " +"converted into a purchase order." +msgstr "" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__display_name +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__display_name +msgid "Display Name" +msgstr "表示名" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__date_planned +msgid "Expected Arrival" +msgstr "入荷予定日" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_budget_code_search +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "Group By" +msgstr "グループ化" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__id +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__id +msgid "ID" +msgstr "" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code____last_update +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line____last_update +msgid "Last Modified on" +msgstr "最終変更日" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__write_uid +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__write_uid +msgid "Last Updated by" +msgstr "最終更新者" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__write_date +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__write_date +msgid "Last Updated on" +msgstr "最終更新日" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "Locked" +msgstr "ロック済" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__name +msgid "Name" +msgstr "名称" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "Order" +msgstr "オーダ" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__date_order +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "Order Date" +msgstr "オーダ日" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__order_line_id +msgid "Order Line" +msgstr "オーダ明細" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__order_id +msgid "Order Reference" +msgstr "オーダ参照" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__order_state +msgid "Order Status" +msgstr "オーダ状態" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_budget_code__parent_id +msgid "Parent" +msgstr "親" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__partner_id +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "Partner" +msgstr "取引先" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "Planned Date" +msgstr "入荷予定日" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__product_id +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "Product" +msgstr "プロダクト" + +#. module: purchase_budget_line +#: model:ir.model,name:purchase_budget_line.model_purchase_budget_line +msgid "Purchase Budget Line" +msgstr "購買予算明細" + +#. module: purchase_budget_line +#. odoo-python +#: code:addons/purchase_budget_line/models/purchase_order_line.py:0 +#: model:ir.actions.act_window,name:purchase_budget_line.action_purchase_budget_line +#: model:ir.ui.menu,name:purchase_budget_line.purchase_budget_line_menu +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.purchase_order_form +#, python-format +msgid "Purchase Budget Lines" +msgstr "購買予算明細" + +#. module: purchase_budget_line +#: model:ir.model,name:purchase_budget_line.model_purchase_order +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "Purchase Order" +msgstr "購買オーダ" + +#. module: purchase_budget_line +#: model:ir.model,name:purchase_budget_line.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "購買オーダ明細" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__purchase_price_unit +msgid "Purchase Unit Price" +msgstr "購買単価" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__quantity +msgid "Quantity" +msgstr "数量" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_order_line__quick_encoding_budget_qty +msgid "Quick Encoding Budget Qty" +msgstr "" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "RFQ" +msgstr "見積依頼" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "RFQ Sent" +msgstr "見積依頼送付済" + +#. module: purchase_budget_line +#. odoo-python +#: code:addons/purchase_budget_line/models/purchase_order.py:0 +#, python-format +msgid "" +"There is a line with inconsistent quantities between order and budget:\n" +"%s" +msgstr "" +"オーダと予算で数量が不一致の明細があります:\n" +"%s" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_budget_line_search +msgid "To Approve" +msgstr "未承認" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__price_total +msgid "Total" +msgstr "合計" + +#. module: purchase_budget_line +#: model:ir.model.fields,field_description:purchase_budget_line.field_purchase_budget_line__uom_id +msgid "Unit of Measure" +msgstr "計数単位" + +#. module: purchase_budget_line +#: model_terms:ir.ui.view,arch_db:purchase_budget_line.view_purchase_order_line_budget_line_form +msgid "UoM" +msgstr "単位" + +#. module: purchase_budget_line +#: model:ir.model.fields,help:purchase_budget_line.field_purchase_budget_line__partner_id +msgid "You can find a vendor by its Name, TIN, Email or Internal Reference." +msgstr "" + +#. module: purchase_budget_line +#: model:ir.model,name:purchase_budget_line.model_budget_code +msgid "budget.code" +msgstr "" diff --git a/purchase_budget_line/models/__init__.py b/purchase_budget_line/models/__init__.py new file mode 100644 index 00000000..6f2e715e --- /dev/null +++ b/purchase_budget_line/models/__init__.py @@ -0,0 +1,4 @@ +from . import budget_code +from . import purchase_budget_line +from . import purchase_order_line +from . import purchase_order diff --git a/purchase_budget_line/models/budget_code.py b/purchase_budget_line/models/budget_code.py new file mode 100644 index 00000000..db628e1c --- /dev/null +++ b/purchase_budget_line/models/budget_code.py @@ -0,0 +1,77 @@ +# Copyright 2024 Quartile (https://www.quartile.co) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class BudgetCode(models.Model): + _name = "budget.code" + _order = "complete_code" + _rec_names_search = ["complete_code", "complete_name_en", "complete_name_ja"] + + name = fields.Char(required=True, translate=True) + code = fields.Char(required=True) + parent_id = fields.Many2one("budget.code") + analytic_account_id = fields.Many2one("account.analytic.account") + complete_code = fields.Char( + compute="_compute_complete_code", + recursive=True, + store=True, + ) + complete_name_en = fields.Char( + compute="_compute_complete_name", + recursive=True, + store=True, + ) + complete_name_ja = fields.Char( + compute="_compute_complete_name", + recursive=True, + store=True, + ) + child_ids = fields.One2many( + string="Child Budget Codes", + comodel_name="budget.code", + inverse_name="parent_id", + copy=True, + ) + active = fields.Boolean(default=True) + + @api.depends("code", "parent_id.complete_code") + def _compute_complete_code(self): + for rec in self: + if rec.parent_id: + rec.complete_code = "%s%s" % (rec.parent_id.complete_code, rec.code) + else: + rec.complete_code = rec.code + + def _get_complete_name_field(self, lang=None): + self.ensure_one() + if not lang: + lang = self.env.context.get("lang", "en_US") + return "complete_name_en" if lang.startswith("en") else "complete_name_ja" + + @api.depends("name", "parent_id.complete_name_en", "parent_id.complete_name_ja") + def _compute_complete_name(self): + for lang in ["en_US", "ja_JP"]: + for rec in self.with_context(lang=lang): + # Record creation fails without this. + if isinstance(rec.id, models.NewId): + continue + complete_name_field = rec._get_complete_name_field() + if rec.parent_id: + complete_name_value = "%s-%s" % ( + getattr(rec.parent_id, complete_name_field), + rec.name, + ) + else: + complete_name_value = rec.name + setattr(rec, complete_name_field, complete_name_value) + + def name_get(self): + name_list = [] + for rec in self: + complete_name_field = rec._get_complete_name_field() + complete_name = getattr(rec, complete_name_field) + name = "[" + rec.complete_code + "] " + complete_name + name_list.append((rec.id, name)) + return name_list diff --git a/purchase_budget_line/models/purchase_budget_line.py b/purchase_budget_line/models/purchase_budget_line.py new file mode 100644 index 00000000..e6e7fc54 --- /dev/null +++ b/purchase_budget_line/models/purchase_budget_line.py @@ -0,0 +1,58 @@ +# Copyright 2024 Quartile (https://www.quartile.co) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class PurchaseBudgetLine(models.Model): + _name = "purchase.budget.line" + _description = "Purchase Budget Line" + + order_line_id = fields.Many2one( + "purchase.order.line", ondelete="cascade", required=True + ) + budget_code_id = fields.Many2one("budget.code", required=True) + product_id = fields.Many2one(related="order_line_id.product_id", store=True) + quantity = fields.Float() + uom_id = fields.Many2one(related="order_line_id.product_uom", store=True) + purchase_price_unit = fields.Float( + related="order_line_id.price_unit", + string="Purchase Unit Price", + digits="Product Price", + store=True, + ) + budget_price_unit = fields.Float(digits="Product Price", string="Budget Unit Price") + price_total = fields.Monetary( + compute="_compute_price_total", string="Total", store=True + ) + currency_id = fields.Many2one(related="order_line_id.currency_id", store=True) + partner_id = fields.Many2one(related="order_line_id.partner_id", store=True) + order_id = fields.Many2one(related="order_line_id.order_id", store=True) + date_order = fields.Datetime(related="order_line_id.date_order", store=True) + date_planned = fields.Datetime(related="order_line_id.date_planned", store=True) + order_state = fields.Selection( + related="order_line_id.state", + string="Order Status", + store=True, + ) + invoice_ids = fields.Many2many( + "account.move", compute="_compute_invoice_ids", string="Bills", store=True + ) + + @api.depends("quantity", "budget_price_unit") + def _compute_price_total(self): + for rec in self: + rec.price_total = rec.quantity * rec.budget_price_unit + + @api.depends("order_line_id.invoice_lines") + def _compute_invoice_line_ids(self): + for rec in self: + rec.invoice_line_ids = False + if rec.order_line_id.invoice_lines: + rec.invoice_line_ids = rec.order_line_id.invoice_lines + + @api.depends("order_line_id.invoice_lines.move_id") + def _compute_invoice_ids(self): + for rec in self: + invoices = rec.order_line_id.invoice_lines.move_id + rec.invoice_ids = invoices diff --git a/purchase_budget_line/models/purchase_order.py b/purchase_budget_line/models/purchase_order.py new file mode 100644 index 00000000..7730b4d8 --- /dev/null +++ b/purchase_budget_line/models/purchase_order.py @@ -0,0 +1,30 @@ +# Copyright 2024 Quartile (https://www.quartile.co) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models + + +class PurchaseOrder(models.Model): + _inherit = "purchase.order" + + budget_qty_inconsistency_warning = fields.Text( + compute="_compute_budget_qty_inconsistency_warning", + ) + budget_code_ids = fields.Many2many(related="order_line.budget_code_ids") + + @api.constrains("order_line.product_qty", "order_line.budget_qty") + def _compute_budget_qty_inconsistency_warning(self): + for order in self: + message = False + product_names = "" + for line in order.order_line: + if not line.budget_line_ids or line.budget_qty == line.product_qty: + continue + product_names += "\n" + line.product_id.display_name + if product_names: + message = _( + "There is a line with inconsistent quantities between order and " + "budget:\n%s", + product_names, + ) + order.budget_qty_inconsistency_warning = message diff --git a/purchase_budget_line/models/purchase_order_line.py b/purchase_budget_line/models/purchase_order_line.py new file mode 100644 index 00000000..67e63741 --- /dev/null +++ b/purchase_budget_line/models/purchase_order_line.py @@ -0,0 +1,59 @@ +# Copyright 2024 Quartile (https://www.quartile.co) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models + + +class PurchaseOrderLine(models.Model): + _inherit = "purchase.order.line" + + budget_line_ids = fields.One2many( + "purchase.budget.line", + "order_line_id", + copy=False, + ) + budget_qty = fields.Float( + string="Budget Quantity", + digits="Product Unit of Measure", + compute="_compute_budget_qty", + ) + budget_code_ids = fields.Many2many( + "budget.code", + compute="_compute_budget_code_ids", + store=True, + ) + quick_encoding_budget_qty = fields.Binary( + compute="_compute_quick_encoding_budget_qty", + exportable=False, + ) + + @api.depends("budget_line_ids.quantity") + def _compute_budget_qty(self): + for line in self: + line.budget_qty = sum(line.budget_line_ids.mapped("quantity")) + + @api.depends("budget_line_ids.budget_code_id") + def _compute_budget_code_ids(self): + for line in self: + line.budget_code_ids = line.budget_line_ids.budget_code_id + + @api.depends("product_qty", "budget_qty") + def _compute_quick_encoding_budget_qty(self): + for line in self: + line.quick_encoding_budget_qty = line.product_qty - line.budget_qty + + def action_show_budget_lines(self): + self.ensure_one() + view = self.env.ref( + "purchase_budget_line.view_purchase_order_line_budget_line_form" + ) + return { + "name": _("Purchase Budget Lines"), + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "purchase.order.line", + "views": [(view.id, "form")], + "view_id": view.id, + "target": "new", + "res_id": self.id, + } diff --git a/purchase_budget_line/readme/DESCRIPTION.md b/purchase_budget_line/readme/DESCRIPTION.md new file mode 100644 index 00000000..b1c28026 --- /dev/null +++ b/purchase_budget_line/readme/DESCRIPTION.md @@ -0,0 +1,3 @@ +This module adds the purchase budget line model whose records are linked to the purchase +order line with one2many relationship (multiple budget lines per order line). It aims +to help manage the CBS information effectively. diff --git a/purchase_budget_line/security/ir.model.access.csv b/purchase_budget_line/security/ir.model.access.csv new file mode 100644 index 00000000..e2463f45 --- /dev/null +++ b/purchase_budget_line/security/ir.model.access.csv @@ -0,0 +1,6 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_budget_code_user,budget.code.user,model_budget_code,base.group_user,1,0,0,0 +access_budget_code_account_user,budget.code.account.user,model_budget_code,account.group_account_user,1,1,1,1 +access_budget_code_analytic_accounting,budget.code.analytic.accounting,model_budget_code,analytic.group_analytic_accounting,1,1,1,1 +access_purchase_budget_line_user,purchase.budget.line.user,model_purchase_budget_line,base.group_user,1,0,0,0 +access_purchase_budget_line_purchase_user,purchase.budget.line.purchase.user,model_purchase_budget_line,purchase.group_purchase_user,1,1,1,1 diff --git a/purchase_budget_line/static/description/index.html b/purchase_budget_line/static/description/index.html new file mode 100644 index 00000000..c3059ccc --- /dev/null +++ b/purchase_budget_line/static/description/index.html @@ -0,0 +1,412 @@ + + + + + + +Purchase Budget Line + + + +
+

Purchase Budget Line

+ + +

Beta License: AGPL-3 qrtl/axls-custom

+

This module adds the purchase budget line model whose records are linked +to the purchase order line with one2many relationship (multiple budget +lines per order line). It aims to help manage the CBS information +effectively.

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Quartile Limited
  • +
+
+
+

Maintainers

+

This module is part of the qrtl/axls-custom project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/purchase_budget_line/views/budget_code_views.xml b/purchase_budget_line/views/budget_code_views.xml new file mode 100644 index 00000000..74ad191c --- /dev/null +++ b/purchase_budget_line/views/budget_code_views.xml @@ -0,0 +1,96 @@ + + + + budget.code.search + budget.code + + + + + + + + + + + + + + + budget.code.tree + budget.code + + + + + + + + + + + + + + budget.code.form + budget.code + +
+ + + +
+
+ + + + + + + + + + + + +
+ +
+
+ + Budget Codes + budget.code + tree,form + {} + + +
diff --git a/purchase_budget_line/views/purchase_budget_line_views.xml b/purchase_budget_line/views/purchase_budget_line_views.xml new file mode 100644 index 00000000..c838ff78 --- /dev/null +++ b/purchase_budget_line/views/purchase_budget_line_views.xml @@ -0,0 +1,124 @@ + + + + purchase.budget.line.search + purchase.budget.line + + + + + + + + + + + + + + + + + + + + + + + + + + + + + purchase.budget.line.tree + purchase.budget.line + + + + + + + + + + + + + + + + + + + + + Purchase Budget Lines + purchase.budget.line + tree + + {} + + + diff --git a/purchase_budget_line/views/purchase_order_views.xml b/purchase_budget_line/views/purchase_order_views.xml new file mode 100644 index 00000000..0f0a80d9 --- /dev/null +++ b/purchase_budget_line/views/purchase_order_views.xml @@ -0,0 +1,88 @@ + + + + request.quotation.select + purchase.order + + + + + + + + + purchase.order.select + purchase.order + + + + + + + + + purchase.order.form + purchase.order + + + + + + +