diff options
| author | FIN-IT_AndriFP <it@fixcomart.co.id> | 2025-10-02 14:04:56 +0700 |
|---|---|---|
| committer | FIN-IT_AndriFP <it@fixcomart.co.id> | 2025-10-02 14:04:56 +0700 |
| commit | 7d89516ce05d0ea67733c04436cc2de544189efe (patch) | |
| tree | 2521fbf09f4695253fd7db1ff7613b7f003f20ea /indoteknik_custom/models/account_move.py | |
| parent | 10da5e27e658030f171f694d6696f93e4a472447 (diff) | |
| parent | 875b20796c7fa64abebe430b2707df597e29836b (diff) | |
Merge branch 'pum-v2' of https://bitbucket.org/altafixco/indoteknik-addons into pum-v2
Diffstat (limited to 'indoteknik_custom/models/account_move.py')
| -rw-r--r-- | indoteknik_custom/models/account_move.py | 135 |
1 files changed, 88 insertions, 47 deletions
diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index c93cfb76..44b3cb76 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -99,12 +99,42 @@ class AccountMove(models.Model): reminder_sent_date = fields.Date(string="Tanggal Reminder Terkirim") + payment_difficulty = fields.Selection(string="Payment Difficulty", related='partner_id.payment_difficulty', readonly=True) + customer_promise_date = fields.Date( string="Janji Bayar", help="Tanggal janji bayar dari customer setelah reminder dikirim.", tracking=True ) + # def _check_and_lock_cbd(self): + # cbd_term = self.env['account.payment.term'].browse(26) + # today = date.today() + + # # Cari semua invoice overdue + # overdue_invoices = self.search([ + # ('move_type', '=', 'out_invoice'), + # ('state', '=', 'posted'), + # ('payment_state', 'not in', ['paid', 'in_payment', 'reversed']), + # ('invoice_date_due', '!=', False), + # ('invoice_date_due', '<=', today - timedelta(days=30)), + # ], limit=3) + + # _logger.info(f"Found {len(overdue_invoices)} overdue invoices for CBD lock check.") + # _logger.info(f"Overdue Invoices: {overdue_invoices.mapped('name')}") + + # # Ambil partner unik dari invoice + # partners_to_lock = overdue_invoices.mapped('partner_id').filtered(lambda p: not p.is_cbd_locked) + # _logger.info(f"Partners to lock: {partners_to_lock.mapped('name')}") + + # # Lock hanya partner yang belum locked + # if partners_to_lock: + # partners_to_lock.write({ + # 'is_cbd_locked': True, + # 'property_payment_term_id': cbd_term.id, + # }) + + def compute_partial_payment(self): for move in self: if move.amount_total_signed > 0 and move.amount_residual_signed > 0 and move.payment_state == 'partial': @@ -164,49 +194,56 @@ class AccountMove(models.Model): def send_due_invoice_reminder(self): today = fields.Date.today() target_dates = [ - today - timedelta(days=7), - today - timedelta(days=3), - today, - today + timedelta(days=3), today + timedelta(days=7), + today + timedelta(days=3), + today, ] - - for days_after_due in range(14, 181, 7): - target_dates.append(today - timedelta(days=days_after_due)) - invoices = self.env['account.move'].search([ ('move_type', '=', 'out_invoice'), ('state', '=', 'posted'), ('payment_state', 'not in', ['paid', 'in_payment', 'reversed']), ('invoice_date_due', 'in', target_dates), - ('date_terima_tukar_faktur', '!=', False) - ]) - _logger.info(f"Invoices: {invoices}") + ('date_terima_tukar_faktur', '!=', False), + ('invoice_payment_term_id.name', 'ilike', 'tempo')]) + _logger.info(f"Found {len(invoices)} invoices due for reminder {invoices}.") + if not invoices: + _logger.info("Tidak ada invoice yang due") + return - invoices = invoices.filtered( - lambda inv: inv.invoice_payment_term_id and 'tempo' in (inv.invoice_payment_term_id.name or '').lower() - ) - # _logger.info(f"Invoices tahap 2: {invoices}") + self._send_invoice_reminders(invoices, mode='due') + def send_overdue_invoice_reminder(self): + today = fields.Date.today() + invoices = self.env['account.move'].search([ + ('move_type', '=', 'out_invoice'), + ('state', '=', 'posted'), + ('payment_state', 'not in', ['paid', 'in_payment', 'reversed']), + ('invoice_date_due', '<', today), + ('date_terima_tukar_faktur', '!=', False), + ('invoice_payment_term_id.name', 'ilike', 'tempo')]) + _logger.info(f"Found {len(invoices)} invoices overdue for reminder {invoices}.") if not invoices: - _logger.info("Tidak ada invoice yang due") + _logger.info("Tidak ada invoice yang overdue") return + self._send_invoice_reminders(invoices, mode='overdue') + + def _send_invoice_reminders(self, invoices, mode): + today = fields.Date.today() + template = self.env.ref('indoteknik_custom.mail_template_invoice_due_reminder') invoice_group = {} for inv in invoices: dtd = (inv.invoice_date_due - today).days if inv.invoice_date_due else 0 - key = (inv.partner_id, dtd) + key = (inv.partner_id, dtd if mode == 'due' else "overdue") if key not in invoice_group: invoice_group[key] = self.env['account.move'] # recordset kosong invoice_group[key] |= inv # gabung recordset - template = self.env.ref('indoteknik_custom.mail_template_invoice_due_reminder') - for (partner, dtd), invs in invoice_group.items(): if all(inv.reminder_sent_date == today for inv in invs): _logger.info(f"Reminder untuk {partner.name} sudah terkirim hari ini, skip.") continue - + promise_dates = [inv.customer_promise_date for inv in invs if inv.customer_promise_date] if promise_dates: earliest_promise = min(promise_dates) # ambil janji paling awal @@ -248,11 +285,12 @@ class AccountMove(models.Model): invoice_table_rows = "" grand_total = 0 - for inv in invs: + for idx, inv in enumerate(invs, start=1): # numbering days_to_due = (inv.invoice_date_due - today).days if inv.invoice_date_due else 0 grand_total += inv.amount_total invoice_table_rows += f""" <tr> + <td>{idx}</td> <td>{inv.partner_id.name}</td> <td>{inv.ref or '-'}</td> <td>{inv.name}</td> @@ -263,6 +301,7 @@ class AccountMove(models.Model): <td>{days_to_due}</td> </tr> """ + invoice_table_footer = f""" <tfoot> <tr style="font-weight:bold; background-color:#f9f9f9;"> @@ -296,12 +335,14 @@ class AccountMove(models.Model): currency = invs[0].currency_id if invs else partner.company_id.currency_id tempo_link = 'https://indoteknik.com/my/tempo' # tempo_link = 'http://localhost:2100/my/tempo' + # payment_term = partner.previous_payment_term_id if partner.is_cbd_locked else partner.property_payment_term_id + payment_term = invs[0].invoice_payment_term_id limit_info_html = f""" <p><b>Informasi Tambahan:</b></p> <ul style="font-size:12px; color:#333; line-height:1.4; margin:0; padding-left:0; list-style-position:inside;"> <li>Kredit Limit Anda: {formatLang(self.env, blocking_limit, currency_obj=currency)}</li> - <li>Status Detail Tempo: {partner.property_payment_term_id.name or 'Review'}</li> + <li>Status Detail Tempo: {payment_term.name or ''}</li> <li style="color:{'red' if (blocking_limit - outstanding_amount) < 0 else 'green'};"> Sisa Kredit Limit: {formatLang(self.env, blocking_limit - outstanding_amount, currency_obj=currency)} </li> @@ -326,33 +367,33 @@ class AccountMove(models.Model): days_to_due_message = "" closing_message = "" - if dtd > 0: - days_to_due_message = ( - f"Kami ingin mengingatkan bahwa tagihan anda akan jatuh tempo dalam {dtd} hari ke depan, " - "dengan rincian sebagai berikut:" - ) - closing_message = ( - "Kami mengharapkan pembayaran dapat dilakukan tepat waktu untuk mendukung kelancaran " - "hubungan kerja sama yang baik antara kedua belah pihak.<br/>" - "Mohon konfirmasi apabila pembayaran telah dijadwalkan. " - "Terima kasih atas perhatian dan kerja samanya." - ) - - if dtd == 0: - days_to_due_message = ( - "Kami ingin mengingatkan bahwa tagihan anda telah memasuki tanggal jatuh tempo pada hari ini, " - "dengan rincian sebagai berikut:" - ) - closing_message = ( - "Mohon kesediaannya untuk segera melakukan pembayaran tepat waktu guna menghindari status " - "keterlambatan dan menjaga kelancaran hubungan kerja sama yang telah terjalin dengan baik.<br/>" - "Apabila pembayaran telah dijadwalkan atau diproses, mohon dapat dikonfirmasi kepada kami. " - "Terima kasih atas perhatian dan kerja samanya." - ) + if mode == "due": + if dtd > 0: + days_to_due_message = ( + f"Kami ingin mengingatkan bahwa tagihan anda akan jatuh tempo dalam {dtd} hari ke depan, " + "dengan rincian sebagai berikut:" + ) + closing_message = ( + "Kami mengharapkan pembayaran dapat dilakukan tepat waktu untuk mendukung kelancaran " + "hubungan kerja sama yang baik antara kedua belah pihak.<br/>" + "Mohon konfirmasi apabila pembayaran telah dijadwalkan. " + "Terima kasih atas perhatian dan kerja samanya." + ) - if dtd < 0: + elif dtd == 0: + days_to_due_message = ( + "Kami ingin mengingatkan bahwa tagihan anda telah memasuki tanggal jatuh tempo pada hari ini, " + "dengan rincian sebagai berikut:" + ) + closing_message = ( + "Mohon kesediaannya untuk segera melakukan pembayaran tepat waktu guna menghindari status " + "keterlambatan dan menjaga kelancaran hubungan kerja sama yang telah terjalin dengan baik.<br/>" + "Apabila pembayaran telah dijadwalkan atau diproses, mohon dapat dikonfirmasi kepada kami. " + "Terima kasih atas perhatian dan kerja samanya." + ) + else: # mode overdue days_to_due_message = ( - f"Kami ingin mengingatkan bahwa tagihan anda telah jatuh tempo selama {abs(dtd)} hari, " + f"Kami ingin mengingatkan bahwa beberapa tagihan anda telah jatuh tempo, " "dengan rincian sebagai berikut:" ) closing_message = ( |
