diff options
| author | FIN-IT_AndriFP <it@fixcomart.co.id> | 2025-10-23 14:57:04 +0700 |
|---|---|---|
| committer | FIN-IT_AndriFP <it@fixcomart.co.id> | 2025-10-23 14:57:04 +0700 |
| commit | a94708b3f16d6d1bfe5db971904a0b1d31f74bcd (patch) | |
| tree | 7bc15743ee29830cfdd67a1d0aa28393f97cb454 | |
| parent | 310f92c9b825a458618daa3b00581b790f8e009e (diff) | |
(andri) del done not realized
| -rw-r--r-- | indoteknik_custom/models/advance_payment_request.py | 319 | ||||
| -rw-r--r-- | indoteknik_custom/views/advance_payment_settlement.xml | 21 |
2 files changed, 184 insertions, 156 deletions
diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index b333fcc4..4e0e481b 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -87,6 +87,7 @@ class AdvancePaymentRequest(models.Model): ('fat', 'FAT'), ('it', 'IT'), ('hr_ga', 'HR & GA'), + ('pimpinan', 'Pimpinan') ], string='Departement Type', tracking=3, required=True) attachment_file_image = fields.Binary(string='Attachment Image', attachment_filename='attachment_filename_image') @@ -228,100 +229,103 @@ class AdvancePaymentRequest(models.Model): 'filename': filename, } - 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' - """ - today = date.today() - pum_ids = self.search([ - ('date_back_to_office', '!=', False), - ('status', 'not in', ['draft', 'reject']), - ]) - - 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.") - return - - for pum in pum_ids: - _logger.info(f"[REMINDER] Memproses PUM {pum.number}") - - 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) - days_remaining = (due_date - today).days - - realization = self.env['advance.payment.settlement'].search([('pum_id', '=', pum.id)], limit=1) - if not realization or realization.done_status != 'remaining': - _logger.info(f"[REMINDER] Lewati PUM {pum.number}, status realisasi bukan 'remaining'.") - continue - - # Tentukan template - if pum.date_back_to_office == today: - template = template_today - elif days_remaining == 2: - template = template_h2 - else: - _logger.info(f"[REMINDER] Lewati PUM {pum.number}, hari ini bukan tanggal pengingat.") - continue - - # Generate attachment - try: - attachment_vals = pum._get_jasper_attachment() - attachment = self.env['ir.attachment'].create({ - 'name': attachment_vals['name'], - 'type': 'binary', - 'datas': attachment_vals['datas'], - 'res_model': 'advance.payment.request', - 'res_id': pum.id, - 'mimetype': 'application/pdf', - }) - except Exception as e: - _logger.error(f"[REMINDER] Gagal membuat attachment untuk PUM {pum.number}: {str(e)}") - continue - - email_values = { - # 'email_to': pum.user_id.partner_id.email, - 'email_to': 'andrifebriyadiputra@gmail.com', - 'email_from': pum.email_ap, - '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}") - - # Post info sederhana - pum.message_post( - body="Email Reminder Berhasil dikirimkan", - message_type="comment", - subtype_xmlid="mail.mt_note", - ) - - user_system = self.env['res.users'].browse(25) - system_id = user_system.partner_id.id if user_system else False - - # Post isi email ke chatter - pum.message_post( - body=body_html, - message_type="comment", - subtype_xmlid="mail.mt_note", - author_id=system_id, - ) - except Exception as e: - _logger.error(f"[REMINDER] Gagal mengirim email untuk PUM {pum.number}: {str(e)}") - - return True + # 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' + # """ + # today = date.today() + # pum_ids = self.search([ + # ('date_back_to_office', '!=', False), + # ('status', 'not in', ['draft', 'reject']), + # ]) + + # 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.") + # return + + # for pum in pum_ids: + # _logger.info(f"[REMINDER] Memproses PUM {pum.number}") + + # 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) + # 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: + # template = template_today + # elif days_remaining == 2: + # template = template_h2 + # else: + # _logger.info(f"[REMINDER] Lewati PUM {pum.number}, hari ini bukan tanggal pengingat.") + # continue + + # # Generate attachment + # try: + # attachment_vals = pum._get_jasper_attachment() + # attachment = self.env['ir.attachment'].create({ + # 'name': attachment_vals['name'], + # 'type': 'binary', + # 'datas': attachment_vals['datas'], + # 'res_model': 'advance.payment.request', + # 'res_id': pum.id, + # 'mimetype': 'application/pdf', + # }) + # except Exception as e: + # _logger.error(f"[REMINDER] Gagal membuat attachment untuk PUM {pum.number}: {str(e)}") + # continue + + # email_values = { + # # 'email_to': pum.user_id.partner_id.email, + # 'email_to': 'andrifebriyadiputra@gmail.com', + # 'email_from': pum.email_ap, + # '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}") + + # # Post info sederhana + # pum.message_post( + # body="Email Reminder Berhasil dikirimkan", + # message_type="comment", + # subtype_xmlid="mail.mt_note", + # ) + + # user_system = self.env['res.users'].browse(25) + # system_id = user_system.partner_id.id if user_system else False + + # # Post isi email ke chatter + # pum.message_post( + # body=body_html, + # message_type="comment", + # subtype_xmlid="mail.mt_note", + # author_id=system_id, + # ) + # except Exception as e: + # _logger.error(f"[REMINDER] Gagal mengirim email untuk PUM {pum.number}: {str(e)}") + + # return True @api.depends('move_id.state') @@ -521,6 +525,7 @@ class AdvancePaymentRequest(models.Model): 'fat': 'Finance & Accounting Manager', 'it': 'IT Manager', 'hr_ga': 'HR & GA Manager', + 'pimpinan': 'Pimpinan', } rec.position_department = department_titles.get(rec.departement_type, 'Departement Manager') @@ -547,7 +552,7 @@ class AdvancePaymentRequest(models.Model): rec.message_post( body=f"Approval <b>AP</b> oleh <b>{self.env.user.name}</b> " - f"pada <i>{formatted_date}</i>." + f"pada <i>{formatted_date}</i>." ) elif rec.status == 'pengajuan3': @@ -561,7 +566,7 @@ class AdvancePaymentRequest(models.Model): rec.message_post( body=f"Approval <b>Pimpinan</b> oleh <b>{self.env.user.name}</b> " - f"pada <i>{formatted_date}</i>." + f"pada <i>{formatted_date}</i>." ) else: @@ -654,7 +659,7 @@ class AdvancePaymentRequest(models.Model): active_pum_count = 0 for pum in pum_ids: realization = self.env['advance.payment.settlement'].search([('pum_id', '=', pum.id)], limit=1) - if not realization or realization.done_status != 'done_not_realized': + if not realization: active_pum_count += 1 if active_pum_count >= 2: @@ -692,7 +697,7 @@ class AdvancePaymentRequest(models.Model): active_pum_count = 0 for pum in pum_ids: realization = self.env['advance.payment.settlement'].search([('pum_id', '=', pum.id)], limit=1) - if not realization or realization.done_status != 'done_not_realized': + if not realization: active_pum_count += 1 if active_pum_count >= 2 and vals.get('type_request') == 'pum': @@ -706,25 +711,45 @@ class AdvancePaymentRequest(models.Model): initial_status = '' position = vals.get('position_type') - if position == 'staff': - initial_status = 'pengajuan1' - elif position == 'manager': + department = vals.get('departement_type') + if department == 'hr_ga' or position in ('manager', 'pimpinan'): initial_status = 'pengajuan2' + else: + initial_status = 'pengajuan1' + + vals['status'] = initial_status + + if initial_status == 'pengajuan2' and department != 'hr_ga': applicant_name = vals.get('applicant_name') vals['name_approval_departement'] = self.env['res.users'].browse(applicant_name).name or '' vals['date_approved_department'] = now department_type = vals.get('departement_type') department_titles = self._get_department_titles_mapping() vals['position_department'] = department_titles.get(department_type, 'Departement Manager') - elif position == 'pimpinan': - initial_status = 'pengajuan2' - applicant_name = vals.get('applicant_name') - vals['name_approval_pimpinan'] = self.env['res.users'].browse(applicant_name).name or '' + + if position == 'pimpinan' and department != 'hr_ga': + vals['name_approval_pimpinan'] = self.env['res.users'].browse(vals.get('applicant_name')).name or '' vals['position_pimpinan'] = 'Pimpinan' vals['date_approved_pimpinan'] = now + # if position == 'staff': + # initial_status = 'pengajuan1' + # elif position == 'manager': + # initial_status = 'pengajuan2' + # applicant_name = vals.get('applicant_name') + # vals['name_approval_departement'] = self.env['res.users'].browse(applicant_name).name or '' + # vals['date_approved_department'] = now + # department_type = vals.get('departement_type') + # department_titles = self._get_department_titles_mapping() + # vals['position_department'] = department_titles.get(department_type, 'Departement Manager') + # elif position == 'pimpinan': + # initial_status = 'pengajuan2' + # applicant_name = vals.get('applicant_name') + # vals['name_approval_pimpinan'] = self.env['res.users'].browse(applicant_name).name or '' + # vals['position_pimpinan'] = 'Pimpinan' + # vals['date_approved_pimpinan'] = now + + # vals['status'] = initial_status - vals['status'] = initial_status - if not vals.get('number') or vals['number'] == 'New Draft': if vals.get('type_request') == 'reimburse': vals['number'] = self.env['ir.sequence'].next_by_code('reimburse.request') or 'New Draft' @@ -947,13 +972,14 @@ class AdvancePaymentSettlement(models.Model): ('approved', 'Approved'), ], string='Status', default='pengajuan1', tracking=3, index=True, track_visibility='onchange') - done_status = fields.Selection([ - ('remaining', 'Remaining'), - ('done_not_realized', 'Done Not Realized'), - ('done_realized', 'Done Realized') - ], string='Status Realisasi', tracking=3, default='remaining') - - date_done_not_realized = fields.Date(string='Tanggal Done Not Realized', tracking=3) + # --- DIHAPUS --- + # done_status = fields.Selection([ + # ('remaining', 'Remaining'), + # ('done_not_realized', 'Done Not Realized'), + # ('done_realized', 'Done Realized') + # ], string='Status Realisasi', tracking=3, default='remaining') + # date_done_not_realized = fields.Date(string='Tanggal Done Not Realized', tracking=3) + # --- BATAS DIHAPUS --- currency_id = fields.Many2one( 'res.currency', string='Currency', @@ -1076,24 +1102,26 @@ class AdvancePaymentSettlement(models.Model): rec.remaining_value = rec.nominal_pum - rec.grand_total_use return - def action_validation(self): - self.ensure_one() + # --- DIHAPUS --- + # def action_validation(self): + # self.ensure_one() - # Validasi hanya AP yang bisa validasi - 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 dapat melakukan validasi realisasi.') - - if self.done_status == 'remaining': - self.done_status = 'done_not_realized' - self.date_done_not_realized = fields.Date.today() - elif self.done_status == 'done_not_realized': - self.done_status = 'done_realized' - else: - raise UserError('Realisasi sudah berstatus Done Realized.') - - # Opsional: Tambah log di chatter - self.message_post(body=f"Status realisasi diperbarui menjadi <b>{dict(self._fields['done_status'].selection).get(self.done_status)}</b> oleh {self.env.user.name}.") + # # Validasi hanya AP yang bisa validasi + # 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 dapat melakukan validasi realisasi.') + + # if self.done_status == 'remaining': + # self.done_status = 'done_not_realized' + # self.date_done_not_realized = fields.Date.today() + # elif self.done_status == 'done_not_realized': + # self.done_status = 'done_realized' + # else: + # raise UserError('Realisasi sudah berstatus Done Realized.') + + # # Opsional: Tambah log di chatter + # self.message_post(body=f"Status realisasi diperbarui menjadi <b>{dict(self._fields['done_status'].selection).get(self.done_status)}</b> oleh {self.env.user.name}.") + # --- BATAS DIHAPUS --- def action_cab(self): self.ensure_one() @@ -1119,8 +1147,10 @@ class AdvancePaymentSettlement(models.Model): # Account Uang Muka Operasional account_uang_muka = 403 + # --- PENYESUAIAN LOGIKA --- # Tanggal pakai create_date atau hari ini - account_date = self.date_done_not_realized or fields.Date.today() + account_date = fields.Date.context_today(self) + # --- BATAS PENYESUAIAN --- ref_label = f"Realisasi {self.pum_id.number} Biaya {self.pum_id.detail_note} ({cab_move.name})" @@ -1209,6 +1239,7 @@ class AdvancePaymentSettlement(models.Model): 'fat': 'Finance & Accounting Manager', 'it': 'IT Manager', 'hr_ga': 'HR & GA Manager', + 'pimpinan': 'Pimpinan', } rec.position_department = department_titles.get(rec.pum_id.departement_type, 'Departement Manager') @@ -1242,7 +1273,9 @@ class AdvancePaymentSettlement(models.Model): rec.date_approved_pimpinan = now rec.position_pimpinan = 'Pimpinan' rec.status = 'approved' - rec.done_status = 'done_not_realized' # Set status done untuk realisasi + # --- DIHAPUS --- + # rec.done_status = 'done_not_realized' # Set status done untuk realisasi + # --- BATAS DIHAPUS --- rec.message_post( body=f"Approval <b>Pimpinan</b> oleh <b>{self.env.user.name}</b> " @@ -1266,15 +1299,24 @@ class AdvancePaymentSettlement(models.Model): @api.model def create(self, vals): jakarta_tz = pytz.timezone('Asia/Jakarta') + # --- PENYESUAIAN LOGIKA WAKTU --- now = datetime.now(jakarta_tz).replace(tzinfo=None) + # Gunakan fields.Datetime.now() agar konsisten + # now = fields.Datetime.now() + # --- BATAS PENYESUAIAN --- + pum_id = vals.get('pum_id') initial_status = '' if pum_id: pum_request = self.env['advance.payment.request'].browse(pum_id) if pum_request: - position_dari_pum = pum_request.position_type + position_dari_pum = pum_request.position_type + department_dari_pum = pum_request.departement_type if position_dari_pum == 'staff': - initial_status = 'pengajuan1' + if department_dari_pum == 'hr_ga': + initial_status = 'pengajuan2' + else: + initial_status = 'pengajuan1' elif position_dari_pum == 'manager': initial_status = 'pengajuan2' applicant_name_str = pum_request.applicant_name.name or '' @@ -1289,9 +1331,12 @@ class AdvancePaymentSettlement(models.Model): applicant_name_str = pum_request.applicant_name.name or '' vals['date_approved_pimpinan'] = now vals['name_approval_pimpinan'] = applicant_name_str - vals['position_department'] = 'Pimpinan' + vals['position_pimpinan'] = 'Pimpinan' + + # --- PENYESUAIAN LOGIKA: SET DEFAULT JIKA KOSONG --- + vals['status'] = initial_status or 'pengajuan1' + # --- BATAS PENYESUAIAN --- - vals['status'] = initial_status rec = super().create(vals) rec._check_remaining_value() return rec diff --git a/indoteknik_custom/views/advance_payment_settlement.xml b/indoteknik_custom/views/advance_payment_settlement.xml index 8c831be4..72af17d8 100644 --- a/indoteknik_custom/views/advance_payment_settlement.xml +++ b/indoteknik_custom/views/advance_payment_settlement.xml @@ -5,11 +5,6 @@ <field name="arch" type="xml"> <form string="Advance Payment Settlement"> <header> - <button name="action_validation" - type="object" - string="Validasi" - class="btn-info" - attrs="{'invisible': [('status', '!=', 'approved')]}"/> <button name="action_cab" type="object" class="btn-info" @@ -26,9 +21,6 @@ readonly="1"/> </header> <sheet> - <widget name="web_ribbon" title="Remaining" bg_color="bg-danger" attrs="{'invisible': [('done_status', '!=', 'remaining')]}"/> - <widget name="web_ribbon" title="Done Not Realized" bg_color="bg-warning" attrs="{'invisible': [('done_status', '!=', 'done_not_realized')]}"/> - <widget name="web_ribbon" title="Realized" attrs="{'invisible': [('done_status', '!=', 'done_realized')]}"/> <div class="oe_button_box" name="button_box"> <field name="is_cab_visible" invisible="1"/> <field name="is_current_user_ap" invisible="1"/> @@ -36,7 +28,7 @@ name="action_view_journal_uangmuka" class="oe_stat_button" icon="fa-book" - attrs="{'invisible': [('is_cab_visible', '=', False)], 'readonly': [('is_current_user_ap', '=', False)]}" + attrs="{'invisible': [('is_cab_visible', '=', False)], 'readonly': [('is_current_user_ap', '=', False)]}" style="width: 200px;"> <field name="move_id" widget="statinfo" string="Journal Entries"/> <span class="o_stat_text"> @@ -58,10 +50,6 @@ <field name="note_approval" required="1"/> <field name="lot_of_attachment"/> <field name="approved_by" readonly="1"/> - <field name="done_status" - decoration-success="done_status == 'done_realized'" - decoration-danger="done_status == 'remaining'" - widget="badge" readonly="1" invisible="1"/> <field name="applicant_name" readonly="1"/> <field name="user_id" readonly="1"/> </group> @@ -145,10 +133,8 @@ <group col="2"> <group class="oe_subtotal_footer oe_right"> <field name="currency_id" invisible="1"/> - <!-- <field name="grand_total" readonly="1" widget="monetary" options="{'currency_field': 'currency_id'}"/> --> <field name="grand_total_use" readonly="1" widget="monetary" options="{'currency_field': 'currency_id'}"/> <field name="nominal_pum" readonly="1" widget="monetary" options="{'currency_field': 'currency_id'}" style="font-weight: bold;"/> - <!-- <field name="value_down_payment" readonly="1" widget="monetary" options="{'currency_field': 'currency_id'}" style="font-weight: bold;"/> --> <field name="remaining_value" readonly="1" widget="monetary" options="{'currency_field': 'currency_id'}"/> </group> </group> @@ -178,10 +164,7 @@ <field name="grand_total_use" string="Total Realisasi"/> <field name="remaining_value" string="Sisa PUM"/> <field name="status" widget="badge" decoration-success="status == 'approved'"/> - <field name="done_status" widget="badge" - decoration-success="done_status == 'done_realized'" - decoration-danger="done_status == 'remaining'"/> - </tree> + </tree> </field> </record> |
