From 73b7658b46f62518274fec1fb1291d5a88a5ed5a Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 27 Oct 2025 15:41:09 +0700 Subject: (andri) final --- indoteknik_custom/__manifest__.py | 1 + .../models/advance_payment_request.py | 121 +++++++++++++-------- .../views/advance_payment_request.xml | 17 +-- .../views/advance_payment_settlement.xml | 4 +- indoteknik_custom/views/mail_template_pum.xml | 20 ++-- 5 files changed, 99 insertions(+), 64 deletions(-) diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index fe770b4c..7a179ce3 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -186,6 +186,7 @@ 'views/unpaid_invoice_view.xml', 'views/letter_receivable.xml', 'views/letter_receivable_mail_template.xml', + 'views/mail_template_pum.xml', # 'views/reimburse.xml', 'views/sj_tele.xml', 'views/close_tempo_mail_template.xml', diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index a2c39b52..06fb7917 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -15,6 +15,7 @@ class AdvancePaymentRequest(models.Model): _description = 'Advance Payment Request or Reimburse' _rec_name = 'number' _inherit = ['mail.thread', 'mail.activity.mixin'] + _order = 'create_date desc' user_id = fields.Many2one('res.users', string='Diajukan Oleh', default=lambda self: self.env.user, tracking=3) partner_id = fields.Many2one('res.partner', string='Partner', related='user_id.partner_id', readonly=True) @@ -233,49 +234,78 @@ class AdvancePaymentRequest(models.Model): # def action_send_pum_reminder(self): # """ # Kirim email reminder PUM otomatis. - # - Hari ini = kirim dengan template 'mail_template_pum_reminder_today' - # - H-2 dari due date = kirim dengan template 'mail_template_pum_reminder_h_2' + # - PUM Perjalanan: + # - Hari H kembali ke kantor = template 'mail_template_pum_reminder_today' + # - H-2 dari due date = template 'mail_template_pum_reminder_h_2' + # - PUM Non-Perjalanan: + # - H-2 dari due date = template 'mail_template_pum_reminder_h_2' # """ # today = date.today() + + # # Penyesuaian 1: Cari semua PUM yang sudah disetujui (bukan draft/reject) + # # Kita tidak filter 'date_back_to_office' di sini lagi. # pum_ids = self.search([ - # ('date_back_to_office', '!=', False), # ('status', 'not in', ['draft', 'reject']), + # ('type_request', '=', 'pum') # ]) # template_today = self.env.ref('indoteknik_custom.mail_template_pum_reminder_today', raise_if_not_found=False) # template_h2 = self.env.ref('indoteknik_custom.mail_template_pum_reminder_h_2', raise_if_not_found=False) # if not template_today or not template_h2: - # _logger.warning("Salah satu template email tidak ditemukan.") + # _logger.warning("Salah satu template email PUM (today/h2) tidak ditemukan.") # return # for pum in pum_ids: # _logger.info(f"[REMINDER] Memproses PUM {pum.number}") + # # Penyesuaian 2: Logika ini sudah benar (sesuai update kita sebelumnya) + # # Jika realisasi sudah dibuat, PUM tidak aktif lagi, lewati. + # realization = self.env['advance.payment.settlement'].search([('pum_id', '=', pum.id)], limit=1) + # if realization: + # _logger.info(f"[REMINDER] Lewati PUM {pum.number}, realisasi sudah dibuat.") + # continue + # if not pum.email_ap or not pum.user_id.partner_id.email: # _logger.warning(f"[REMINDER] Lewati PUM {pum.number} karena email_ap atau email user kosong.") # continue - # due_date = pum.date_back_to_office + timedelta(days=7) + # # Penyesuaian 3: Logika penentuan Due Date (Wajib) + # due_date = False + # base_date_for_today_check = False # Khusus PUM Perjalanan + + # if pum.apr_perjalanan: + # if pum.date_back_to_office: + # due_date = pum.date_back_to_office + timedelta(days=7) + # base_date_for_today_check = pum.date_back_to_office + # else: + # _logger.warning(f"[REMINDER] Lewati PUM {pum.number} (perjalanan) karena tgl kembali kosong.") + # continue + # else: + # # Ini adalah PUM Non-Perjalanan + # if not pum.create_date: + # _logger.warning(f"[REMINDER] Lewati PUM {pum.number} (non-perjalanan) karena create_date kosong.") + # continue + # base_date = pum.create_date.date() + # due_date = base_date + timedelta(days=7) + + # # Hitung sisa hari # days_remaining = (due_date - today).days - # # --- PENYESUAIAN LOGIKA --- - # # Jika realisasi sudah dibuat (apapun status realisasinya), lewati. - # realization = self.env['advance.payment.settlement'].search([('pum_id', '=', pum.id)], limit=1) - # if realization: - # _logger.info(f"[REMINDER] Lewati PUM {pum.number}, realisasi sudah dibuat.") - # continue - # # --- BATAS PENYESUAIAN --- - - # # Tentukan template - # if pum.date_back_to_office == today: + # # Penyesuaian 4: Tentukan template berdasarkan sisa hari + # template = False + # if pum.apr_perjalanan and base_date_for_today_check == today: + # # Hari H kembali ke kantor (HANYA PUM Perjalanan) # template = template_today # elif days_remaining == 2: + # # H-2 due date (Untuk SEMUA jenis PUM) # template = template_h2 # else: - # _logger.info(f"[REMINDER] Lewati PUM {pum.number}, hari ini bukan tanggal pengingat.") + # _logger.info(f"[REMINDER] Lewati PUM {pum.number}, hari ini bukan tgl pengingat (Sisa hari: {days_remaining}).") # continue + # # --- Sisanya (Generate attachment & kirim email) sudah aman --- + # # Generate attachment # try: # attachment_vals = pum._get_jasper_attachment() @@ -293,16 +323,16 @@ class AdvancePaymentRequest(models.Model): # email_values = { # # 'email_to': pum.user_id.partner_id.email, - # 'email_to': 'andrifebriyadiputra@gmail.com', + # 'email_to': 'andrifebriyadiputra@gmail.com', # Masih hardcode # 'email_from': pum.email_ap, - # 'attachment_ids': [(6, 0, [attachment.id])], + # 'email_from': 'finance@indoteknik.co.id', + # 'attachment_ids': [(6, 0, [attachment.id])] # } # _logger.info(f"[REMINDER] Mengirim email PUM {pum.number} ke {email_values['email_to']} dari {email_values['email_from']}") # try: # body_html = template._render_field('body_html', [pum.id])[pum.id] - # template.send_mail(pum.id, force_send=True, email_values=email_values) # _logger.info(f"[REMINDER] Email berhasil dikirim untuk PUM {pum.number}") @@ -338,9 +368,9 @@ class AdvancePaymentRequest(models.Model): def action_view_journal_uangmuka(self): self.ensure_one() - # ap_user_ids = [23, 9468] - # if self.env.user.id not in ap_user_ids: - # raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') + ap_user_ids = [23, 9468] + if self.env.user.id not in ap_user_ids: + raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') if not self.move_id: raise UserError("Journal Uang Muka belum tersedia.") @@ -460,12 +490,12 @@ class AdvancePaymentRequest(models.Model): def action_confirm_payment(self): - jakarta_tz = pytz.timezone('Asia/Jakarta') - now = datetime.now(jakarta_tz).replace(tzinfo=None) + # jakarta_tz = pytz.timezone('Asia/Jakarta') + # now = datetime.now(jakarta_tz).replace(tzinfo=None) - # ap_user_ids = [23, 9468] - # if self.env.user.id not in ap_user_ids: - # raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') + ap_user_ids = [23, 9468] + if self.env.user.id not in ap_user_ids: + raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') for rec in self: if not rec.attachment_file_image and not rec.attachment_file_pdf: @@ -475,10 +505,10 @@ class AdvancePaymentRequest(models.Model): ) rec.status_pay_down_payment = 'payment' - rec.upload_attachment_date = now + rec.upload_attachment_date = datetime.utcnow() rec.message_post( - body="Status pembayaran telah dikonfirmasi oleh AP.", + body="Bukti transfer telah di upload oleh Finance AP.", message_type="comment", subtype_xmlid="mail.mt_note", ) @@ -538,9 +568,9 @@ class AdvancePaymentRequest(models.Model): ) elif rec.status == 'pengajuan2': - # ap_user_ids = [23, 9468] # List user ID yang boleh approve sebagai Finance AP - # if self.env.user.id not in ap_user_ids: - # raise UserError("Hanya AP yang berhak menyetujui tahap ini.") + ap_user_ids = [23, 9468] # List user ID yang boleh approve sebagai Finance AP + if self.env.user.id not in ap_user_ids: + raise UserError("Hanya AP yang berhak menyetujui tahap ini.") rec.name_approval_ap = self.env.user.name rec.approved_by = (rec.approved_by + ', ' if rec.approved_by else '') + rec.name_approval_ap rec.email_ap = self.env.user.email @@ -580,9 +610,9 @@ class AdvancePaymentRequest(models.Model): def action_ap_only(self): self.ensure_one() - # ap_user_ids = [23, 9468] # Ganti sesuai kebutuhan - # if self.env.user.id not in ap_user_ids: - # raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') + ap_user_ids = [23, 9468] # Ganti sesuai kebutuhan + if self.env.user.id not in ap_user_ids: + raise UserError('Hanya User AP yang dapat menggunakan fitur ini.') if self.move_id: raise UserError('CAB / Jurnal sudah pernah dibuat untuk PUM ini.') @@ -604,7 +634,7 @@ class AdvancePaymentRequest(models.Model): def _compute_days_remaining(self): today = date.today() for rec in self: - if rec.status in ['approved', 'reject'] and rec.days_remaining: + if rec.status in ['approved'] and rec.days_remaining: continue if rec.apr_perjalanan: @@ -767,7 +797,7 @@ class AdvancePaymentUsageLine(models.Model): realization_id = fields.Many2one('advance.payment.settlement', string='Realization') date = fields.Date(string='Tanggal', required=True, default=fields.Date.today) - description = fields.Char(string='Description', required=True) + description = fields.Text(string='Description', required=True) nominal = fields.Float(string='Nominal', required=True) done_attachment = fields.Boolean(string='Checked', default=False) @@ -788,7 +818,7 @@ class AdvancePaymentUsageLine(models.Model): attachment_filename_pdf = fields.Char(string='Filename PDF') account_id = fields.Many2one( - 'account.account', string='Jenis Biaya', + 'account.account', string='Jenis Biaya', tracking=3, domain="[('id', 'in', [484, 486, 488, 506, 507, 625, 471, 519, 527, 528, 529, 530, 565])]" # ID Jenis Biaya yang dibutuhkan ) @@ -803,11 +833,11 @@ class AdvancePaymentUsageLine(models.Model): for line in self: line.is_current_user_ap = is_ap - @api.onchange('account_id') - def _onchange_account_id(self): - for rec in self: - if rec.account_id: - rec.description = rec.account_id.name + " - " + # @api.onchange('account_id') + # def _onchange_account_id(self): + # for rec in self: + # if rec.account_id: + # rec.description = rec.account_id.name + " - " @api.onchange('attachment_type') def _onchange_attachment_type(self): @@ -851,10 +881,10 @@ class ReimburseLine(models.Model): date = fields.Date(string='Tanggal', required=True, default=fields.Date.today) account_id = fields.Many2one( 'account.account', - string='Jenis Biaya', + string='Jenis Biaya', tracking=3, domain="[('id', 'in', [484, 486, 527, 529, 530, 471, 473, 492, 493, 488, 625, 528, 533, 534])]" ) - description = fields.Char(string='Description', required=True, tracking=3) + description = fields.Text(string='Description', required=True, tracking=3) distance_departure = fields.Float(string='Pergi (Km)', tracking=3) distance_return = fields.Float(string='Pulang (Km)', tracking=3) quantity = fields.Float(string='Quantity', tracking=3) @@ -926,6 +956,7 @@ class AdvancePaymentSettlement(models.Model): _description = 'Advance Payment Settlement' _inherit = ['mail.thread'] _rec_name = 'name' + _order = 'create_date desc' pum_id = fields.Many2one('advance.payment.request', string='No PUM', ondelete='cascade') name = fields.Char(string='Nama', readonly=True, tracking=3) diff --git a/indoteknik_custom/views/advance_payment_request.xml b/indoteknik_custom/views/advance_payment_request.xml index 6a0d61b1..c33a2843 100644 --- a/indoteknik_custom/views/advance_payment_request.xml +++ b/indoteknik_custom/views/advance_payment_request.xml @@ -10,7 +10,10 @@ type="object" string="Realisasi" class="btn-primary" - attrs="{'invisible': ['|', ('status', '!=', 'approved'), ('has_settlement', '=', True)]}"/> + attrs="{'invisible': ['|', + ('status', '!=', 'approved'), + '|', ('type_request', '!=', 'pum'), + ('has_settlement', '=', True)]}"/>