From fa2c8cc7b00e963e740307484c174961f61ffc84 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Thu, 5 Jun 2025 08:35:39 +0700 Subject: (andri) add field Journal Uang Muka di PO dan Purchase Order pada CAB --- indoteknik_custom/models/account_move.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 30de67be..24cedc34 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -68,6 +68,17 @@ class AccountMove(models.Model): purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order') length_of_payment = fields.Integer(string="Length of Payment", compute='compute_length_of_payment') + def name_get(self): + result = [] + for move in self: + if move.move_type == 'entry': + # Tampilkan nomor CAB (name) + result.append((move.id, move.name)) + else: + # Gunakan default display + result.append((move.id, move.display_name)) + return result + def compute_length_of_payment(self): for rec in self: payment_term = rec.invoice_payment_term_id.line_ids[0].days -- cgit v1.2.3 From c43cba9dd205a3f08343f79233d3af6f5ab189ff Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Thu, 5 Jun 2025 08:47:31 +0700 Subject: (andri) penyesuaian value field CAB ketika masi dalam keadaan draft --- indoteknik_custom/models/account_move.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 24cedc34..29368089 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -72,10 +72,14 @@ class AccountMove(models.Model): result = [] for move in self: if move.move_type == 'entry': - # Tampilkan nomor CAB (name) - result.append((move.id, move.name)) + # Jika masih draft, tampilkan 'Draft CAB' + if move.state == 'draft': + label = 'Draft CAB' + else: + label = move.name + result.append((move.id, label)) else: - # Gunakan default display + # Untuk invoice dan lainnya, pakai default result.append((move.id, move.display_name)) return result -- cgit v1.2.3 From 984e128294f4c3d9d3d8eab8dacf03846f8336b2 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 7 Jun 2025 15:53:32 +0700 Subject: (andri) revisi peletakan CAB pada PO dan add field reklas misc --- indoteknik_custom/models/account_move.py | 1 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 29368089..73dbefd6 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -67,6 +67,7 @@ class AccountMove(models.Model): is_hr = fields.Boolean(string="Is HR?", default=False) purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order') length_of_payment = fields.Integer(string="Length of Payment", compute='compute_length_of_payment') + reklas_misc_id = fields.Many2one('account.move', string='No Jurnal Reklas (MISC)') def name_get(self): result = [] -- cgit v1.2.3 From 9200e74126c99410b79ef2c344915251bef6af19 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 7 Jun 2025 15:55:40 +0700 Subject: (andri) edit penamaan field Reklas --- indoteknik_custom/models/account_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 73dbefd6..3333af8f 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -67,7 +67,7 @@ class AccountMove(models.Model): is_hr = fields.Boolean(string="Is HR?", default=False) purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order') length_of_payment = fields.Integer(string="Length of Payment", compute='compute_length_of_payment') - reklas_misc_id = fields.Many2one('account.move', string='No Jurnal Reklas (MISC)') + reklas_misc_id = fields.Many2one('account.move', string='Journal Entries Reklas') def name_get(self): result = [] -- cgit v1.2.3 From c827294ee6dd613de089af846521cfdc76550e16 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Tue, 10 Jun 2025 13:10:35 +0700 Subject: (andri) revisi mengenai onchange create reklas dan yang lain --- indoteknik_custom/models/account_move.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 3333af8f..4cd2b6b3 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -68,6 +68,9 @@ class AccountMove(models.Model): purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order') length_of_payment = fields.Integer(string="Length of Payment", compute='compute_length_of_payment') reklas_misc_id = fields.Many2one('account.move', string='Journal Entries Reklas') + # Di model account.move + bill_id = fields.Many2one('account.move', string='Vendor Bill', domain=[('move_type', '=', 'in_invoice')], help='Bill asal dari proses reklas ini') + def name_get(self): result = [] -- cgit v1.2.3 From acc284c5881675780faecd89ab5aaa85fd017914 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Wed, 11 Jun 2025 13:07:51 +0700 Subject: (andri) fix bug name invoice yang berdampak pada dunningrun line --- indoteknik_custom/models/account_move.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 4cd2b6b3..54eaabcf 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -72,20 +72,20 @@ class AccountMove(models.Model): bill_id = fields.Many2one('account.move', string='Vendor Bill', domain=[('move_type', '=', 'in_invoice')], help='Bill asal dari proses reklas ini') - 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 + # 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 def compute_length_of_payment(self): for rec in self: -- cgit v1.2.3 From 4fc9dd9424b4b5665872a0386389278efada75f9 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Wed, 18 Jun 2025 15:24:23 +0700 Subject: (andri) fix date --- indoteknik_custom/models/account_move.py | 40 ++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 54eaabcf..66020a69 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -87,6 +87,17 @@ class AccountMove(models.Model): # result.append((move.id, move.display_name)) # return result + @api.onchange('invoice_date') + def _onchange_invoice_date(self): + if self.invoice_date: + self.date = self.invoice_date + + @api.onchange('date') + def _onchange_date(self): + if self.date: + self.invoice_date = self.date + + def compute_length_of_payment(self): for rec in self: payment_term = rec.invoice_payment_term_id.line_ids[0].days @@ -145,13 +156,38 @@ class AccountMove(models.Model): } template.send_mail(record.id, email_values=email_values, force_send=True) + # @api.model + # def create(self, vals): + # vals['nomor_kwitansi'] = self.env['ir.sequence'].next_by_code('nomor.kwitansi') or '0' + # result = super(AccountMove, self).create(vals) + # # result._update_line_name_from_ref() + # return result + @api.model def create(self, vals): - vals['nomor_kwitansi'] = self.env['ir.sequence'].next_by_code('nomor.kwitansi') or '0' + vals['nomor_kwitansi'] = self.env['ir.sequence'].next_by_code('nomor.kwitansi') or '0' result = super(AccountMove, self).create(vals) - # result._update_line_name_from_ref() + + # Tambahan: jika ini Vendor Bill dan tanggal belum diisi + if result.move_type == 'in_invoice' and not vals.get('invoice_date') and not vals.get('date'): + po = result.purchase_order_id + if po: + # Cari receipt dari PO + picking = self.env['stock.picking'].search([ + ('purchase_id', '=', po.id), + ('picking_type_code', '=', 'incoming'), + ('state', '=', 'done'), + ('date_done', '!=', False), + ], order='date_done desc', limit=1) + + if picking: + receipt_date = picking.date_done + result.invoice_date = receipt_date + result.date = receipt_date + return result + def compute_so_shipping_paid_by(self): for record in self: record.so_shipping_paid_by = record.sale_id.shipping_paid_by -- cgit v1.2.3 From 6a913c0025c64903536fa6c9aeda526b609d27e6 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 24 Jun 2025 11:23:36 +0700 Subject: change request coretax down payment --- indoteknik_custom/models/account_move.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 66020a69..ece47236 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -70,6 +70,7 @@ class AccountMove(models.Model): reklas_misc_id = fields.Many2one('account.move', string='Journal Entries Reklas') # Di model account.move bill_id = fields.Many2one('account.move', string='Vendor Bill', domain=[('move_type', '=', 'in_invoice')], help='Bill asal dari proses reklas ini') + down_payment = fields.Boolean('Down Payments?') # def name_get(self): @@ -441,7 +442,7 @@ class AccountMove(models.Model): # Panggil model coretax.faktur untuk menghasilkan XML coretax_faktur = self.env['coretax.faktur'].create({}) - response = coretax_faktur.export_to_download(invoices=valid_invoices) + response = coretax_faktur.export_to_download(invoices=valid_invoices, down_payments=valid_invoices.down_payment) current_time = datetime.utcnow() # Tandai faktur sebagai sudah diekspor -- cgit v1.2.3 From 7e42b0fdd1735df03e249f1362e58c169236465d Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Tue, 24 Jun 2025 15:08:37 +0700 Subject: (andri) fix download xml invoice --- indoteknik_custom/models/account_move.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index ece47236..af24f93e 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -437,18 +437,18 @@ class AccountMove(models.Model): return invoices def export_faktur_to_xml(self): - valid_invoices = self - # Panggil model coretax.faktur untuk menghasilkan XML coretax_faktur = self.env['coretax.faktur'].create({}) - response = coretax_faktur.export_to_download(invoices=valid_invoices, down_payments=valid_invoices.down_payment) - current_time = datetime.utcnow() - # Tandai faktur sebagai sudah diekspor + response = coretax_faktur.export_to_download( + invoices=valid_invoices, + down_payments=[inv.down_payment for inv in valid_invoices], + ) + valid_invoices.write({ 'is_efaktur_exported': True, - 'date_efaktur_exported': current_time, # Set tanggal ekspor + 'date_efaktur_exported': datetime.utcnow(), }) - return response + return response \ No newline at end of file -- cgit v1.2.3 From e5b1c4117bd887b1e77c0aa8117b79646397855b Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Fri, 4 Jul 2025 10:02:31 +0700 Subject: (andri) fix open jurnal entries --- indoteknik_custom/models/account_move.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index af24f93e..b6627867 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -99,12 +99,27 @@ class AccountMove(models.Model): self.invoice_date = self.date + # def compute_length_of_payment(self): + # for rec in self: + # payment_term = rec.invoice_payment_term_id.line_ids[0].days + # terima_faktur = rec.date_terima_tukar_faktur + # payment = self.search([('ref', '=', rec.name), ('move_type', '=', 'entry')], limit=1) + + # if payment and terima_faktur: + # date_diff = terima_faktur - payment.date + # rec.length_of_payment = date_diff.days + payment_term + # else: + # rec.length_of_payment = 0 + def compute_length_of_payment(self): for rec in self: - payment_term = rec.invoice_payment_term_id.line_ids[0].days + payment_term = 0 + if rec.invoice_payment_term_id and rec.invoice_payment_term_id.line_ids: + payment_term = rec.invoice_payment_term_id.line_ids[0].days + terima_faktur = rec.date_terima_tukar_faktur payment = self.search([('ref', '=', rec.name), ('move_type', '=', 'entry')], limit=1) - + if payment and terima_faktur: date_diff = terima_faktur - payment.date rec.length_of_payment = date_diff.days + payment_term -- cgit v1.2.3 From db98db3e34ac47eeea0fc53f215cb483d6c5d5f9 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Wed, 9 Jul 2025 11:32:19 +0700 Subject: (andri) scheduler reminder due inv --- indoteknik_custom/models/account_move.py | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index b6627867..df79b9f6 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -8,12 +8,14 @@ import PyPDF2 import os import re from terbilang import Terbilang +from collections import defaultdict _logger = logging.getLogger(__name__) class AccountMove(models.Model): _inherit = 'account.move' + _description = 'Account Move' invoice_day_to_due = fields.Integer(string="Day to Due", compute="_compute_invoice_day_to_due") bill_day_to_due = fields.Date(string="Day to Due", compute="_compute_bill_day_to_due") date_send_fp = fields.Datetime(string="Tanggal Kirim Faktur Pajak") @@ -72,6 +74,58 @@ class AccountMove(models.Model): bill_id = fields.Many2one('account.move', string='Vendor Bill', domain=[('move_type', '=', 'in_invoice')], help='Bill asal dari proses reklas ini') down_payment = fields.Boolean('Down Payments?') + 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) + if not partner: + _logger.info("Partner tidak ditemukan.") + return + + invoices = self.env['account.move'].search([ + ('move_type', '=', 'out_invoice'), + ('state', '=', 'posted'), + ('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=3)), + ('invoice_date_due', '<=', today + timedelta(days=7)), + ('partner_id', '=', partner.id), + ]) + + _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() + ) + _logger.info(f"Invoices tahap 2: {invoices}") + + if not invoices: + _logger.info(f"Tidak ada invoice yang due untuk partner: {partner.name}") + return + + # Pastikan field compute jalan + invoices._compute_invoice_day_to_due() + + # 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)}") # def name_get(self): # result = [] -- cgit v1.2.3 From 0d43c8987d05543c20b1ea26e6645afcf153691b Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Wed, 9 Jul 2025 13:04:08 +0700 Subject: (andri) test --- indoteknik_custom/models/account_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index df79b9f6..059e8330 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -81,7 +81,7 @@ class AccountMove(models.Model): 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', 'ROYALTAMA MULIA KONTRAKTORINDO')], limit=1) if not partner: _logger.info("Partner tidak ditemukan.") return -- cgit v1.2.3 From 5e905a9af7f6bb928c44cad2d47f8c6e69662bd2 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Wed, 9 Jul 2025 13:08:41 +0700 Subject: (andri) test --- indoteknik_custom/models/account_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 059e8330..8ef3d273 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -81,7 +81,7 @@ class AccountMove(models.Model): 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', 'ROYALTAMA MULIA KONTRAKTORINDO')], limit=1) + partner = self.env['res.partner'].search([('name', 'ilike', 'DAYA ANUGRAH MULYA')], limit=1) if not partner: _logger.info("Partner tidak ditemukan.") return -- cgit v1.2.3 From c72db0d0fa214e6691fa9a293020e7091a9c82c2 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Wed, 9 Jul 2025 13:42:33 +0700 Subject: (andri) fix invoices --- indoteknik_custom/models/account_move.py | 36 +++++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 8ef3d273..e63f4cb2 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -76,12 +76,9 @@ 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', 'DAYA ANUGRAH MULYA')], 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 - timedelta(days=0)), ('invoice_date_due', '<=', today + timedelta(days=3)), ('invoice_date_due', '<=', today + timedelta(days=7)), ('partner_id', '=', partner.id), @@ -115,17 +113,25 @@ class AccountMove(models.Model): # 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)}") + try: + template.with_context(invoices=invoices).send_mail(partner.id, force_send=True, email_values={ + 'email_to': 'andrifebriyadiputra@gmail.com', # test override + }) + _logger.info(f"Reminder terkirim ke {partner.name} → {len(invoices)} invoice") + except Exception as e: + _logger.error(f"Gagal kirim email 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 = [] -- cgit v1.2.3 From 028480352e86ac8cbfef5ea4834caf111ebfb3d4 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Wed, 9 Jul 2025 14:04:27 +0700 Subject: (andri) try --- indoteknik_custom/models/account_move.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index e63f4cb2..436dfcaa 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -114,12 +114,15 @@ class AccountMove(models.Model): template = self.env.ref('indoteknik_custom.mail_template_invoice_due_reminder') try: - template.with_context(invoices=invoices).send_mail(partner.id, force_send=True, email_values={ - 'email_to': 'andrifebriyadiputra@gmail.com', # test override - }) - _logger.info(f"Reminder terkirim ke {partner.name} → {len(invoices)} invoice") + email_values = template.with_context(invoices=invoices).generate_email(partner.id) + 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"Gagal kirim email ke {partner.name}: {str(e)}") + _logger.error(f"[Reminder Gagal] ke {partner.name} → {str(e)}") + # for inv in invoices: # try: -- cgit v1.2.3 From 00b357fa35ff809c153a5aeaf67f97a00715e463 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Wed, 9 Jul 2025 14:33:52 +0700 Subject: (andr) try2 --- indoteknik_custom/models/account_move.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 436dfcaa..c3908daf 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -114,7 +114,9 @@ class AccountMove(models.Model): template = self.env.ref('indoteknik_custom.mail_template_invoice_due_reminder') try: - email_values = template.with_context(invoices=invoices).generate_email(partner.id) + 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' -- cgit v1.2.3 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 ++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 20 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') 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 = [] -- 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(-) (limited to 'indoteknik_custom/models/account_move.py') 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 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') 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') -- cgit v1.2.3 From b3003dfcffa29390ec078ed206c9b013e683d1c8 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Thu, 10 Jul 2025 15:41:26 +0700 Subject: (andri) try --- indoteknik_custom/models/account_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 6c4eb14b..33149cb0 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -78,7 +78,7 @@ class AccountMove(models.Model): def send_due_invoice_reminder(self): today = fields.Date.today() - partner = self.env['res.partner'].search([('name', 'ilike', 'TIRTA FRESINDO JAYA')], limit=1) + partner = self.env['res.partner'].search([('name', 'ilike', 'GEMILANG TUJUH BERSAUDARA')], limit=1) if not partner: _logger.info("Partner tidak ditemukan.") return -- cgit v1.2.3 From 9aa1682f36cad78e04d3367c1d30867c7706a5d1 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Thu, 10 Jul 2025 17:15:02 +0700 Subject: (andri) fix invoices date due --- indoteknik_custom/models/account_move.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 33149cb0..ddd2f7d9 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -77,8 +77,15 @@ class AccountMove(models.Model): def send_due_invoice_reminder(self): today = fields.Date.today() - - partner = self.env['res.partner'].search([('name', 'ilike', 'GEMILANG TUJUH BERSAUDARA')], limit=1) + target_dates = [ + today - timedelta(days=7), + today - timedelta(days=3), + today, + today + timedelta(days=3), + today + timedelta(days=7), + ] + + partner = self.env['res.partner'].search([('name', 'ilike', 'PROBAN OSTBURG TRISAKTI')], limit=1) if not partner: _logger.info("Partner tidak ditemukan.") return @@ -87,11 +94,7 @@ class AccountMove(models.Model): ('move_type', '=', 'out_invoice'), ('state', '=', 'posted'), ('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)), + ('invoice_date_due', 'in', target_dates), ('partner_id', '=', partner.id), ]) @@ -138,8 +141,8 @@ class AccountMove(models.Model): template.body_html, flags=re.DOTALL ).replace('${object.name}', partner.name) \ - .replace('${object.partner_id.name}', partner.name) \ - .replace('${object.email}', partner.email or '') + .replace('${object.partner_id.name}', partner.name) + # .replace('${object.email}', partner.email or '') values = { 'subject': subject, @@ -150,7 +153,7 @@ class AccountMove(models.Model): _logger.info(f"VALUES: {values}") - self.env['mail.mail'].create(values).send() + template.send_mail(invs[0].id, force_send=True, email_values=values) _logger.info(f"Reminder terkirim ke {partner.name} ({values['email_to']}) → {len(invs)} invoice") -- cgit v1.2.3 From 575a7a506382487a625914a7bde9a18b20173cc6 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Fri, 11 Jul 2025 10:45:26 +0700 Subject: (andri) rev template email & fix sequence approval --- indoteknik_custom/models/account_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index ddd2f7d9..5ac1c6e5 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -85,7 +85,7 @@ class AccountMove(models.Model): today + timedelta(days=7), ] - partner = self.env['res.partner'].search([('name', 'ilike', 'PROBAN OSTBURG TRISAKTI')], limit=1) + partner = self.env['res.partner'].search([('name', 'ilike', 'FLYNINDO MEGA PERSADA')], limit=1) if not partner: _logger.info("Partner tidak ditemukan.") return -- cgit v1.2.3 From 6f4d19cd6985790414b06678fe2147c431caed9e Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 12 Jul 2025 11:28:38 +0700 Subject: (andri)chatter send email reminder due invoices terkait --- indoteknik_custom/models/account_move.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 5ac1c6e5..42f9f43a 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -85,7 +85,7 @@ class AccountMove(models.Model): today + timedelta(days=7), ] - partner = self.env['res.partner'].search([('name', 'ilike', 'FLYNINDO MEGA PERSADA')], limit=1) + partner = self.env['res.partner'].search([('name', 'ilike', 'BANGUNAN TEKNIK GRUP')], limit=1) if not partner: _logger.info("Partner tidak ditemukan.") return @@ -153,7 +153,22 @@ class AccountMove(models.Model): _logger.info(f"VALUES: {values}") - template.send_mail(invs[0].id, force_send=True, email_values=values) + # template.send_mail(invs[0].id, force_send=True, email_values=values) + + # Default System User + user_system = self.env['res.users'].browse(25) + system_id = user_system.partner_id.id if user_system else False + _logger.info(f"System User: {user_system.name} ({user_system.id})") + _logger.info(f"System User ID: {system_id}") + + for inv in invs: + inv.message_post( + subject=subject, + body=body_html, + subtype_id=self.env.ref('mail.mt_note').id, + author_id=system_id, + ) + _logger.info(f"Reminder terkirim ke {partner.name} ({values['email_to']}) → {len(invs)} invoice") -- cgit v1.2.3 From 8ff2da221c3e744706a69b0f8016f65169b61aca Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 12 Jul 2025 14:18:20 +0700 Subject: (andri) add reply dan masuk ke chatter --- indoteknik_custom/models/account_move.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 42f9f43a..72ac5452 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -149,11 +149,12 @@ class AccountMove(models.Model): 'email_to': 'andrifebriyadiputra@gmail.com', # Ubah ke partner.email untuk produksi 'email_from': 'finance@indoteknik.co.id', 'body_html': body_html, + 'reply_to': f'invoice+account.move_{invs[0].id}@indoteknik.co.id', } _logger.info(f"VALUES: {values}") - # template.send_mail(invs[0].id, force_send=True, email_values=values) + template.send_mail(invs[0].id, force_send=True, email_values=values) # Default System User user_system = self.env['res.users'].browse(25) -- cgit v1.2.3 From deb60713ed39979b34083ee094de79fa3afac3b8 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 23 Jul 2025 14:50:10 +0700 Subject: Refund System --- indoteknik_custom/models/account_move.py | 35 +++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index b6627867..7bb71e03 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -1,5 +1,6 @@ from odoo import models, api, fields from odoo.exceptions import AccessError, UserError, ValidationError +from markupsafe import escape as html_escape from datetime import timedelta, date, datetime from pytz import timezone, utc import logging @@ -71,7 +72,24 @@ class AccountMove(models.Model): # Di model account.move bill_id = fields.Many2one('account.move', string='Vendor Bill', domain=[('move_type', '=', 'in_invoice')], help='Bill asal dari proses reklas ini') down_payment = fields.Boolean('Down Payments?') - + refund_id = fields.Many2one('refund.sale.order', string='Refund Reference') + refund_so_ids = fields.Many2many( + 'sale.order', + 'account_move_sale_order_rel', + 'move_id', + 'sale_order_id', + string='Group SO Number' + ) + + refund_so_links = fields.Html( + string="Group SO Numbers", + compute="_compute_refund_so_links", + ) + + has_refund_so = fields.Boolean( + string='Has Refund SO', + compute='_compute_has_refund_so', + ) # def name_get(self): # result = [] @@ -98,6 +116,21 @@ class AccountMove(models.Model): if self.date: self.invoice_date = self.date + @api.depends('refund_so_ids') + def _compute_refund_so_links(self): + for rec in self: + links = [] + for so in rec.refund_so_ids: + url = f"/web#id={so.id}&model=sale.order&view_type=form" + name = html_escape(so.name or so.display_name) + links.append(f'{name}') + rec.refund_so_links = ', '.join(links) if links else "-" + + @api.depends('refund_so_ids') + def _compute_has_refund_so(self): + for rec in self: + rec.has_refund_so = bool(rec.refund_so_ids) + # def compute_length_of_payment(self): # for rec in self: -- cgit v1.2.3 From 4d0ba0dc130697e6dec1422efa7339b5e6445b53 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 23 Jul 2025 15:11:52 +0700 Subject: fix --- indoteknik_custom/models/account_move.py | 192 +++++++++++++++---------------- 1 file changed, 96 insertions(+), 96 deletions(-) (limited to 'indoteknik_custom/models/account_move.py') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index db52f398..1a6fad1c 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -109,102 +109,102 @@ class AccountMove(models.Model): # result.append((move.id, move.display_name)) # return result - 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), - ] - - partner = self.env['res.partner'].search([('name', 'ilike', 'BANGUNAN TEKNIK GRUP')], limit=1) - if not partner: - _logger.info("Partner tidak ditemukan.") - return - - 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), - ('partner_id', '=', partner.id), - ]) - - _logger.info(f"Invoices tahap 1: {invoices}") - - 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}") - - if not invoices: - _logger.info(f"Tidak ada invoice yang due untuk partner: {partner.name}") - return - - grouped = {} - for inv in invoices: - grouped.setdefault(inv.partner_id, []).append(inv) - - template = self.env.ref('indoteknik_custom.mail_template_invoice_due_reminder') - - 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, - 'reply_to': f'invoice+account.move_{invs[0].id}@indoteknik.co.id', - } - - _logger.info(f"VALUES: {values}") - - template.send_mail(invs[0].id, force_send=True, email_values=values) - - # Default System User - user_system = self.env['res.users'].browse(25) - system_id = user_system.partner_id.id if user_system else False - _logger.info(f"System User: {user_system.name} ({user_system.id})") - _logger.info(f"System User ID: {system_id}") - - for inv in invs: - inv.message_post( - subject=subject, - body=body_html, - subtype_id=self.env.ref('mail.mt_note').id, - author_id=system_id, - ) - - _logger.info(f"Reminder terkirim ke {partner.name} ({values['email_to']}) → {len(invs)} invoice") + # 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), + # ] + + # partner = self.env['res.partner'].search([('name', 'ilike', 'BANGUNAN TEKNIK GRUP')], limit=1) + # if not partner: + # _logger.info("Partner tidak ditemukan.") + # return + + # 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), + # ('partner_id', '=', partner.id), + # ]) + + # _logger.info(f"Invoices tahap 1: {invoices}") + + # 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}") + + # if not invoices: + # _logger.info(f"Tidak ada invoice yang due untuk partner: {partner.name}") + # return + + # grouped = {} + # for inv in invoices: + # grouped.setdefault(inv.partner_id, []).append(inv) + + # template = self.env.ref('indoteknik_custom.mail_template_invoice_due_reminder') + + # 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, + # 'reply_to': f'invoice+account.move_{invs[0].id}@indoteknik.co.id', + # } + + # _logger.info(f"VALUES: {values}") + + # template.send_mail(invs[0].id, force_send=True, email_values=values) + + # # Default System User + # user_system = self.env['res.users'].browse(25) + # system_id = user_system.partner_id.id if user_system else False + # _logger.info(f"System User: {user_system.name} ({user_system.id})") + # _logger.info(f"System User ID: {system_id}") + + # for inv in invs: + # inv.message_post( + # subject=subject, + # body=body_html, + # subtype_id=self.env.ref('mail.mt_note').id, + # author_id=system_id, + # ) + + # _logger.info(f"Reminder terkirim ke {partner.name} ({values['email_to']}) → {len(invs)} invoice") @api.onchange('invoice_date') -- cgit v1.2.3