from odoo import models, api, fields from odoo.exceptions import UserError from datetime import datetime import logging _logger = logging.getLogger(__name__) class CustomerRebate(models.Model): _name = 'customer.rebate' _order = 'id desc' _inherit = ['mail.thread'] partner_id = fields.Many2one('res.partner', string='Customer', required=True) date_from = fields.Date(string='Date From', required=True, help="Pastikan tanggal 1 januari, jika tidak, code akan break") date_to = fields.Date(string='Date To', required=True, help="Pastikan tanggal 31 desember, jika tidak, code akan break") description = fields.Char(string='Description') target_1st = fields.Float(string='Target/Quarter 1st') target_2nd = fields.Float(string='Target/Quarter 2nd') achieve_1 = fields.Float(string='Achieve 1 %') achieve_2 = fields.Float(string='Achieve 2 %') dpp_q1 = fields.Float(string='DPP Q1', compute='_compute_current_dpp') dpp_q2 = fields.Float(string='DPP Q2', compute='_compute_current_dpp') dpp_q3 = fields.Float(string='DPP Q3', compute='_compute_current_dpp') dpp_q4 = fields.Float(string='DPP Q4', compute='_compute_current_dpp') status_q1 = fields.Char(string='Status Q1', compute='_compute_achievement') status_q2 = fields.Char(string='Status Q2', compute='_compute_achievement') status_q3 = fields.Char(string='Status Q3', compute='_compute_achievement') status_q4 = fields.Char(string='Status Q4', compute='_compute_achievement') # all code class CustomerRebate deprecated, cause lack of performance def _compute_current_dpp(self): for line in self: line.dpp_q1 = line._get_current_dpp_q1(line) line.dpp_q2 = line._get_current_dpp_q2(line) line.dpp_q3 = line._get_current_dpp_q3(line) line.dpp_q4 = line._get_current_dpp_q4(line) def _compute_achievement(self): for line in self: line.status_q1 = line._check_achievement(line.target_1st, line.target_2nd, line.dpp_q1) line.status_q2 = line._check_achievement(line.target_1st, line.target_2nd, line.dpp_q2) line.status_q3 = line._check_achievement(line.target_1st, line.target_2nd, line.dpp_q3) line.status_q4 = line._check_achievement(line.target_1st, line.target_2nd, line.dpp_q4) def _check_achievement(self, target_1st, target_2nd, dpp): status = 'not achieve' if dpp >= target_1st: status = '1st' elif dpp >= target_2nd: status = '2nd' else: status = 'not achieve' return status def _get_current_dpp_q1(self, line): sum_dpp = 0 brand = [10, 89, 122] where = [ ('move_id.move_type', '=', 'out_invoice'), ('move_id.state', '=', 'posted'), ('move_id.is_customer_commision', '=', False), ('move_id.partner_id.id', '=', line.partner_id.id), ('move_id.invoice_date', '>=', line.date_from), ('move_id.invoice_date', '<=', '2023-03-31'), ('product_id.x_manufacture', 'in', brand), ] invoice_lines = self.env['account.move.line'].search(where, order='id') for invoice_line in invoice_lines: sum_dpp += invoice_line.price_subtotal return sum_dpp def _get_current_dpp_q2(self, line): sum_dpp = 0 brand = [10, 89, 122] where = [ ('move_id.move_type', '=', 'out_invoice'), ('move_id.state', '=', 'posted'), ('move_id.is_customer_commision', '=', False), ('move_id.partner_id.id', '=', line.partner_id.id), ('move_id.invoice_date', '>=', '2023-04-01'), ('move_id.invoice_date', '<=', '2023-06-30'), ('product_id.x_manufacture', 'in', brand), ] invoices = self.env['account.move.line'].search(where, order='id') for invoice in invoices: sum_dpp += invoice.price_subtotal return sum_dpp def _get_current_dpp_q3(self, line): sum_dpp = 0 brand = [10, 89, 122] where = [ ('move_id.move_type', '=', 'out_invoice'), ('move_id.state', '=', 'posted'), ('move_id.is_customer_commision', '=', False), ('move_id.partner_id.id', '=', line.partner_id.id), ('move_id.invoice_date', '>=', '2023-07-01'), ('move_id.invoice_date', '<=', '2023-09-30'), ('product_id.x_manufacture', 'in', brand), ] invoices = self.env['account.move.line'].search(where, order='id') for invoice in invoices: sum_dpp += invoice.price_subtotal return sum_dpp def _get_current_dpp_q4(self, line): sum_dpp = 0 brand = [10, 89, 122] where = [ ('move_id.move_type', '=', 'out_invoice'), ('move_id.state', '=', 'posted'), ('move_id.is_customer_commision', '=', False), ('move_id.partner_id.id', '=', line.partner_id.id), ('move_id.invoice_date', '>=', '2023-10-01'), ('move_id.invoice_date', '<=', line.date_to), ('product_id.x_manufacture', 'in', brand), ] invoices = self.env['account.move.line'].search(where, order='id') for invoice in invoices: sum_dpp += invoice.price_subtotal return sum_dpp class CustomerCommision(models.Model): _name = 'customer.commision' _order = 'id desc' _inherit = ['mail.thread'] _rec_name = 'number' number = fields.Char(string='Document No', index=True, copy=False, readonly=True) date_from = fields.Date(string='Date From', required=True) date_to = fields.Date(string='Date To', required=True) partner_ids = fields.Many2many('res.partner', String='Customer', required=True) description = fields.Char(string='Description') notification = fields.Char(string='Notification') commision_lines = fields.One2many('customer.commision.line', 'customer_commision_id', string='Lines', auto_join=True) status = fields.Selection([ ('pengajuan1', 'Menunggu Approval Marketing'), ('pengajuan2', 'Menunggu Approval Pimpinan'), ('approved', 'Approved') ], string='Status', copy=False, readonly=True, tracking=3) commision_percent = fields.Float(string='Commision %', tracking=3) commision_amt = fields.Float(string='Commision Amount', tracking=3) total_dpp = fields.Float(string='Total DPP', compute='_compute_total_dpp') commision_type = fields.Selection([ ('fee', 'Fee'), ('cashback', 'Cashback'), ('rebate', 'Rebate'), ], string='Commision Type', required=True) bank_name = fields.Char(string='Bank', tracking=3) account_name = fields.Char(string='Account Name', tracking=3) bank_account = fields.Char(string='Account No', tracking=3) note_transfer = fields.Char(string='Keterangan') # add status for type of commision, fee, rebate / cashback # include child or not? # @api.constrains('partner_ids') def _onchange_partner_ids(self): commision = self.env['cust.commision'].search([ ('partner_id', 'in', [rec.id for rec in self.partner_ids]), ('commision_type', '=', self.commision_type) ], limit=1) if commision: if self.commision_type == 'fee': max_commision = max(commision.mapped('commision_percent')) self.commision_percent = max_commision else: target_1st, target_2nd = commision.target_1st, commision.target_2nd achieve_1st, achieve_2nd = commision.achieve_1st, commision.achieve_2nd if self.total_dpp >= target_1st: self.commision_percent = achieve_1st elif target_2nd <= self.total_dpp < target_1st: self.commision_percent = achieve_2nd else: self.commision_percent = 0 self._onchange_commision_amt() @api.constrains('commision_percent') def _onchange_commision_percent(self): if not self.env.context.get('_onchange_commision_percent', True): return if self.commision_amt == 0: self.commision_amt = self.commision_percent * self.total_dpp // 100 @api.constrains('commision_amt') def _onchange_commision_amt(self): if not self.env.context.get('_onchange_commision_amt', True): return if self.total_dpp > 0 and self.commision_percent == 0: self.commision_percent = (self.commision_amt / self.total_dpp) * 100 def _compute_total_dpp(self): for data in self: total_dpp = 0 for line in data.commision_lines: total_dpp = total_dpp + line.dpp data.total_dpp = total_dpp @api.model def create(self, vals): vals['number'] = self.env['ir.sequence'].next_by_code('customer.commision') or '0' # if vals['commision_amt'] > 0: # commision_amt = vals['commision_amt'] # total_dpp = vals['total_dpp'] # commision_percent = commision_amt / total_dpp * 100 # vals['commision_percent'] = commision_percent result = super(CustomerCommision, self).create(vals) return result def action_confirm_customer_commision(self):#add 2 step approval if not self.status: self.status = 'pengajuan1' elif self.status == 'pengajuan1' and self.env.user.id == 19: self.status = 'pengajuan2' elif self.status == 'pengajuan2' and self.env.user.is_leader: for line in self.commision_lines: line.invoice_id.is_customer_commision = True self.status = 'approved' else: raise UserError('Harus di approved oleh yang bersangkutan') return def generate_customer_commision(self): if self.commision_lines: raise UserError('Line sudah ada, tidak bisa di generate ulang') if self.commision_type == 'fee': self._generate_customer_commision_fee() else: self._generate_customer_commision_rebate() context = self.env.context.copy() context.update({'_onchange_commision_amt': False}) self.env.context = context self._onchange_partner_ids() # self._onchange_commision_percent() # self._onchange_commision_amt() def _generate_customer_commision_rebate(self): for rec in self: # partners = rec.partner_ids.child_ids + rec.partner_ids partners = rec.partner_ids for partner in partners: brand = [92, 10, 89, 12, 324, 11] where = [ ('move_id.move_type', '=', 'out_invoice'), ('move_id.state', '=', 'posted'), ('move_id.is_customer_commision', '=', False), ('move_id.amount_residual_signed', '=', 0), ('move_id.partner_id.id', '=', partner.id), ('move_id.invoice_date', '>=', self.date_from), ('move_id.invoice_date', '<=', self.date_to), ('product_id.x_manufacture', 'in', brand), ] invoice_lines = self.env['account.move.line'].search(where, order='id') for invoice_line in invoice_lines: tax = invoice_line.price_total - invoice_line.price_subtotal self.env['customer.commision.line'].create([{ 'customer_commision_id': self.id, 'partner_id': invoice_line.move_id.partner_id.id, 'invoice_id': invoice_line.move_id.id, 'state': invoice_line.move_id.state, 'product_id': invoice_line.product_id.id, 'dpp': invoice_line.price_subtotal, 'tax': tax, 'total': invoice_line.price_total }]) return def _generate_customer_commision_fee(self): for rec in self: # partners = rec.partner_ids.child_ids + rec.partner_ids partners = rec.partner_ids for partner in partners: where = [ ('move_type', '=', 'out_invoice'), ('state', '=', 'posted'), ('is_customer_commision', '=', False), ('amount_residual_signed', '=', 0), ('partner_id.id', '=', partner.id), ('invoice_date', '>=', self.date_from), ('invoice_date', '<=', self.date_to), ] invoices = self.env['account.move'].search(where, order='id') for invoice in invoices: self.env['customer.commision.line'].create([{ 'customer_commision_id': self.id, 'partner_id': invoice.partner_id.id, 'invoice_id': invoice.id, 'state': invoice.state, 'dpp': invoice.amount_untaxed_signed, 'tax': invoice.amount_tax_signed, 'total': invoice.amount_total_signed }]) return class CustomerCommisionLine(models.Model): _name = 'customer.commision.line' _order = 'id' customer_commision_id = fields.Many2one('customer.commision', string='Ref', required=True, ondelete='cascade', copy=False) invoice_id = fields.Many2one('account.move', string='Invoice') partner_id = fields.Many2one('res.partner', string='Customer') state = fields.Char(string='InvStatus') dpp = fields.Float(string='DPP') tax = fields.Float(string='TaxAmt') total = fields.Float(string='Total') product_id = fields.Many2one('product.product', string='Product') class AccountMove(models.Model): _inherit = 'account.move' is_customer_commision = fields.Boolean(string='Customer Commision Used')