From 07095c73472de33cc75b2e41405e3f948c12c33c Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Wed, 12 Apr 2023 12:24:20 +0630 Subject: [PATCH 1/2] [ADD] vendor_bill_final_price_check --- .../odoo/addons/vendor_bill_final_price_check | 1 + setup/vendor_bill_final_price_check/setup.py | 6 + vendor_bill_final_price_check/README.rst | 59 +++ vendor_bill_final_price_check/__init__.py | 1 + vendor_bill_final_price_check/__manifest__.py | 13 + .../models/__init__.py | 2 + .../models/account_move.py | 17 + .../models/account_move_line.py | 20 + .../readme/DESCRIPTION.rst | 8 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 417 ++++++++++++++++++ .../tests/__init__.py | 1 + .../tests/test_purchase_stock_analytic.py | 43 ++ .../views/account_move_views.xml | 36 ++ 14 files changed, 624 insertions(+) create mode 120000 setup/vendor_bill_final_price_check/odoo/addons/vendor_bill_final_price_check create mode 100644 setup/vendor_bill_final_price_check/setup.py create mode 100644 vendor_bill_final_price_check/README.rst create mode 100644 vendor_bill_final_price_check/__init__.py create mode 100644 vendor_bill_final_price_check/__manifest__.py create mode 100644 vendor_bill_final_price_check/models/__init__.py create mode 100644 vendor_bill_final_price_check/models/account_move.py create mode 100644 vendor_bill_final_price_check/models/account_move_line.py create mode 100644 vendor_bill_final_price_check/readme/DESCRIPTION.rst create mode 100644 vendor_bill_final_price_check/static/description/icon.png create mode 100644 vendor_bill_final_price_check/static/description/index.html create mode 100644 vendor_bill_final_price_check/tests/__init__.py create mode 100644 vendor_bill_final_price_check/tests/test_purchase_stock_analytic.py create mode 100644 vendor_bill_final_price_check/views/account_move_views.xml diff --git a/setup/vendor_bill_final_price_check/odoo/addons/vendor_bill_final_price_check b/setup/vendor_bill_final_price_check/odoo/addons/vendor_bill_final_price_check new file mode 120000 index 00000000..ecee2b44 --- /dev/null +++ b/setup/vendor_bill_final_price_check/odoo/addons/vendor_bill_final_price_check @@ -0,0 +1 @@ +../../../../vendor_bill_final_price_check \ No newline at end of file diff --git a/setup/vendor_bill_final_price_check/setup.py b/setup/vendor_bill_final_price_check/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/vendor_bill_final_price_check/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/vendor_bill_final_price_check/README.rst b/vendor_bill_final_price_check/README.rst new file mode 100644 index 00000000..dff0f2d2 --- /dev/null +++ b/vendor_bill_final_price_check/README.rst @@ -0,0 +1,59 @@ +============================= +Vendor Bill Final Price Check +============================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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--oca-lightgray.png?logo=github + :target: https://github.com/qrtl/axls-oca/tree/16.0/vendor_bill_final_price_check + :alt: qrtl/axls-oca + +|badge1| |badge2| |badge3| + +This module does the following- + - Add confirm_final_price and is_change_price field in account.move + - Add menuitem for account manager to allow confirm for the bills that change the price. + +This module restricts the user to confirm the vendor bills if the price in account.move.line is changed. + +Currently odoo having issue to correct valuation layer and reset to draft button on bill also hidden after price is changed and confirm bills. +So,the purpose of this module is to make sure that if there's a price change on the move line, the change is a final price. + +**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 smashing 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-oca `_ project on GitHub. + +You are welcome to contribute. diff --git a/vendor_bill_final_price_check/__init__.py b/vendor_bill_final_price_check/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/vendor_bill_final_price_check/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/vendor_bill_final_price_check/__manifest__.py b/vendor_bill_final_price_check/__manifest__.py new file mode 100644 index 00000000..f26023af --- /dev/null +++ b/vendor_bill_final_price_check/__manifest__.py @@ -0,0 +1,13 @@ +# Copyright 2023 Quartile Limited +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Vendor Bill Final Price Check", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "Quartile Limited, Odoo Community Association (OCA)", + "website": "https://www.quartile.co", + "depends": ["purchase_stock"], + "data": ["views/account_move_views.xml"], + "installable": True, +} diff --git a/vendor_bill_final_price_check/models/__init__.py b/vendor_bill_final_price_check/models/__init__.py new file mode 100644 index 00000000..0d5ab6a2 --- /dev/null +++ b/vendor_bill_final_price_check/models/__init__.py @@ -0,0 +1,2 @@ +from . import account_move +from . import account_move_line diff --git a/vendor_bill_final_price_check/models/account_move.py b/vendor_bill_final_price_check/models/account_move.py new file mode 100644 index 00000000..3b3f7c28 --- /dev/null +++ b/vendor_bill_final_price_check/models/account_move.py @@ -0,0 +1,17 @@ +# Copyright 2023 Quartile Limited +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, fields, models +from odoo.exceptions import ValidationError + + +class AccountMove(models.Model): + _inherit = "account.move" + + confirm_final_price = fields.Boolean() + is_change_price = fields.Boolean() + + def _post(self, soft=True): + if not self.confirm_final_price and self.is_change_price: + raise ValidationError(_("This document is needed to confirm by manager.")) + return super()._post(soft) diff --git a/vendor_bill_final_price_check/models/account_move_line.py b/vendor_bill_final_price_check/models/account_move_line.py new file mode 100644 index 00000000..776ed540 --- /dev/null +++ b/vendor_bill_final_price_check/models/account_move_line.py @@ -0,0 +1,20 @@ +# Copyright 2023 Quartile Limited +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + @api.onchange("price_unit") + def _onchange_price_unit(self): + for line in self: + if not line.move_id.move_type == "in_invoice": + return + + if not line.purchase_line_id: + return + + if line.product_id and line.product_id.cost_method != "standard": + line._origin.move_id.write({"is_change_price": True}) diff --git a/vendor_bill_final_price_check/readme/DESCRIPTION.rst b/vendor_bill_final_price_check/readme/DESCRIPTION.rst new file mode 100644 index 00000000..6d2ab736 --- /dev/null +++ b/vendor_bill_final_price_check/readme/DESCRIPTION.rst @@ -0,0 +1,8 @@ +This module does the following- + - Add confirm_final_price and is_change_price field in account.move + - Add menuitem for account manager to allow confirm for the bills that change the price. + +This module restricts the user to confirm the vendor bills if the price in account.move.line is changed. + +Currently odoo having issue to correct valuation layer and reset to draft button on bill also hidden after price is changed and confirm bills. +So,the purpose of this module is to make sure that if there's a price change on the move line, the change is a final price. diff --git a/vendor_bill_final_price_check/static/description/icon.png b/vendor_bill_final_price_check/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/vendor_bill_final_price_check/static/description/index.html b/vendor_bill_final_price_check/static/description/index.html new file mode 100644 index 00000000..cc9facbf --- /dev/null +++ b/vendor_bill_final_price_check/static/description/index.html @@ -0,0 +1,417 @@ + + + + + + +Vendor Bill Final Price Check + + + +
+

Vendor Bill Final Price Check

+ + +

Beta License: AGPL-3 qrtl/axls-oca

+
+
This module does the following-
+
    +
  • Add confirm_final_price and is_change_price field in account.move
  • +
  • Add menuitem for account manager to allow confirm for the bills that change the price.
  • +
+
+
+

This module restricts the user to confirm the vendor bills if the price in account.move.line is changed.

+

Currently odoo having issue to correct valuation layer and reset to draft button on bill also hidden after price is changed and confirm bills. +So,the purpose of this module is to make sure that if there’s a price change on the move line, the change is a final price.

+

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 smashing 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-oca project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/vendor_bill_final_price_check/tests/__init__.py b/vendor_bill_final_price_check/tests/__init__.py new file mode 100644 index 00000000..76a2c027 --- /dev/null +++ b/vendor_bill_final_price_check/tests/__init__.py @@ -0,0 +1 @@ +from . import test_purchase_stock_analytic diff --git a/vendor_bill_final_price_check/tests/test_purchase_stock_analytic.py b/vendor_bill_final_price_check/tests/test_purchase_stock_analytic.py new file mode 100644 index 00000000..f49831fa --- /dev/null +++ b/vendor_bill_final_price_check/tests/test_purchase_stock_analytic.py @@ -0,0 +1,43 @@ +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields +from odoo.tests.common import TransactionCase + + +class TestPurchaseStockAnalytic(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.purchase_order_model = cls.env["purchase.order"] + cls.purchase_order_line_model = cls.env["purchase.order.line"] + cls.product_model = cls.env["product.product"] + cls.res_partner_model = cls.env["res.partner"] + + cls.analytic_distribution = dict( + {str(cls.env.ref("analytic.analytic_agrolait").id): 100.0} + ) + cls.partner = cls.res_partner_model.create({"name": "Partner test"}) + cls.product = cls.product_model.create({"name": "Product test"}) + + cls.purchase_order = cls.purchase_order_model.create( + {"partner_id": cls.partner.id} + ) + cls.purchase_order_line = cls.purchase_order_line_model.create( + { + "name": "purchase order line test", + "product_qty": 3, + "order_id": cls.purchase_order.id, + "price_unit": 20, + "product_id": cls.product.id, + "analytic_distribution": cls.analytic_distribution, + "date_planned": fields.Datetime.today(), + "product_uom": cls.product.uom_po_id.id, + } + ) + + def test_purchase_stock_analytic(self): + self.purchase_order.button_confirm() + self.move = self.purchase_order.picking_ids.move_ids_without_package + self.assertEqual(self.move.analytic_distribution, self.analytic_distribution) diff --git a/vendor_bill_final_price_check/views/account_move_views.xml b/vendor_bill_final_price_check/views/account_move_views.xml new file mode 100644 index 00000000..c61e9195 --- /dev/null +++ b/vendor_bill_final_price_check/views/account_move_views.xml @@ -0,0 +1,36 @@ + + + + account.move.form + account.move + + + + + + + + + + Bills to Allow Confirm + account.move + tree,kanban,form + + + [('move_type', '=', 'in_invoice'),('confirm_final_price', '=', False),('is_change_price', '=', True)] + {'default_move_type': 'in_invoice'} + + + From bea88beeabb9e73669a3bb1136cbb752fb706e50 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Thu, 13 Apr 2023 15:52:53 +0630 Subject: [PATCH 2/2] fixes --- .../models/account_move.py | 17 ++--- .../models/account_move_line.py | 67 +++++++++++++++++-- .../readme/DESCRIPTION.rst | 2 +- .../tests/__init__.py | 1 - .../tests/test_purchase_stock_analytic.py | 43 ------------ .../views/account_move_views.xml | 7 +- 6 files changed, 75 insertions(+), 62 deletions(-) delete mode 100644 vendor_bill_final_price_check/tests/__init__.py delete mode 100644 vendor_bill_final_price_check/tests/test_purchase_stock_analytic.py diff --git a/vendor_bill_final_price_check/models/account_move.py b/vendor_bill_final_price_check/models/account_move.py index 3b3f7c28..66a4e75b 100644 --- a/vendor_bill_final_price_check/models/account_move.py +++ b/vendor_bill_final_price_check/models/account_move.py @@ -1,17 +1,18 @@ # Copyright 2023 Quartile Limited # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, fields, models -from odoo.exceptions import ValidationError +from odoo import api, fields, models class AccountMove(models.Model): _inherit = "account.move" - confirm_final_price = fields.Boolean() - is_change_price = fields.Boolean() + confirm_final_price = fields.Boolean(tracking=True) + is_update_svl = fields.Boolean( + compute="_compute_svl_check", store=True, readonly=False + ) - def _post(self, soft=True): - if not self.confirm_final_price and self.is_change_price: - raise ValidationError(_("This document is needed to confirm by manager.")) - return super()._post(soft) + @api.depends("date") + def _compute_svl_check(self): + for line in self.filtered(lambda move: move.state != "posted").invoice_line_ids: + line._check_svl_create() diff --git a/vendor_bill_final_price_check/models/account_move_line.py b/vendor_bill_final_price_check/models/account_move_line.py index 776ed540..3f6fc943 100644 --- a/vendor_bill_final_price_check/models/account_move_line.py +++ b/vendor_bill_final_price_check/models/account_move_line.py @@ -1,20 +1,77 @@ # Copyright 2023 Quartile Limited # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, models +from odoo import _, models +from odoo.exceptions import ValidationError +from odoo.tools.float_utils import float_is_zero class AccountMoveLine(models.Model): _inherit = "account.move.line" - @api.onchange("price_unit") - def _onchange_price_unit(self): + def _create_in_invoice_svl(self): + svl = super(AccountMoveLine, self)._create_in_invoice_svl() + if svl and not self.move_id.confirm_final_price: + raise ValidationError( + _("This document will create new SVL and need to confirm by Manager.") + ) + return svl + + def _check_svl_create(self): + svl_vals_list = [] for line in self: - if not line.move_id.move_type == "in_invoice": + if line.move_id.move_type not in ("in_invoice", "in_refund", "in_receipt"): return if not line.purchase_line_id: return if line.product_id and line.product_id.cost_method != "standard": - line._origin.move_id.write({"is_change_price": True}) + # Reference _create_in_invoice_svl function to check this document + # will create new svl for updating is_update_svl flag for showing list of Bills + # to allow price change for manager. + line = line.with_company(line.company_id) + move = line.move_id.with_company(line.move_id.company_id) + po_line = line.purchase_line_id + uom = line.product_uom_id or line.product_id.uom_id + + quantity = po_line.qty_received - (po_line.qty_invoiced - line.quantity) + quantity = max(min(line.quantity, quantity), 0) + if float_is_zero(quantity, precision_rounding=uom.rounding): + continue + + layers = line._get_stock_valuation_layers(move) + if not layers: + continue + + price_unit = ( + -line.price_unit + if move.move_type == "in_refund" + else line.price_unit + ) + price_unit = price_unit * (1 - (line.discount or 0.0) / 100.0) + if line.tax_ids: + prec = 1e6 + price_unit *= prec + price_unit = line.tax_ids.with_context(round=False).compute_all( + price_unit, + currency=move.currency_id, + quantity=1.0, + is_refund=move.move_type == "in_refund", + fixed_multiplicator=move.direction_sign, + )["total_excluded"] + price_unit /= prec + layers_price_unit = line._get_stock_valuation_layers_price_unit(layers) + layers_to_correct = line._get_stock_layer_price_difference( + layers, layers_price_unit, price_unit + ) + svl_vals_list += line._prepare_in_invoice_svl_vals(layers_to_correct) + + if svl_vals_list: + self.move_id.write({"is_update_svl": True}) + else: + self.move_id.write({"is_update_svl": False}) + + def write(self, vals): + self._check_svl_create() + return super().write(vals) diff --git a/vendor_bill_final_price_check/readme/DESCRIPTION.rst b/vendor_bill_final_price_check/readme/DESCRIPTION.rst index 6d2ab736..8ffefea6 100644 --- a/vendor_bill_final_price_check/readme/DESCRIPTION.rst +++ b/vendor_bill_final_price_check/readme/DESCRIPTION.rst @@ -1,5 +1,5 @@ This module does the following- - - Add confirm_final_price and is_change_price field in account.move + - Add confirm_final_price and is_update_svl field in account.move - Add menuitem for account manager to allow confirm for the bills that change the price. This module restricts the user to confirm the vendor bills if the price in account.move.line is changed. diff --git a/vendor_bill_final_price_check/tests/__init__.py b/vendor_bill_final_price_check/tests/__init__.py deleted file mode 100644 index 76a2c027..00000000 --- a/vendor_bill_final_price_check/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import test_purchase_stock_analytic diff --git a/vendor_bill_final_price_check/tests/test_purchase_stock_analytic.py b/vendor_bill_final_price_check/tests/test_purchase_stock_analytic.py deleted file mode 100644 index f49831fa..00000000 --- a/vendor_bill_final_price_check/tests/test_purchase_stock_analytic.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2020 ACSONE SA/NV -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import fields -from odoo.tests.common import TransactionCase - - -class TestPurchaseStockAnalytic(TransactionCase): - @classmethod - def setUpClass(cls): - super().setUpClass() - cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) - cls.purchase_order_model = cls.env["purchase.order"] - cls.purchase_order_line_model = cls.env["purchase.order.line"] - cls.product_model = cls.env["product.product"] - cls.res_partner_model = cls.env["res.partner"] - - cls.analytic_distribution = dict( - {str(cls.env.ref("analytic.analytic_agrolait").id): 100.0} - ) - cls.partner = cls.res_partner_model.create({"name": "Partner test"}) - cls.product = cls.product_model.create({"name": "Product test"}) - - cls.purchase_order = cls.purchase_order_model.create( - {"partner_id": cls.partner.id} - ) - cls.purchase_order_line = cls.purchase_order_line_model.create( - { - "name": "purchase order line test", - "product_qty": 3, - "order_id": cls.purchase_order.id, - "price_unit": 20, - "product_id": cls.product.id, - "analytic_distribution": cls.analytic_distribution, - "date_planned": fields.Datetime.today(), - "product_uom": cls.product.uom_po_id.id, - } - ) - - def test_purchase_stock_analytic(self): - self.purchase_order.button_confirm() - self.move = self.purchase_order.picking_ids.move_ids_without_package - self.assertEqual(self.move.analytic_distribution, self.analytic_distribution) diff --git a/vendor_bill_final_price_check/views/account_move_views.xml b/vendor_bill_final_price_check/views/account_move_views.xml index c61e9195..341d6615 100644 --- a/vendor_bill_final_price_check/views/account_move_views.xml +++ b/vendor_bill_final_price_check/views/account_move_views.xml @@ -11,20 +11,19 @@ attrs="{'invisible': [('move_type', '!=', 'in_invoice')]}" groups="account.group_account_manager" /> - + - Bills to Allow Confirm + Bills to allow price change account.move tree,kanban,form [('move_type', '=', 'in_invoice'),('confirm_final_price', '=', False),('is_change_price', '=', True)] - {'default_move_type': 'in_invoice'} + >[('move_type', 'in', ['in_invoice', 'in_refund', 'in_receipt']),('confirm_final_price', '=', False),('is_update_svl', '=', True)]