From 97599d35f19a2a6542361145b6197f2257523de3 Mon Sep 17 00:00:00 2001 From: Jared Kipe Date: Thu, 20 Jun 2019 10:08:00 -0700 Subject: [PATCH 1/7] Initial commit of `sale_credit_limit` for 11.0 --- sale_credit_limit/__init__.py | 1 + sale_credit_limit/__manifest__.py | 29 ++++++++++++++++++++++ sale_credit_limit/data/sale_exceptions.xml | 21 ++++++++++++++++ sale_credit_limit/models/__init__.py | 1 + sale_credit_limit/models/sale.py | 17 +++++++++++++ sale_credit_limit/views/partner_views.xml | 15 +++++++++++ 6 files changed, 84 insertions(+) create mode 100644 sale_credit_limit/__init__.py create mode 100644 sale_credit_limit/__manifest__.py create mode 100644 sale_credit_limit/data/sale_exceptions.xml create mode 100644 sale_credit_limit/models/__init__.py create mode 100644 sale_credit_limit/models/sale.py create mode 100644 sale_credit_limit/views/partner_views.xml diff --git a/sale_credit_limit/__init__.py b/sale_credit_limit/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/sale_credit_limit/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_credit_limit/__manifest__.py b/sale_credit_limit/__manifest__.py new file mode 100644 index 00000000..966faa45 --- /dev/null +++ b/sale_credit_limit/__manifest__.py @@ -0,0 +1,29 @@ +{ + 'name': 'Sale Credit Limit', + 'summary': 'Uses credit limit on Partners to warn salespeople if they are over their limit.', + 'version': '11.0.1.0.0', + 'author': "Hibou Corp.", + 'category': 'Sale', + 'license': 'AGPL-3', + 'complexity': 'expert', + 'images': [], + 'website': "https://hibou.io", + 'description': """ +Uses credit limit on Partners to warn salespeople if they are over their limit. + +When confirming a sale order, the current sale order total will be considered and a Sale Order Exception +will be created if the total would put them over their credit limit. +""", + 'depends': [ + 'sale', + 'account', + 'sale_exception', + ], + 'demo': [], + 'data': [ + 'data/sale_exceptions.xml', + 'views/partner_views.xml', + ], + 'auto_install': False, + 'installable': True, +} diff --git a/sale_credit_limit/data/sale_exceptions.xml b/sale_credit_limit/data/sale_exceptions.xml new file mode 100644 index 00000000..ba593a13 --- /dev/null +++ b/sale_credit_limit/data/sale_exceptions.xml @@ -0,0 +1,21 @@ + + + + + Invoice Partner credit limit exceeded. + The Customer or Invoice Address has a credit limit. + This sale order, or the customer has an outstanding balance that, exceeds their credit limit. + 50 + sale.order + sale + +partner = sale.partner_invoice_id.commercial_partner_id +partner_balance = partner.credit + sale.amount_total +if partner.credit_limit and partner.credit_limit <= partner_balance: + failed = True + + + sale + + + \ No newline at end of file diff --git a/sale_credit_limit/models/__init__.py b/sale_credit_limit/models/__init__.py new file mode 100644 index 00000000..8a0dc04e --- /dev/null +++ b/sale_credit_limit/models/__init__.py @@ -0,0 +1 @@ +from . import sale diff --git a/sale_credit_limit/models/sale.py b/sale_credit_limit/models/sale.py new file mode 100644 index 00000000..ff40a466 --- /dev/null +++ b/sale_credit_limit/models/sale.py @@ -0,0 +1,17 @@ +from odoo import api, models + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + @api.onchange('partner_invoice_id') + def _onchange_partner_invoice_id(self): + for so in self: + partner = so.partner_invoice_id.commercial_partner_id + if partner.credit_limit and partner.credit_limit <= partner.credit: + m = 'Partner outstanding receivables %0.2f is above their credit limit of %0.2f' \ + % (partner.credit, partner.credit_limit) + return { + 'warning': {'title': 'Sale Credit Limit', + 'message': m} + } diff --git a/sale_credit_limit/views/partner_views.xml b/sale_credit_limit/views/partner_views.xml new file mode 100644 index 00000000..009ee4be --- /dev/null +++ b/sale_credit_limit/views/partner_views.xml @@ -0,0 +1,15 @@ + + + + + res.partner.form.inherit + res.partner + + + + + + + + + \ No newline at end of file From b30feb3b35f52535965d93a406458908f6ed5733 Mon Sep 17 00:00:00 2001 From: Jared Kipe Date: Thu, 20 Jun 2019 15:15:54 -0700 Subject: [PATCH 2/7] IMP `sale_credit_limit` Include the Currency and Currency formatting in SO warning. --- sale_credit_limit/models/sale.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sale_credit_limit/models/sale.py b/sale_credit_limit/models/sale.py index ff40a466..5b1f9b89 100644 --- a/sale_credit_limit/models/sale.py +++ b/sale_credit_limit/models/sale.py @@ -1,4 +1,5 @@ from odoo import api, models +from odoo.addons.mail.models.mail_template import format_amount class SaleOrder(models.Model): @@ -9,8 +10,9 @@ class SaleOrder(models.Model): for so in self: partner = so.partner_invoice_id.commercial_partner_id if partner.credit_limit and partner.credit_limit <= partner.credit: - m = 'Partner outstanding receivables %0.2f is above their credit limit of %0.2f' \ - % (partner.credit, partner.credit_limit) + m = 'Partner outstanding receivables %s is above their credit limit of %s' \ + % (format_amount(self.env, partner.credit, so.currency_id), + format_amount(self.env, partner.credit_limit, so.currency_id)) return { 'warning': {'title': 'Sale Credit Limit', 'message': m} From ec82434f6190a32379553b2914e015f056bb42fa Mon Sep 17 00:00:00 2001 From: Jared Kipe Date: Tue, 3 Sep 2019 14:03:09 -0700 Subject: [PATCH 3/7] MIG `sale_credit_limit` for 12.0 --- sale_credit_limit/__manifest__.py | 2 +- sale_credit_limit/views/partner_views.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sale_credit_limit/__manifest__.py b/sale_credit_limit/__manifest__.py index 966faa45..f0291499 100644 --- a/sale_credit_limit/__manifest__.py +++ b/sale_credit_limit/__manifest__.py @@ -1,7 +1,7 @@ { 'name': 'Sale Credit Limit', 'summary': 'Uses credit limit on Partners to warn salespeople if they are over their limit.', - 'version': '11.0.1.0.0', + 'version': '12.0.1.0.0', 'author': "Hibou Corp.", 'category': 'Sale', 'license': 'AGPL-3', diff --git a/sale_credit_limit/views/partner_views.xml b/sale_credit_limit/views/partner_views.xml index 009ee4be..e9dbe0ae 100644 --- a/sale_credit_limit/views/partner_views.xml +++ b/sale_credit_limit/views/partner_views.xml @@ -6,7 +6,7 @@ res.partner - + From dbb450f91f7a090d0eadf7b00e2b0d7ecc094d6a Mon Sep 17 00:00:00 2001 From: Bhoomi Vaishnani Date: Tue, 14 Jul 2020 12:30:11 -0400 Subject: [PATCH 4/7] [MIG] sale_credit_limit: For Odoo13.0 --- sale_credit_limit/__manifest__.py | 2 +- sale_credit_limit/data/sale_exceptions.xml | 2 -- sale_credit_limit/models/sale.py | 7 ++-- sale_credit_limit/tests/__init__.py | 1 + .../tests/test_sale_credit_exception.py | 32 +++++++++++++++++++ 5 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 sale_credit_limit/tests/__init__.py create mode 100644 sale_credit_limit/tests/test_sale_credit_exception.py diff --git a/sale_credit_limit/__manifest__.py b/sale_credit_limit/__manifest__.py index f0291499..30ec8fe4 100644 --- a/sale_credit_limit/__manifest__.py +++ b/sale_credit_limit/__manifest__.py @@ -1,7 +1,7 @@ { 'name': 'Sale Credit Limit', 'summary': 'Uses credit limit on Partners to warn salespeople if they are over their limit.', - 'version': '12.0.1.0.0', + 'version': '13.0.1.0.0', 'author': "Hibou Corp.", 'category': 'Sale', 'license': 'AGPL-3', diff --git a/sale_credit_limit/data/sale_exceptions.xml b/sale_credit_limit/data/sale_exceptions.xml index ba593a13..b8f6192d 100644 --- a/sale_credit_limit/data/sale_exceptions.xml +++ b/sale_credit_limit/data/sale_exceptions.xml @@ -7,7 +7,6 @@ This sale order, or the customer has an outstanding balance that, exceeds their credit limit. 50 sale.order - sale partner = sale.partner_invoice_id.commercial_partner_id partner_balance = partner.credit + sale.amount_total @@ -15,7 +14,6 @@ if partner.credit_limit and partner.credit_limit <= partner_balance: failed = True - sale \ No newline at end of file diff --git a/sale_credit_limit/models/sale.py b/sale_credit_limit/models/sale.py index 5b1f9b89..5b90514e 100644 --- a/sale_credit_limit/models/sale.py +++ b/sale_credit_limit/models/sale.py @@ -1,5 +1,4 @@ -from odoo import api, models -from odoo.addons.mail.models.mail_template import format_amount +from odoo import api, models, tools class SaleOrder(models.Model): @@ -11,8 +10,8 @@ class SaleOrder(models.Model): partner = so.partner_invoice_id.commercial_partner_id if partner.credit_limit and partner.credit_limit <= partner.credit: m = 'Partner outstanding receivables %s is above their credit limit of %s' \ - % (format_amount(self.env, partner.credit, so.currency_id), - format_amount(self.env, partner.credit_limit, so.currency_id)) + % (tools.format_amount(self.env, partner.credit, so.currency_id), + tools.format_amount(self.env, partner.credit_limit, so.currency_id)) return { 'warning': {'title': 'Sale Credit Limit', 'message': m} diff --git a/sale_credit_limit/tests/__init__.py b/sale_credit_limit/tests/__init__.py new file mode 100644 index 00000000..a2d422d0 --- /dev/null +++ b/sale_credit_limit/tests/__init__.py @@ -0,0 +1 @@ +from . import test_sale_credit_exception diff --git a/sale_credit_limit/tests/test_sale_credit_exception.py b/sale_credit_limit/tests/test_sale_credit_exception.py new file mode 100644 index 00000000..d679661f --- /dev/null +++ b/sale_credit_limit/tests/test_sale_credit_exception.py @@ -0,0 +1,32 @@ + +from odoo.addons.sale_exception.tests.test_sale_exception import TestSaleException + + +class TestSaleCreditException(TestSaleException): + + def setUp(self): + super(TestSaleCreditException, self).setUp() + + def test_sale_order_credit_limit_exception(self): + self.sale_exception_confirm = self.env['sale.exception.confirm'] + exception = self.env.ref('sale_credit_limit.excep_sale_credit_limit') + exception.active = True + partner = self.env.ref('base.res_partner_12') + partner.credit_limit = 100.00 + p = self.env.ref('product.product_product_25_product_template') + so1 = self.env['sale.order'].create({ + 'partner_id': partner.id, + 'partner_invoice_id': partner.id, + 'partner_shipping_id': partner.id, + 'order_line': [(0, 0, {'name': p.name, + 'product_id': p.id, + 'product_uom_qty': 2, + 'product_uom': p.uom_id.id, + 'price_unit': p.list_price})], + 'pricelist_id': self.env.ref('product.list0').id, + }) + + # confirm quotation + so1.action_confirm() + self.assertTrue(so1.state == 'draft') + self.assertFalse(so1.ignore_exception) From f1d694cb34d2d0e59d2ca31c7dd0b71d6423b665 Mon Sep 17 00:00:00 2001 From: Jared Self Date: Wed, 18 Nov 2020 11:51:51 -0700 Subject: [PATCH 5/7] [MIG] Changed User For Test Module --- sale_credit_limit/__manifest__.py | 2 +- sale_credit_limit/tests/test_sale_credit_exception.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sale_credit_limit/__manifest__.py b/sale_credit_limit/__manifest__.py index 30ec8fe4..8b45f97c 100644 --- a/sale_credit_limit/__manifest__.py +++ b/sale_credit_limit/__manifest__.py @@ -1,7 +1,7 @@ { 'name': 'Sale Credit Limit', 'summary': 'Uses credit limit on Partners to warn salespeople if they are over their limit.', - 'version': '13.0.1.0.0', + 'version': '14.0.1.0.0', 'author': "Hibou Corp.", 'category': 'Sale', 'license': 'AGPL-3', diff --git a/sale_credit_limit/tests/test_sale_credit_exception.py b/sale_credit_limit/tests/test_sale_credit_exception.py index d679661f..01a63cfd 100644 --- a/sale_credit_limit/tests/test_sale_credit_exception.py +++ b/sale_credit_limit/tests/test_sale_credit_exception.py @@ -8,8 +8,9 @@ class TestSaleCreditException(TestSaleException): super(TestSaleCreditException, self).setUp() def test_sale_order_credit_limit_exception(self): + admin_user = self.env.ref('base.user_admin') self.sale_exception_confirm = self.env['sale.exception.confirm'] - exception = self.env.ref('sale_credit_limit.excep_sale_credit_limit') + exception = self.env.ref('sale_credit_limit.excep_sale_credit_limit').with_user(admin_user) exception.active = True partner = self.env.ref('base.res_partner_12') partner.credit_limit = 100.00 From 7aa422f738aa6a98dfe88cdafee6aced5660772b Mon Sep 17 00:00:00 2001 From: Jared Kipe Date: Mon, 22 Mar 2021 15:16:19 -0700 Subject: [PATCH 6/7] [IMP] sale_credit_limit: forward port improvements, Hibou Professional --- sale_credit_limit/__manifest__.py | 4 +-- sale_credit_limit/data/sale_exceptions.xml | 28 +++++++++++++++++++ sale_credit_limit/models/__init__.py | 3 ++ sale_credit_limit/models/partner.py | 18 ++++++++++++ sale_credit_limit/models/sale.py | 10 +++++++ sale_credit_limit/tests/__init__.py | 2 ++ .../tests/test_sale_credit_exception.py | 4 +-- sale_credit_limit/views/partner_views.xml | 9 ++++-- 8 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 sale_credit_limit/models/partner.py diff --git a/sale_credit_limit/__manifest__.py b/sale_credit_limit/__manifest__.py index 8b45f97c..f5c0bae1 100644 --- a/sale_credit_limit/__manifest__.py +++ b/sale_credit_limit/__manifest__.py @@ -1,10 +1,10 @@ { 'name': 'Sale Credit Limit', 'summary': 'Uses credit limit on Partners to warn salespeople if they are over their limit.', - 'version': '14.0.1.0.0', + 'version': '14.0.1.0.1', 'author': "Hibou Corp.", 'category': 'Sale', - 'license': 'AGPL-3', + 'license': 'OPL-1', 'complexity': 'expert', 'images': [], 'website': "https://hibou.io", diff --git a/sale_credit_limit/data/sale_exceptions.xml b/sale_credit_limit/data/sale_exceptions.xml index b8f6192d..796e107f 100644 --- a/sale_credit_limit/data/sale_exceptions.xml +++ b/sale_credit_limit/data/sale_exceptions.xml @@ -16,4 +16,32 @@ if partner.credit_limit and partner.credit_limit <= partner_balance: + + Customer On Credit Hold. + The Customer is on Credit Hold. + Please have the customer contact accounting. + 50 + sale.order + +partner = sale.partner_invoice_id.commercial_partner_id +if partner.credit_hold: + failed = True + + + + + + Customer has Overdue Invoices. + The Customer has unpaid overdue invoices. + Please have the customer contact accounting. + 55 + sale.order + +partner = sale.partner_invoice_id.commercial_partner_id +if partner.invoice_ids.filtered(lambda i: i.state == 'posted' and i.payment_state != 'paid' and (i.invoice_date_due and str(i.invoice_date_due) < str(datetime.date.today())) and i.move_type == 'out_invoice'): + failed = True + + + + \ No newline at end of file diff --git a/sale_credit_limit/models/__init__.py b/sale_credit_limit/models/__init__.py index 8a0dc04e..da805931 100644 --- a/sale_credit_limit/models/__init__.py +++ b/sale_credit_limit/models/__init__.py @@ -1 +1,4 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from . import partner from . import sale diff --git a/sale_credit_limit/models/partner.py b/sale_credit_limit/models/partner.py new file mode 100644 index 00000000..ce018f0f --- /dev/null +++ b/sale_credit_limit/models/partner.py @@ -0,0 +1,18 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + +from odoo import api, fields, models + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + credit_remaining = fields.Float('Credit Remaining', compute='_compute_credit_remaining') + credit_hold = fields.Boolean('Credit Hold') + + @api.depends('credit_limit', 'credit') + def _compute_credit_remaining(self): + for partner in self: + if partner.credit_limit: + partner.credit_remaining = partner.credit_limit - partner.credit + else: + partner.credit_remaining = 0.0 diff --git a/sale_credit_limit/models/sale.py b/sale_credit_limit/models/sale.py index 5b90514e..4512fcac 100644 --- a/sale_credit_limit/models/sale.py +++ b/sale_credit_limit/models/sale.py @@ -1,9 +1,19 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + from odoo import api, models, tools +from odoo.tools.safe_eval import datetime as wrapped_datetime class SaleOrder(models.Model): _inherit = 'sale.order' + # We need a way to be able to create a 'today' date to compare + @api.model + def _exception_rule_eval_context(self, rec): + res = super(SaleOrder, self)._exception_rule_eval_context(rec) + res["datetime"] = wrapped_datetime + return res + @api.onchange('partner_invoice_id') def _onchange_partner_invoice_id(self): for so in self: diff --git a/sale_credit_limit/tests/__init__.py b/sale_credit_limit/tests/__init__.py index a2d422d0..2fe6104a 100644 --- a/sale_credit_limit/tests/__init__.py +++ b/sale_credit_limit/tests/__init__.py @@ -1 +1,3 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + from . import test_sale_credit_exception diff --git a/sale_credit_limit/tests/test_sale_credit_exception.py b/sale_credit_limit/tests/test_sale_credit_exception.py index 01a63cfd..f0af5e30 100644 --- a/sale_credit_limit/tests/test_sale_credit_exception.py +++ b/sale_credit_limit/tests/test_sale_credit_exception.py @@ -1,3 +1,4 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. from odoo.addons.sale_exception.tests.test_sale_exception import TestSaleException @@ -8,10 +9,7 @@ class TestSaleCreditException(TestSaleException): super(TestSaleCreditException, self).setUp() def test_sale_order_credit_limit_exception(self): - admin_user = self.env.ref('base.user_admin') self.sale_exception_confirm = self.env['sale.exception.confirm'] - exception = self.env.ref('sale_credit_limit.excep_sale_credit_limit').with_user(admin_user) - exception.active = True partner = self.env.ref('base.res_partner_12') partner.credit_limit = 100.00 p = self.env.ref('product.product_product_25_product_template') diff --git a/sale_credit_limit/views/partner_views.xml b/sale_credit_limit/views/partner_views.xml index e9dbe0ae..7463769c 100644 --- a/sale_credit_limit/views/partner_views.xml +++ b/sale_credit_limit/views/partner_views.xml @@ -6,8 +6,13 @@ res.partner - - + + + + + + + From 85b256425ac39146cdd6ce1d640792a88474a854 Mon Sep 17 00:00:00 2001 From: Jared Kipe Date: Mon, 6 Dec 2021 09:47:02 -0800 Subject: [PATCH 7/7] [MIG] sale_credit_limit: for Odoo 15.0 --- sale_credit_limit/__manifest__.py | 2 +- sale_credit_limit/data/sale_exceptions.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sale_credit_limit/__manifest__.py b/sale_credit_limit/__manifest__.py index f5c0bae1..c112b152 100644 --- a/sale_credit_limit/__manifest__.py +++ b/sale_credit_limit/__manifest__.py @@ -1,7 +1,7 @@ { 'name': 'Sale Credit Limit', 'summary': 'Uses credit limit on Partners to warn salespeople if they are over their limit.', - 'version': '14.0.1.0.1', + 'version': '15.0.1.0.0', 'author': "Hibou Corp.", 'category': 'Sale', 'license': 'OPL-1', diff --git a/sale_credit_limit/data/sale_exceptions.xml b/sale_credit_limit/data/sale_exceptions.xml index 796e107f..cba88e60 100644 --- a/sale_credit_limit/data/sale_exceptions.xml +++ b/sale_credit_limit/data/sale_exceptions.xml @@ -8,8 +8,8 @@ 50 sale.order -partner = sale.partner_invoice_id.commercial_partner_id -partner_balance = partner.credit + sale.amount_total +partner = object.partner_invoice_id.commercial_partner_id +partner_balance = partner.credit + object.amount_total if partner.credit_limit and partner.credit_limit <= partner_balance: failed = True @@ -23,7 +23,7 @@ if partner.credit_limit and partner.credit_limit <= partner_balance: 50 sale.order -partner = sale.partner_invoice_id.commercial_partner_id +partner = object.partner_invoice_id.commercial_partner_id if partner.credit_hold: failed = True @@ -37,7 +37,7 @@ if partner.credit_hold: 55 sale.order -partner = sale.partner_invoice_id.commercial_partner_id +partner = object.partner_invoice_id.commercial_partner_id if partner.invoice_ids.filtered(lambda i: i.state == 'posted' and i.payment_state != 'paid' and (i.invoice_date_due and str(i.invoice_date_due) < str(datetime.date.today())) and i.move_type == 'out_invoice'): failed = True