# -*- coding: utf-8 -*- ############################################################################# # # Cybrosys Technologies Pvt. Ltd. # # Copyright (C) 2019-TODAY Cybrosys Technologies() # Author: Cybrosys Techno Solutions() # # 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 . # ############################################################################# 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' approval_status = fields.Selection([ ('pengajuan1', 'Approval Manager'), ('pengajuan2', 'Approval Pimpinan'), ('approved', 'Approved'), ], string='Approval Status', readonly=True, copy=False, index=True, tracking=3) def _get_outstanding_amount(self): for rec in self: if not rec.id: continue all_order_amount = 0 outstanding_invoice_amount = 0 outstanding_amount = 0 # this is only outstanding per user, must add outstanding parent partners = [] parent_id = 0 if rec.partner_id.parent_id: parent_id = rec.partner_id.parent_id else: parent_id = rec.partner_id partners += parent_id.child_ids partners.append(parent_id) for partner in partners: if partner.type != 'contact': continue print(partner.name) outstanding_invoice_ids = self.env['account.move'].search([ # ('payment_state', '=', 'paid'), ('partner_id', '=', partner.id), ('move_type', '=', 'out_invoice'), ('amount_residual_signed', '>', 0), ('state', '=', 'posted') ]) if outstanding_invoice_ids: print("-----check invoice here-----") for invoice in outstanding_invoice_ids: print(invoice.name) print(invoice.amount_total) outstanding_invoice_amount += invoice.amount_total outstanding_amount = outstanding_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: # all_order_amount += order.amount_total # # if paid_invoice_ids: # for invoice in paid_invoice_ids: # paid_invoice_amount += invoice.amount_total outstanding_amount = rec.outstanding_amount check_credit_limit = False ###### block_stage = 0 if rec.partner_id.parent_id: if rec.partner_id.parent_id.active_limit and rec.partner_id.parent_id.enable_credit_limit: check_credit_limit = True else: if rec.partner_id.active_limit and rec.partner_id.enable_credit_limit: check_credit_limit = True term_days = 0 for term_line in rec.payment_term_id.line_ids: term_days += term_line.days if term_days == 0: check_credit_limit = False if check_credit_limit: if rec.partner_id.parent_id: block_stage = rec.partner_id.parent_id.blocking_stage or 0 else: block_stage = rec.partner_id.blocking_stage or 0 if (outstanding_amount + rec.amount_total) >= block_stage: if block_stage != 0: remaining_credit_limit = block_stage - outstanding_amount raise UserError(_("%s is in Blocking Stage, Remaining credit limit is %s, from %s and outstanding %s") % (rec.partner_id.name, remaining_credit_limit, block_stage, outstanding_amount)) return super(SaleOrder, self)._action_confirm() @api.onchange('partner_id') def check_due(self): """To show the due amount and warning stage""" for order in self: # partner_id = 0aku if order.partner_id.parent_id: partner_id = order.partner_id.parent_id else: partner_id = order.partner_id if partner_id and partner_id.due_amount > 0 \ and partner_id.active_limit \ and partner_id.enable_credit_limit: order.has_due = True else: order.has_due = False if partner_id and partner_id.active_limit\ and partner_id.enable_credit_limit: print(order.outstanding_amount) if order.outstanding_amount >= partner_id.warning_stage: if partner_id.warning_stage != 0: order.is_warning = True else: order.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 outstanding_invoice_amount = 0 partners = [] parent_id = 0 if rec.partner_id.parent_id: parent_id = rec.partner_id.parent_id else: parent_id = rec.partner_id partners += parent_id.child_ids partners.append(parent_id) for partner in partners: if partner.type != 'contact': continue print(partner.name) outstanding_invoice_ids = self.env['account.move'].search([ # ('payment_state', '=', 'paid'), ('partner_id', '=', partner.id), ('move_type', '=', 'out_invoice'), ('amount_residual_signed', '>', 0), ('state', '=', 'posted') ]) if outstanding_invoice_ids: print("-----check invoice here-----") for invoice in outstanding_invoice_ids: print(invoice.name) print(invoice.amount_total) outstanding_invoice_amount += invoice.amount_total # outstanding_amount = all_order_amount - paid_invoice_amount outstanding_amount = outstanding_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.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""" for order in self: if order.partner_id.parent_id: partner_id = order.partner_id.parent_id else: partner_id = order.partner_id if partner_id and partner_id.due_amount > 0 \ and partner_id.active_limit \ and partner_id.enable_credit_limit: order.has_due = True else: order.has_due = False if partner_id and partner_id.active_limit \ and partner_id.enable_credit_limit: if order.outstanding_amount >= partner_id.warning_stage: if partner_id.warning_stage != 0: order.is_warning = True else: order.is_warning = False