diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2025-07-10 08:34:00 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2025-07-10 08:34:00 +0000 |
| commit | 256f4f7cc1e0899f30f8aaae844069e9537ed5e3 (patch) | |
| tree | d7082be95a2591e213513e45bd892dd1ef57cdcf | |
| parent | ced1cf1a4733bc713f899d50d1e365f36c9fad56 (diff) | |
| parent | 839474c5f411b8c6c2476d8dcda9a6068d9848e5 (diff) | |
Merged in reminder-tempo (pull request #354)
Reminder tempo
| -rw-r--r-- | indoteknik_custom/models/account_move.py | 91 | ||||
| -rw-r--r-- | indoteknik_custom/views/mail_template_invoice_reminder.xml | 30 |
2 files changed, 53 insertions, 68 deletions
diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index c3908daf..6c4eb14b 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__) @@ -77,7 +78,6 @@ class AccountMove(models.Model): def send_due_invoice_reminder(self): today = fields.Date.today() - # Ganti nama partner untuk test jika perlu partner = self.env['res.partner'].search([('name', 'ilike', 'TIRTA FRESINDO JAYA')], limit=1) if not partner: _logger.info("Partner tidak ditemukan.") @@ -89,7 +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 - timedelta(days=0)), + ('invoice_date_due', '>=', today), ('invoice_date_due', '<=', today + timedelta(days=3)), ('invoice_date_due', '<=', today + timedelta(days=7)), ('partner_id', '=', partner.id), @@ -97,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() ) @@ -107,51 +106,53 @@ 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') - try: - email_values = template.with_context(invoices=invoices).generate_email( - partner.id, - ['subject', 'body_html', 'email_to', 'email_from']) - email_values['email_to'] = 'andrifebriyadiputra@gmail.com' # override untuk test - email_values['email_from'] = 'finance@indoteknik.co.id' - - self.env['mail.mail'].create(email_values).send() - _logger.info(f"[Reminder Terkirim] ke {partner.name} → {len(invoices)} invoice") - except Exception as e: - _logger.error(f"[Reminder Gagal] ke {partner.name} → {str(e)}") - - - # 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 + 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""" + <tr> + <td>{inv.name}</td> + <td>{fields.Date.to_string(inv.invoice_date) or '-'}</td> + <td>{fields.Date.to_string(inv.invoice_date_due) or '-'}</td> + <td>{days_to_due}</td> + <td>{formatLang(self.env, inv.amount_total, currency_obj=inv.currency_id)}</td> + <td>{inv.ref or '-'}</td> + </tr> + """ + + subject = f"Reminder Invoice Due - {partner.name}" + body_html = re.sub( + r"<tbody[^>]*>.*?</tbody>", + f"<tbody>{invoice_table_rows}</tbody>", + 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") + @api.onchange('invoice_date') def _onchange_invoice_date(self): diff --git a/indoteknik_custom/views/mail_template_invoice_reminder.xml b/indoteknik_custom/views/mail_template_invoice_reminder.xml index 176a68ba..92362284 100644 --- a/indoteknik_custom/views/mail_template_invoice_reminder.xml +++ b/indoteknik_custom/views/mail_template_invoice_reminder.xml @@ -2,24 +2,22 @@ <odoo> <data noupdate="1"> <record id="mail_template_invoice_due_reminder" model="mail.template"> - <field name="name">Invoice Reminder: Due Date Notification</field> + <field name="name">Invoice Reminder: Due Date Notification (Manual)</field> <field name="model_id" ref="base.model_res_partner"/> - <field name="subject">[Reminder] Invoice Due Summary for ${object.name}</field> + <field name="subject">[Reminder] Invoice Manual</field> <field name="email_from">finance@indoteknik.co.id</field> <field name="email_to">andrifebriyadiputra@gmail.com</field> - <!-- <field name="email_to">${object.email|safe}</field> --> <field name="body_html" type="html"> <div style="font-family:Arial, sans-serif; font-size:14px;"> - <p>Dengan Hormat Bpk/Ibu ${object.name},</p> + <p>Dengan Hormat Bpk/Ibu,</p> <p>Berikut adalah daftar invoice Anda yang mendekati atau telah jatuh tempo:</p> <table border="1" cellpadding="6" cellspacing="0" style="border-collapse: collapse; width: 100%;"> <thead> <tr style="background-color: #f2f2f2;"> - <th>No</th> <th>Invoice Number</th> - <th>Tanggal</th> + <th>Tanggal Invoice</th> <th>Jatuh Tempo</th> <th>Sisa Hari</th> <th>Total</th> @@ -27,34 +25,20 @@ </tr> </thead> <tbody> - <t t-set="i" t-value="1"/> - <t t-foreach="ctx.get('invoices', [])" t-as="inv"> - <tr> - <td><t t-esc="i"/></td> - <td><t t-esc="inv.name"/></td> - <td><t t-esc="format_date(inv.invoice_date)"/></td> - <td><t t-esc="format_date(inv.invoice_date_due)"/></td> - <td><t t-esc="inv.invoice_day_to_due"/></td> - <td><t t-esc="format_amount(inv.amount_total, inv.currency_id)"/></td> - <td><t t-esc="inv.ref or '-'"/></td> - </tr> - <t t-set="i" t-value="i + 1"/> - </t> </tbody> </table> - <p>Mohon segera melakukan proses pembayaran. Terima kasih.</p> + <p>Mohon segera melakukan proses pembayaran untuk invoice-invoice tersebut.</p> <p> Hormat Kami,<br/> <strong>PT. INDOTEKNIK DOTCOM GEMILANG</strong><br/> - Telp: 021-2933 8828 / 29<br/> - Email: finance@indoteknik.co.id + Jl. Bandengan Utara 85A No. 8-9, Penjaringan, Jakarta Utara<br/> + Telp: 021-2933 8828 / 29 | Email: finance@indoteknik.co.id </p> </div> </field> <field name="auto_delete" eval="True"/> </record> - </data> </odoo> |
