from odoo import models, api, fields, _ from odoo.exceptions import UserError from datetime import datetime # import datetime import logging _logger = logging.getLogger(__name__) from terbilang import Terbilang import pytz from pytz import timezone class DownPayment(models.Model): _name = 'down.payment' _description = 'Down Payment Management' _rec_name = 'number' _inherit = ['mail.thread'] user_id = fields.Many2one('res.users', string='Diajukan Oleh', default=lambda self: self.env.user, tracking=3) number = fields.Char(string='No. Dokumen', default='New Draft', tracking=3) applicant_name = fields.Char(string='Nama Pemohon', tracking=3, required=True) nominal = fields.Float(string='Nominal', tracking=3, required=True) bank_name = fields.Char(string='Bank', tracking=3, required=True) account_name = fields.Char(string='Nama Account', tracking=3, required=True) bank_account = fields.Char(string='No. Rekening', tracking=3, required=True) detail_note = fields.Text(string='Keterangan Penggunaan Rinci', tracking=3) status = fields.Selection([ ('draft', 'Draft'), ('pengajuan1', 'Menunggu Approval Departement'), ('pengajuan2', 'Menunggu Pengecekan AP'), ('pengajuan3', 'Menunggu Approval Pimpinan'), ('approved', 'Approved'), ('reject', 'Rejected') ], string='Status', default='draft', tracking=3, index=True, track_visibility='onchange') last_status = fields.Selection([ ('draft', 'Draft'), ('pengajuan1', 'Menunggu Approval Departement'), ('pengajuan2', 'Menunggu Pengecekan AP'), ('pengajuan3', 'Menunggu Approval Pimpinan'), ('approved', 'Approved'), ('reject', 'Rejected') ], string='Status') status_pay_down_payment = fields.Selection([ ('pending', 'Pending'), ('payment', 'Payment'), ], string='Status Pembayaran', default='pending', tracking=3) departement_type = fields.Selection([ ('sales', 'Sales'), ('merchandiser', 'Merchandiser'), ('marketing', 'Marketing'), ('logistic', 'Logistic'), ('procurement', 'Procurement'), ('fat', 'FAT'), ('hr_ga', 'HR & GA'), ], string='Departement Type', tracking=3, required=True) # Sales & MD : Darren ID 19 # Marketing : Iwan ID 216 # Logistic & Procurement : Rafly H ID 21 # FAT : Stephan ID 28 # HR & GA : Akbar ID 7 / Pimpinan # --------------------------------------- # AP : Manzila (Finance) ID 23 def _get_departement_approver(self): mapping = { 'sales': 19, 'merchandiser': 19, 'marketing': 216, 'logistic': 21, 'procurement': 21, 'fat': 28, 'hr_ga': 7, } return mapping.get(self.departement_type) def action_realisasi_pum(self): return { 'type': 'ir.actions.act_window', 'name': 'Realisasi PUM', 'res_model': 'realization.down.payment', 'view_mode': 'form', 'target': 'current', 'context': { 'default_pum_id': self.id, 'default_value_down_payment': self.nominal, } } def action_confirm_payment(self): # Logic untuk konfirmasi pembayaran return def action_approval_check(self): for record in self: # user = record.user_id user = self.env['res.users'].browse(3401) roles = sorted(set( f"{group.name} (Category: {group.category_id.name})" for group in user.groups_id if group.category_id.name == 'Roles' )) _logger.info(f"[ROLE CHECK] User: {user.name} (Login: {user.login}) Roles: {roles}") return def action_reject(self): # Logic untuk konfirmasi pembayaran return def action_draft(self): for record in self: record.status = record.last_status if record.last_status else 'draft' return @api.model def create(self, vals): if not vals.get('number') or vals['number'] == 'New Draft': vals['number'] = self.env['ir.sequence'].next_by_code('down.payment') or 'New Draft' return super(DownPayment, self).create(vals) class RealizationDownPaymentLine(models.Model): _name = 'realization.down.payment.line' _description = 'Rincian Pemberian PUM' realization_id = fields.Many2one('realization.down.payment', string='Realization') date = fields.Date(string='Tanggal', required=True, default=fields.Date.today) description = fields.Char(string='Description', required=True) value = fields.Float(string='Nilai', required=True) class RealizationDownPaymentUseLine(models.Model): _name = 'realization.down.payment.use.line' _description = 'Rincian Penggunaan PUM' realization_id = fields.Many2one('realization.down.payment', string='Realization') date = fields.Date(string='Tanggal', required=True, default=fields.Date.today) description = fields.Char(string='Description', required=True) nominal = fields.Float(string='Nominal', required=True) attachment = fields.Boolean(string='Lampiran', default=False) class RealizationDownPayment(models.Model): _name = 'realization.down.payment' _description = 'Realization Down Payment Management' _inherit = ['mail.thread'] pum_id = fields.Many2one('down.payment', string='No PUM') title = fields.Char(string='Judul', tracking=3) goals = fields.Text(string='Tujuan', tracking=3) related = fields.Char(string='Terkait', tracking=3,) pemberian_line_ids = fields.One2many( 'realization.down.payment.line', 'realization_id', string='Rincian Pemberian' ) penggunaan_line_ids = fields.One2many( 'realization.down.payment.use.line', 'realization_id', string='Rincian Penggunaan' ) grand_total = fields.Float(string='Grand Total Pemberian', tracking=3, compute='_compute_grand_total') grand_total_use = fields.Float(string='Grand Total Penggunaan', tracking=3, compute='_compute_grand_total_use') value_down_payment = fields.Float(string='PUM', tracking=3) remaining_value = fields.Float(string='Sisa Uang PUM', tracking=3, compute='_compute_remaining_value') note_approval = fields.Text(string='Note Persetujuan', tracking=3) currency_id = fields.Many2one( 'res.currency', string='Currency', default=lambda self: self.env.company.currency_id ) @api.depends('pemberian_line_ids.value') def _compute_grand_total(self): for rec in self: rec.grand_total = sum(line.value for line in rec.pemberian_line_ids) @api.depends('penggunaan_line_ids.nominal') def _compute_grand_total_use(self): for rec in self: rec.grand_total_use = sum(line.nominal for line in rec.penggunaan_line_ids) @api.depends('grand_total', 'grand_total_use') def _compute_remaining_value(self): for rec in self: rec.remaining_value = rec.value_down_payment - rec.grand_total_use