From 8e80bb240aa74c8b2942d983e73ff501f5b8defc Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Thu, 10 Jul 2025 15:12:36 +0700 Subject: (andri) rev mutiple invoices reminder --- indoteknik_custom/models/account_move.py | 78 ++++++++++++++++------ .../views/mail_template_invoice_reminder.xml | 25 ++----- 2 files changed, 65 insertions(+), 38 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index df79b9f6..fd72d566 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -9,6 +9,7 @@ import os import re from terbilang import Terbilang from collections import defaultdict +from odoo.tools.misc import formatLang _logger = logging.getLogger(__name__) @@ -76,12 +77,8 @@ class AccountMove(models.Model): def send_due_invoice_reminder(self): today = fields.Date.today() - reminder_days = [-7, -3, 0, 3, 7] - target_dates = [today + timedelta(days=delta) for delta in reminder_days] - target_dates_str = [d.isoformat() for d in target_dates] - # Ganti nama partner untuk test jika perlu - partner = self.env['res.partner'].search([('name', 'ilike', 'PRIMA SEJAHTERA MARITIM')], limit=1) + partner = self.env['res.partner'].search([('name', 'ilike', 'TIRTA FRESINDO JAYA')], limit=1) if not partner: _logger.info("Partner tidak ditemukan.") return @@ -92,6 +89,7 @@ class AccountMove(models.Model): ('payment_state', 'not in', ['paid','in_payment', 'reversed']), ('invoice_date_due', '>=', today - timedelta(days=7)), ('invoice_date_due', '>=', today - timedelta(days=3)), + ('invoice_date_due', '=', today), ('invoice_date_due', '<=', today + timedelta(days=3)), ('invoice_date_due', '<=', today + timedelta(days=7)), ('partner_id', '=', partner.id), @@ -99,7 +97,6 @@ class AccountMove(models.Model): _logger.info(f"Invoices tahap 1: {invoices}") - # Filter berdasarkan term mengandung "tempo" invoices = invoices.filtered( lambda inv: inv.invoice_payment_term_id and 'tempo' in (inv.invoice_payment_term_id.name or '').lower() ) @@ -109,23 +106,64 @@ class AccountMove(models.Model): _logger.info(f"Tidak ada invoice yang due untuk partner: {partner.name}") return - # Pastikan field compute jalan - invoices._compute_invoice_day_to_due() + grouped = {} + for inv in invoices: + grouped.setdefault(inv.partner_id, []).append(inv) - # Ambil template template = self.env.ref('indoteknik_custom.mail_template_invoice_due_reminder') - for inv in invoices: - try: - # Untuk test: override ke email pribadi Anda - email_values = { - 'email_to': 'andrifebriyadiputra@gmail.com', - 'email_from': 'finance@indoteknik.co.id', - } - template.send_mail(inv.id, force_send=True, email_values=email_values) - _logger.info(f"Reminder terkirim: {inv.name} → {email_values['email_to']}") - except Exception as e: - _logger.error(f"Gagal kirim email untuk {inv.name}: {str(e)}") + for partner, invs in grouped.items(): + if not partner.email: + _logger.info(f"Partner {partner.name} tidak memiliki email") + continue + + invoice_table_rows = "" + for inv in invs: + days_to_due = (inv.invoice_date_due - today).days if inv.invoice_date_due else 0 + invoice_table_rows += f""" + + {inv.name} + {fields.Date.to_string(inv.invoice_date) or '-'} + {fields.Date.to_string(inv.invoice_date_due) or '-'} + {days_to_due} + {formatLang(self.env, inv.amount_total, currency_obj=inv.currency_id)} + {inv.ref or '-'} + + """ + + subject = f"Reminder Invoice Due - {partner.name}" + body_html = re.sub( + r"]*>.*?", + f"{invoice_table_rows}", + template.body_html, + flags=re.DOTALL + ).replace('${object.name}', partner.name) \ + .replace('${object.partner_id.name}', partner.name) \ + .replace('${object.email}', partner.email or '') + + values = { + 'subject': subject, + 'email_to': 'andrifebriyadiputra@gmail.com', # Ubah ke partner.email untuk produksi + 'email_from': 'finance@indoteknik.co.id', + 'body_html': body_html, + } + + _logger.info(f"VALUES: {values}") + + # self.env['mail.mail'].create(values).send() + # _logger.info(f"Reminder terkirim ke {partner.name} ({values['email_to']}) → {len(invs)} invoice") + + # for inv in invoices: + # try: + # # Untuk test: override ke email pribadi Anda + # email_values = { + # 'email_to': 'andrifebriyadiputra@gmail.com', + # 'email_from': 'finance@indoteknik.co.id', + # } + # template.send_mail(inv.id, force_send=True, email_values=email_values) + # _logger.info(f"Reminder terkirim: {inv.name} → {email_values['email_to']}") + # except Exception as e: + # _logger.error(f"Gagal kirim email untuk {inv.name}: {str(e)}") # def name_get(self): # result = [] diff --git a/indoteknik_custom/views/mail_template_invoice_reminder.xml b/indoteknik_custom/views/mail_template_invoice_reminder.xml index b19171b2..b39730b6 100644 --- a/indoteknik_custom/views/mail_template_invoice_reminder.xml +++ b/indoteknik_custom/views/mail_template_invoice_reminder.xml @@ -2,17 +2,16 @@ - Invoice Reminder: Due Date Notification - - [Reminder] Invoice ${object.name} is Due Soon + Invoice Reminder: Due Date Notification (Manual) + + [Reminder] Invoice Manual finance@indoteknik.co.id - finance@indoteknik.co.id - andrifebriyadiputra@gmail.com + test@example.com
-

Dengan Hormat Bpk/Ibu ${object.partner_id.name},

+

Dengan Hormat Bpk/Ibu,

-

Berikut adalah detail invoice Anda yang sudah mendekati atau telah jatuh tempo:

+

Berikut adalah daftar invoice Anda yang mendekati atau telah jatuh tempo:

@@ -26,20 +25,10 @@ - - - - - - - -
${object.name}${format_date(object.invoice_date)}${format_date(object.invoice_date_due)}${object.invoice_day_to_due}${format_amount(object.amount_total, object.currency_id)}${object.ref or '-'}
-

Mohon segera melakukan proses pembayaran sebelum jatuh tempo.

- -

Terima kasih atas perhatian dan kerjasamanya.

+

Mohon segera melakukan proses pembayaran untuk invoice-invoice tersebut.

Hormat Kami,
-- cgit v1.2.3 From 6aee89eff0e1511c257c60fac9fa84172729063c Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Thu, 10 Jul 2025 15:13:18 +0700 Subject: (andri) apus bagian yang tak perlu --- indoteknik_custom/models/account_move.py | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index fd72d566..eb39a1ac 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -153,32 +153,6 @@ class AccountMove(models.Model): # self.env['mail.mail'].create(values).send() # _logger.info(f"Reminder terkirim ke {partner.name} ({values['email_to']}) → {len(invs)} invoice") - # for inv in invoices: - # try: - # # Untuk test: override ke email pribadi Anda - # email_values = { - # 'email_to': 'andrifebriyadiputra@gmail.com', - # 'email_from': 'finance@indoteknik.co.id', - # } - # template.send_mail(inv.id, force_send=True, email_values=email_values) - # _logger.info(f"Reminder terkirim: {inv.name} → {email_values['email_to']}") - # except Exception as e: - # _logger.error(f"Gagal kirim email untuk {inv.name}: {str(e)}") - - # def name_get(self): - # result = [] - # for move in self: - # if move.move_type == 'entry': - # # Jika masih draft, tampilkan 'Draft CAB' - # if move.state == 'draft': - # label = 'Draft CAB' - # else: - # label = move.name - # result.append((move.id, label)) - # else: - # # Untuk invoice dan lainnya, pakai default - # result.append((move.id, move.display_name)) - # return result @api.onchange('invoice_date') def _onchange_invoice_date(self): -- cgit v1.2.3 From 839474c5f411b8c6c2476d8dcda9a6068d9848e5 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Thu, 10 Jul 2025 15:28:10 +0700 Subject: (andri) try test --- indoteknik_custom/models/account_move.py | 4 ++-- indoteknik_custom/views/mail_template_invoice_reminder.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 822c54f7..6c4eb14b 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -150,8 +150,8 @@ class AccountMove(models.Model): _logger.info(f"VALUES: {values}") - # self.env['mail.mail'].create(values).send() - # _logger.info(f"Reminder terkirim ke {partner.name} ({values['email_to']}) → {len(invs)} invoice") + self.env['mail.mail'].create(values).send() + _logger.info(f"Reminder terkirim ke {partner.name} ({values['email_to']}) → {len(invs)} invoice") @api.onchange('invoice_date') diff --git a/indoteknik_custom/views/mail_template_invoice_reminder.xml b/indoteknik_custom/views/mail_template_invoice_reminder.xml index b39730b6..92362284 100644 --- a/indoteknik_custom/views/mail_template_invoice_reminder.xml +++ b/indoteknik_custom/views/mail_template_invoice_reminder.xml @@ -6,7 +6,7 @@ [Reminder] Invoice Manual finance@indoteknik.co.id - test@example.com + andrifebriyadiputra@gmail.com

Dengan Hormat Bpk/Ibu,

-- cgit v1.2.3