From 7456c70b70749acbbe3f6545ee911a754a59f89b Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Thu, 19 Feb 2026 10:28:45 +0700 Subject: (andri) add estimate biaya pum --- .../models/advance_payment_request.py | 34 +++++++++++++++++++++- indoteknik_custom/security/ir.model.access.csv | 1 + .../views/advance_payment_request.xml | 24 +++++++++++++-- .../views/advance_payment_settlement.xml | 11 +++++++ 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index 8cadb1b6..18953c7c 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -155,6 +155,16 @@ class AdvancePaymentRequest(models.Model): compute='_compute_is_current_user_ap' ) + estimate_line_ids = fields.One2many('advance.payment.request.estimate.line', 'request_id', string='Rincian Estimasi') + + @api.constrains('nominal', 'estimate_line_ids') + def _check_nominal_vs_estimate_total(self): + for rec in self: + if rec.type_request == 'pum' and rec.estimate_line_ids: + total_estimate = sum(line.nominal for line in rec.estimate_line_ids) + if round(total_estimate, 2) != round(rec.nominal, 2): + raise UserError("Total estimasi harus sama dengan nominal PUM. Silakan sesuaikan rincian estimasi atau nominal PUM.") + @api.onchange('grand_total_reimburse', 'type_request') def _onchange_reimburse_line_update_nominal(self): if self.type_request == 'reimburse': @@ -1144,6 +1154,11 @@ class AdvancePaymentSettlement(models.Model): string="Is Current User AP", compute='_compute_is_current_user_ap' ) + pum_estimate_line_ids = fields.One2many( + related='pum_id.estimate_line_ids', + string='Rincian Estimasi PUM', + readonly=True + ) def _compute_is_current_user_ap(self): ap_user_ids = [23, 9468, 16729] @@ -1612,4 +1627,21 @@ class CreateReimburseCabWizard(models.TransientModel): 'type': 'ir.actions.act_window', 'res_id': move.id, 'target': 'current', - } \ No newline at end of file + } + +class AdvancePaymentRequestEstimateLine(models.Model): + _name = 'advance.payment.request.estimate.line' + _description = 'Advance Payment Request Estimate Line' + + request_id = fields.Many2one('advance.payment.request', string='Request') + category_estimate = fields.Selection([ + ('parkir', 'Parkir'), + ('tol', 'Tol'), + ('bbm', 'BBM'), + ('kuli', 'Kuli'), + ('konsumsi', 'Konsumsi'), + ('lain_lain', 'Lain-lain'), + ], string='Kategori Estimasi', required=True) + description = fields.Text(string='keTambahan', help='Deskripsi tambahan untuk estimasi, misalnya tujuan parkir atau rute tol.') + nominal = fields.Float(string='Nominal Estimasi', required=True, help='Masukkan nominal estimasi untuk kategori ini (tidak mesti akurat, hanya untuk gambaran umum).') + currency_id = fields.Many2one(related='request_id.currency_id') diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index bc290370..1294970c 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -200,6 +200,7 @@ access_advance_payment_usage_line,access.advance.payment.usage.line,model_advanc access_advance_payment_create_bill,access.advance.payment.create.bill,model_advance_payment_create_bill,,1,1,1,1 access_create_reimburse_cab_wizard_user,create.reimburse.cab.wizard user,model_create_reimburse_cab_wizard,,1,1,1,1 access_advance_payment_cancel_wizard,advance.payment.cancel.wizard,model_advance_payment_cancel_wizard,,1,1,1,1 +access_advance_payment_request_estimate_line,advance.payment.request.estimate.line,model_advance_payment_request_estimate_line,,1,1,1,1 access_purchasing_job_seen,purchasing.job.seen,model_purchasing_job_seen,,1,1,1,1 access_tukar_guling_all_users,tukar.guling.all.users,model_tukar_guling,base.group_user,1,1,1,1 diff --git a/indoteknik_custom/views/advance_payment_request.xml b/indoteknik_custom/views/advance_payment_request.xml index 340e0caf..4faf905e 100644 --- a/indoteknik_custom/views/advance_payment_request.xml +++ b/indoteknik_custom/views/advance_payment_request.xml @@ -134,8 +134,28 @@
- - + + +

*Masukkan estimasi alokasi biaya sebagai gambaran rencana penggunaan dana, tidak harus diisi dengan nominal yang akurat

+ + + + + + + +
+ + + + + + + +
+
+
+ diff --git a/indoteknik_custom/views/advance_payment_settlement.xml b/indoteknik_custom/views/advance_payment_settlement.xml index a8bf1de7..258f469f 100644 --- a/indoteknik_custom/views/advance_payment_settlement.xml +++ b/indoteknik_custom/views/advance_payment_settlement.xml @@ -124,6 +124,17 @@ + +

*Rincian estimasi PUM ini hanya sebagai gambaran umum untuk realisasi yang dilakukan, tidak harus diisi dengan nominal yang akurat.

+ + + + + + + + +
-- cgit v1.2.3 From 10525d407bbc34d79146ff22955a874509f5b204 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Thu, 19 Feb 2026 15:55:27 +0700 Subject: (andri) compute estimate dengan realisasi --- .../models/advance_payment_request.py | 60 +++++++++++++++++++++- .../views/advance_payment_settlement.xml | 3 ++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index 18953c7c..ac9d7c2d 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -921,6 +921,35 @@ class AdvancePaymentUsageLine(models.Model): compute='_compute_is_current_user_ap' ) + category_usage = fields.Selection([ + ('parkir', 'Parkir'), + ('tol', 'Tol'), + ('bbm', 'BBM'), + ('kuli', 'Kuli'), + ('konsumsi', 'Konsumsi'), + ('lain_lain', 'Lain-lain'), + ], string='Kategori System', compute='_compute_category_usage') + + @api.depends('account_id') + def _compute_category_usage(self): + for rec in self: + if not rec.account_id: + rec.category_usage = False + continue + name = rec.account_id.name.lower() + if 'bbm' in name or 'bahan bakar' in name: + rec.category_usage = 'bbm' + elif 'tol' in name: + rec.category_usage = 'tol' + elif 'parkir' in name: + rec.category_usage = 'parkir' + elif 'kuli' in name or 'bongkar' in name: + rec.category_usage = 'kuli' + elif 'konsumsi' in name or 'makan' in name or 'minum' in name: + rec.category_usage = 'konsumsi' + else: + rec.category_usage = 'lain_lain' + def _compute_is_current_user_ap(self): ap_user_ids = [23, 9468, 16729] is_ap = self.env.user.id in ap_user_ids @@ -1642,6 +1671,35 @@ class AdvancePaymentRequestEstimateLine(models.Model): ('konsumsi', 'Konsumsi'), ('lain_lain', 'Lain-lain'), ], string='Kategori Estimasi', required=True) - description = fields.Text(string='keTambahan', help='Deskripsi tambahan untuk estimasi, misalnya tujuan parkir atau rute tol.') + description = fields.Text(string='Description', help='Deskripsi tambahan untuk estimasi biaya yang diperlukan.') nominal = fields.Float(string='Nominal Estimasi', required=True, help='Masukkan nominal estimasi untuk kategori ini (tidak mesti akurat, hanya untuk gambaran umum).') currency_id = fields.Many2one(related='request_id.currency_id') + + total_actual = fields.Float(string='Nominal Realisasi', compute='_compute_actual_data') + frequency = fields.Integer(string='Qty Realisasi', compute='_compute_actual_data') + + @api.depends('request_id.settlement_ids.penggunaan_line_ids.nominal', + 'request_id.settlement_ids.penggunaan_line_ids.account_id') + def _compute_actual_data(self): + for rec in self: + total_act = 0 + freq = 0 + if rec.request_id and rec.request_id.settlement_ids: + all_usage_lines = rec.request_id.settlement_ids.mapped('penggunaan_line_ids') + valid_lines = all_usage_lines.filtered(lambda l: l.account_id and l.category_usage) + planned_category = rec.request_id.estimate_line_ids.mapped('category_estimate') + if rec.category_estimate == 'lain_lain': + matched_lines = valid_lines.filtered( + lambda l: l.category_usage == 'lain_lain' or \ + l.category_usage not in planned_category + ) + else: + matched_lines = valid_lines.filtered( + lambda l: l.category_usage == rec.category_estimate + ) + + total_act = sum(matched_lines.mapped('nominal')) + freq = len(matched_lines) + rec.total_actual = total_act + rec.frequency = freq + diff --git a/indoteknik_custom/views/advance_payment_settlement.xml b/indoteknik_custom/views/advance_payment_settlement.xml index 258f469f..352c5b96 100644 --- a/indoteknik_custom/views/advance_payment_settlement.xml +++ b/indoteknik_custom/views/advance_payment_settlement.xml @@ -118,6 +118,7 @@ + @@ -131,6 +132,8 @@ + + -- cgit v1.2.3 From a3dc6bc79215e6223c801f49d1997292b8f4c317 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Fri, 20 Feb 2026 15:36:56 +0700 Subject: (andri) fix --- indoteknik_custom/models/advance_payment_request.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index ac9d7c2d..039d18a5 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -160,7 +160,9 @@ class AdvancePaymentRequest(models.Model): @api.constrains('nominal', 'estimate_line_ids') def _check_nominal_vs_estimate_total(self): for rec in self: - if rec.type_request == 'pum' and rec.estimate_line_ids: + if rec.type_request == 'pum': + if not rec.estimate_line_ids: + raise UserError("Rincian estimasi wajib diisi untuk PUM. Silakan tambahkan rincian estimasi.") total_estimate = sum(line.nominal for line in rec.estimate_line_ids) if round(total_estimate, 2) != round(rec.nominal, 2): raise UserError("Total estimasi harus sama dengan nominal PUM. Silakan sesuaikan rincian estimasi atau nominal PUM.") @@ -761,7 +763,7 @@ class AdvancePaymentRequest(models.Model): pum_ids = self.search([ ('user_id', '=', user.id), - ('status', '!=', 'reject'), + ('status', '!=', 'cancel'), ('type_request', '=', 'pum') ]) -- cgit v1.2.3