summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIT Fixcomart <it@fixcomart.co.id>2025-07-10 08:34:00 +0000
committerIT Fixcomart <it@fixcomart.co.id>2025-07-10 08:34:00 +0000
commit256f4f7cc1e0899f30f8aaae844069e9537ed5e3 (patch)
treed7082be95a2591e213513e45bd892dd1ef57cdcf
parentced1cf1a4733bc713f899d50d1e365f36c9fad56 (diff)
parent839474c5f411b8c6c2476d8dcda9a6068d9848e5 (diff)
Merged in reminder-tempo (pull request #354)
Reminder tempo
-rw-r--r--indoteknik_custom/models/account_move.py91
-rw-r--r--indoteknik_custom/views/mail_template_invoice_reminder.xml30
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>