diff options
Diffstat (limited to 'base_accounting_kit/models/credit_limit.py')
| -rw-r--r-- | base_accounting_kit/models/credit_limit.py | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/base_accounting_kit/models/credit_limit.py b/base_accounting_kit/models/credit_limit.py new file mode 100644 index 0000000..9154806 --- /dev/null +++ b/base_accounting_kit/models/credit_limit.py @@ -0,0 +1,250 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2019-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) +# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see <http://www.gnu.org/licenses/>. +# +############################################################################# + +from odoo import models, fields, api +from odoo.exceptions import UserError +from odoo.tools.translate import _ + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + warning_stage = fields.Float(string='Warning Amount', + help="A warning message will appear once the " + "selected customer is crossed warning " + "amount. Set its value to 0.00 to" + " disable this feature") + blocking_stage = fields.Float(string='Blocking Amount', + help="Cannot make sales once the selected " + "customer is crossed blocking amount." + "Set its value to 0.00 to disable " + "this feature") + due_amount = fields.Float(string="Total Sale", + compute="compute_due_amount") + active_limit = fields.Boolean("Active Credit Limit", default=False) + + enable_credit_limit = fields.Boolean(string="Credit Limit Enabled", + compute="_compute_enable_credit_limit") + + def compute_due_amount(self): + for rec in self: + if not rec.id: + continue + rec.due_amount = rec.credit - rec.debit + + def _compute_enable_credit_limit(self): + """ Check credit limit is enabled in account settings """ + params = self.env['ir.config_parameter'].sudo() + customer_credit_limit = params.get_param('customer_credit_limit', + default=False) + for rec in self: + rec.enable_credit_limit = True if customer_credit_limit else False + + @api.constrains('warning_stage', 'blocking_stage') + def constrains_warning_stage(self): + if self.active_limit and self.enable_credit_limit: + if self.warning_stage >= self.blocking_stage: + if self.blocking_stage > 0: + raise UserError(_( + "Warning amount should be less than Blocking amount")) + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + def _get_outstanding_amount(self): + for rec in self: + if not rec.id: + continue + + all_order_amount = 0 + paid_invoice_amount = 0 + outstanding_amount = 0 + + all_order_ids = self.env['sale.order'].search([ + ('state','in',['sale','done']), + ('partner_id','=',rec.partner_id.id), + ('id', '=', rec.id) + ]) + + paid_invoice_ids = self.env['account.move'].search([ + ('payment_state','=','paid'), + ('partner_id','=',rec.partner_id.id), + ('move_type','=','out_invoice') + ]) + + if all_order_ids: + for order in all_order_ids: + all_order_amount += order.amount_total + + if paid_invoice_ids: + for invoice in paid_invoice_ids: + paid_invoice_amount += invoice.amount_total + + outstanding_amount = all_order_amount - paid_invoice_amount + rec.outstanding_amount = outstanding_amount + + has_due = fields.Boolean() + is_warning = fields.Boolean() + due_amount = fields.Float(related='partner_id.due_amount') + outstanding_amount = fields.Float(compute="_get_outstanding_amount", string="Outstanding Amount") + + def compute_due_amount(self): + for rec in self: + if not rec.id: + continue + rec.due_amount = rec.credit - rec.debit + + def _action_confirm(self): + for rec in self: + """To check the selected customers due amount is exceed than + blocking stage""" + all_order_ids = [] + paid_invoice_ids = [] + all_order_amount = 0 + paid_invoice_amount = 0 + outstanding_amount = 0 + + all_order_ids = self.env['sale.order'].search([ + ('state', 'in', ['sale','done']), + ('partner_id', '=', rec.partner_id.id), + ('id', '=', rec.id) + ]) + + paid_invoice_ids = self.env['account.move'].search([ + ('payment_state','=','paid'), + ('partner_id','=',rec.partner_id.id), + ('move_type','=','out_invoice') + ]) + + if all_order_ids: + for order in all_order_ids: + print ("SO ", order.name) + all_order_amount += order.amount_total + print ("All order amount ", all_order_amount) + + if paid_invoice_ids: + for invoice in paid_invoice_ids: + paid_invoice_amount += invoice.amount_total + print ("Paid invoice amount ", paid_invoice_amount) + + outstanding_amount = all_order_amount - paid_invoice_amount + + ###### + if rec.partner_id.active_limit \ + and rec.partner_id.enable_credit_limit: + if (outstanding_amount + rec.amount_total) >= rec.partner_id.blocking_stage: + if rec.partner_id.blocking_stage != 0: + remaining_credit_limit = rec.partner_id.blocking_stage - outstanding_amount + raise UserError(_("%s is in Blocking Stage, Remaining credit limit is %s %s") % (rec.partner_id.name, rec.currency_id.symbol, remaining_credit_limit)) + + return super(SaleOrder, self)._action_confirm() + + @api.onchange('partner_id') + def check_due(self): + """To show the due amount and warning stage""" + if self.partner_id and self.partner_id.due_amount > 0 \ + and self.partner_id.active_limit \ + and self.partner_id.enable_credit_limit: + self.has_due = True + else: + self.has_due = False + if self.partner_id and self.partner_id.active_limit\ + and self.partner_id.enable_credit_limit: + if self.outstanding_amount >= self.partner_id.warning_stage: + if self.partner_id.warning_stage != 0: + self.is_warning = True + else: + self.is_warning = False + + +class AccountMove(models.Model): + _inherit = 'account.move' + + has_due = fields.Boolean() + is_warning = fields.Boolean() + due_amount = fields.Float(related='partner_id.due_amount') + outstanding_amount = fields.Float(compute="_get_outstanding_amount", string="Outstanding Amount") + + def _get_outstanding_amount(self): + for rec in self: + if not rec.id: + continue + + all_order_amount = 0 + paid_invoice_amount = 0 + outstanding_amount = 0 + + all_order_ids = self.env['sale.order'].search([ + ('state','in',['sale','done']), + ('partner_id','=',rec.partner_id.id) + ]) + + paid_invoice_ids = self.env['account.move'].search([ + ('payment_state','=','paid'), + ('partner_id','=',rec.partner_id.id), + ('move_type','=','out_invoice') + ]) + + if all_order_ids: + for order in all_order_ids: + all_order_amount += order.amount_total + + if paid_invoice_ids: + for invoice in paid_invoice_ids: + paid_invoice_amount += invoice.amount_total + + outstanding_amount = all_order_amount - paid_invoice_amount + rec.outstanding_amount = outstanding_amount + + def action_post(self): + """To check the selected customers due amount is exceed than + blocking stage""" + pay_type = ['out_invoice', 'out_refund', 'out_receipt'] + for rec in self: + if rec.partner_id.active_limit and rec.move_type in pay_type \ + and rec.partner_id.enable_credit_limit: + if (rec.outstanding_amount + rec.amount_total) >= rec.partner_id.blocking_stage: + if rec.partner_id.blocking_stage != 0: + raise UserError(_( + "%s is in Blocking Stage and " + "has a due amount of %s %s to pay") % ( + rec.partner_id.name, rec.due_amount, + rec.currency_id.symbol)) + return super(AccountMove, self).action_post() + + @api.onchange('partner_id') + def check_due(self): + """To show the due amount and warning stage""" + if self.partner_id and self.partner_id.due_amount > 0 \ + and self.partner_id.active_limit \ + and self.partner_id.enable_credit_limit: + self.has_due = True + else: + self.has_due = False + if self.partner_id and self.partner_id.active_limit \ + and self.partner_id.enable_credit_limit: + if self.outstanding_amount >= self.partner_id.warning_stage: + if self.partner_id.warning_stage != 0: + self.is_warning = True + else: + self.is_warning = False |
