from odoo import models, api, fields from odoo.exceptions import AccessError, UserError, ValidationError from datetime import timedelta, date import logging _logger = logging.getLogger(__name__) class CommissionInternal(models.Model): _name = 'commission.internal' _description = 'Commission Internal' _order = 'date_doc, id desc' _inherit = ['mail.thread'] _rec_name = 'number' number = fields.Char(string='Document No', index=True, copy=False, readonly=True) date_doc = fields.Date(string='Document Date', required=True) month = fields.Selection([ ('01', 'January'), ('02', 'February'), ('03', 'March'), ('04', 'April'), ('05', 'May'), ('06', 'June'), ('07', 'July'), ('08', 'August'), ('09', 'September'), ('10', 'October'), ('11', 'November'), ('12', 'December') ], string="Commission Month") year = fields.Selection([(str(y), str(y)) for y in range(2025, 2036)], string="Commission Year") description = fields.Char(string='Description') comment = fields.Char(string='Comment') commission_internal_line = fields.One2many('commission.internal.line', 'commission_internal_id', string='Lines', auto_join=True, order='account_move_id asc') @api.model def create(self, vals): vals['number'] = self.env['ir.sequence'].next_by_code('commission.internal') or '0' result = super(CommissionInternal, self).create(vals) return result def _get_commission_internal_bank_account_ids(self): bank_ids = self.env['ir.config_parameter'].sudo().get_param('commission.internal.bank.account.id') if not bank_ids: return [] return [int(x.strip()) for x in bank_ids.split(',') if x.strip().isdigit()] def _get_period_range(self, period_year, period_month): """Return (date_start, date_end) using separate year and month fields.""" self.ensure_one() # make sure it's called on a single record year_str = period_year or '' month_str = period_month or '' # Validate both fields exist if not (year_str.isdigit() and month_str.isdigit()): return None, None year = int(year_str) month = int(month_str) # First day of this month dt_start = date(year, month, 1) # Compute first day of next month if month == 12: next_month = date(year + 1, 1, 1) else: next_month = date(year, month + 1, 1) # Last day = one day before next month's first day dt_end = next_month - timedelta(days=1) return dt_start, dt_end def generate_commission_from_generate_ledger(self): if self.commission_internal_line: raise UserError('Harus hapus semua line jika ingin generate ulang') if not self.month: raise UserError('Commission Month harus diisi') if not self.year: raise UserError('Commission Year harus diisi') dt_start, dt_end = self._get_period_range(self.year, self.month) account_bank_ids = self._get_commission_internal_bank_account_ids() query = [ ('move_id.state', '=', 'posted'), ('account_id', 'in', account_bank_ids), ('date', '>=', dt_start), ('date', '<=', dt_end) ] ledgers = self.env['account.move.line'].search(query) count = 0 for ledger in ledgers: _logger.info("Read General Ledger Account Move Line %s" % ledger.id) self.env['commission.internal.line'].create([{ 'commission_internal_id': self.id, 'date': ledger.date, 'number': ledger.move_id.name, 'account_move_id': ledger.move_id.id, 'account_move_line_id': ledger.id, 'account_id': ledger.account_id.id, 'label': ledger.name, 'debit': ledger.debit, 'credit': ledger.credit, 'balance': ledger.balance }]) count += 1 _logger.info("Commission Internal Line generated %s" % count) class CommissionInternalLine(models.Model): _name = 'commission.internal.line' _description = 'Line' _order = 'number asc, id' commission_internal_id = fields.Many2one('commission.internal', string='Internal Ref', required=True, ondelete='cascade', index=True, copy=False) date = fields.Date(string='Date') number = fields.Char(string='Number') account_move_id = fields.Many2one('account.move', string='Account Move') account_move_line_id = fields.Many2one('account.move.line', string='Account Move Line') account_id = fields.Many2one('account.account', string='Account') label = fields.Char(string='Label') debit = fields.Float(string='Debit') credit = fields.Float(string='Credit') balance = fields.Float(string='Balance') ongkir = fields.Float(string='Ongkir') refund = fields.Float(string='Refund') pph = fields.Float(string='PPh23') others = fields.Float(string='Others') linenetamt = fields.Float(string='Net Amount') dpp = fields.Float(string='DPP') status = fields.Char(string='Status')