diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2025-09-17 11:27:36 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2025-09-17 11:27:36 +0000 |
| commit | d7cb0787c9a107434c16f3d4a678511858fb6cd5 (patch) | |
| tree | 8667f96ea9d6726f7bf0d20db67878552b4f3140 | |
| parent | ec115f256cfbc24008606c3c4dc47ecdd96955e8 (diff) | |
| parent | 23d713fc686d56ef5b5e8004b91b3f4fe54117e6 (diff) | |
Merged odoo-backup into cbd-apt
| -rw-r--r-- | indoteknik_custom/models/account_move.py | 116 | ||||
| -rwxr-xr-x | indoteknik_custom/models/purchase_order.py | 3 | ||||
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 3 | ||||
| -rw-r--r-- | indoteknik_custom/models/sj_tele.py | 2 | ||||
| -rw-r--r-- | indoteknik_custom/models/stock_picking.py | 1 | ||||
| -rw-r--r-- | indoteknik_custom/report/purchase_report.xml | 4 | ||||
| -rw-r--r-- | indoteknik_custom/views/mail_template_invoice_reminder.xml | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/views/purchase_order.xml | 2 | ||||
| -rw-r--r-- | indoteknik_custom/views/stock_picking.xml | 7 |
9 files changed, 81 insertions, 58 deletions
diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 70cd07e4..f10ca23f 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -192,49 +192,57 @@ 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'), + ('partner_id', 'in', [94603])]) + _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 @@ -276,11 +284,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> @@ -291,6 +300,7 @@ class AccountMove(models.Model): <td>{days_to_due}</td> </tr> """ + invoice_table_footer = f""" <tfoot> <tr style="font-weight:bold; background-color:#f9f9f9;"> @@ -354,33 +364,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 = ( @@ -413,20 +423,20 @@ class AccountMove(models.Model): # Siapkan email values values = { - 'subject': f"Reminder Invoice Due - {partner.name}", - # 'email_to': 'andrifebriyadiputra@gmail.com', - 'email_to': email_to, + 'subject': f"Reminder Invoice Due Test - {partner.name}", + 'email_to': 'andrifebriyadiputra@gmail.com', + # 'email_to': email_to, 'email_from': 'finance@indoteknik.co.id', - 'email_cc': ",".join(sorted(set(cc_list))), + # 'email_cc': ",".join(sorted(set(cc_list))), 'body_html': body_html, - 'reply_to': 'finance@indoteknik.co.id', + # 'reply_to': 'finance@indoteknik.co.id', } template.send_mail(invs[0].id, force_send=True, email_values=values) - _logger.info(f"Mengirim email ke: {values['email_to']} > email CC: {values['email_cc']}") + # _logger.info(f"Mengirim email ke: {values['email_to']} > email CC: {values['email_cc']}") _logger.info(f"Reminder terkirim ke {partner.name} ({values['email_to']}) → {len(invs)} invoice (dtd = {dtd})") # flag - invs.write({'reminder_sent_date': today}) + # invs.write({'reminder_sent_date': today}) # Post ke chatter user_system = self.env['res.users'].browse(25) system_id = user_system.partner_id.id if user_system else False diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index e7e5c382..68180235 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -117,7 +117,8 @@ class PurchaseOrder(models.Model): ) show_description = fields.Boolean( - string='Show Description' + string='Show Description', + default=True ) @api.onchange('show_description') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 861531b9..94c5f041 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1848,7 +1848,8 @@ class SaleOrder(models.Model): # if term.days > 0: # raise UserError('Hanya dapat digunakan pada Cash Before Delivery') for line in self.order_line: - line.qty_to_invoice = line.product_uom_qty + if line.product_id.type == 'product': + line.qty_to_invoice = line.product_uom_qty # def _get_pickings(self): # state = ['assigned'] diff --git a/indoteknik_custom/models/sj_tele.py b/indoteknik_custom/models/sj_tele.py index 029adcbe..d44aa338 100644 --- a/indoteknik_custom/models/sj_tele.py +++ b/indoteknik_custom/models/sj_tele.py @@ -47,7 +47,7 @@ class SjTele(models.Model): def woi(self): bot_mqdd = '8203414501:AAHy_XwiUAVrgRM2EJzW7sZx9npRLITZpb8' - chat_id_mqdd = '-4885333032' + chat_id_mqdd = '-1003087280519' api_base = f'https://api.telegram.org/bot{bot_mqdd}' data = self.search([], order='create_date asc', limit=15) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 78a49ee4..35d408a1 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -307,6 +307,7 @@ class StockPicking(models.Model): ('delay', 'Delay By Vendor'), ('urgent', 'Urgent Delivery'), ], string='Reason Change Date Planned', tracking=True) + delivery_date = fields.Datetime(string='Delivery Date', copy=False) def _get_kgx_awb_number(self): """Menggabungkan name dan origin untuk membuat AWB Number""" diff --git a/indoteknik_custom/report/purchase_report.xml b/indoteknik_custom/report/purchase_report.xml index 150b7af2..dd19340d 100644 --- a/indoteknik_custom/report/purchase_report.xml +++ b/indoteknik_custom/report/purchase_report.xml @@ -61,7 +61,9 @@ <td style="width:50%; border:1px solid #ccc; border-radius:8px; padding:10px; background:#fcfcfc; vertical-align:top;"> <strong style="color:#d32f2f;">Alamat Pengiriman</strong><br/> PT. Indoteknik Dotcom Gemilang<br/> - Jl. Bandengan Utara Raya No. 85A, 8-9 RT.3/RW.16, Penjaringan, Kecamatan Penjaringan, Jkt Utara<br/> + Jl. Bandengan Utara Komp A 8 B + RT. Penjaringan, Kec. Penjaringan, Jakarta + (BELAKANG INDOMARET)<br/> Daerah Khusus Ibukota Jakarta 14440 </td> <td style="width:50%; border:1px solid #ccc; border-radius:8px; padding:10px; background:#fcfcfc; vertical-align:top;"> diff --git a/indoteknik_custom/views/mail_template_invoice_reminder.xml b/indoteknik_custom/views/mail_template_invoice_reminder.xml index 13c02a08..3534f7f6 100644 --- a/indoteknik_custom/views/mail_template_invoice_reminder.xml +++ b/indoteknik_custom/views/mail_template_invoice_reminder.xml @@ -17,6 +17,7 @@ style="border-collapse:collapse; font-size:12px; border:1px solid #ddd;"> <thead> <tr style="background-color:#f2f2f2; text-align:left;"> + <th style="border:1px solid #ddd;">No.</th> <th style="border:1px solid #ddd;">Customer</th> <th style="border:1px solid #ddd;">No. PO</th> <th style="border:1px solid #ddd;">Invoice Number</th> diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index a0ac9824..7feec934 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -99,7 +99,7 @@ <field name="total_delivery_amt" attrs="{'required': [('partner_id', 'in', [9688, 29712])]}"/> <field name="product_bom_id" attrs="{'invisible': [('product_bom_id', '=', None)]}"/> <field name="manufacturing_id" attrs="{'invisible': [('product_bom_id', '=', None)]}"/> - <field name="show_description" attrs="{'invisible': [('partner_id', '!=', 5571)]}" widget="boolean_toggle"/> + <field name="show_description" attrs="{'invisible': [('partner_id', 'not in', [5571, 35475, 38198, 88261,37905, 9688, 20625, 1371, 37902, 12119])]}" widget="boolean_toggle"/> <!-- <field name="move_id" domain="[('move_type','=','entry')]" context="{'form_view_ref': 'account.view_move_form'}" options="{'no_create': True}"/> --> </field> <field name="amount_total" position="after"> diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index fc8be790..abaf347d 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -28,6 +28,10 @@ <!-- <field name="countdown_hours" optional="hide"/> <field name="countdown_ready_to_ship" /> --> </field> + + <field name="scheduled_date" position="after"> + <field name="delivery_date" widget="remaining_days" optional="hide"/> + </field> <field name="partner_id" position="after"> <field name="area_name" optional="hide"/> <field name="purchase_representative_id"/> @@ -140,6 +144,9 @@ <field name="scheduled_date" position="attributes"> <attribute name="readonly">1</attribute> </field> + <field name="arrival_time" position="after"> + <field name="delivery_date" attrs="{'invisible': [('location_id', '!=', 60)]}"/> + </field> <xpath expr="//field[@name='move_ids_without_package']/form/group/field[@name='description_picking']" position="after"> <field name="product_image" widget="image" string="Product Image"/> |
