From 52754dc7663c45a7609e5d4a57119ef26ecb5190 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 17 Dec 2025 16:29:17 +0700 Subject: (andri) fix grand total reminder inv mail --- indoteknik_custom/models/account_move.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index e36b9920..b05ec7ff 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -330,7 +330,8 @@ class AccountMove(models.Model): grand_total = 0 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 + # grand_total += inv.amount_total + grand_total += inv.amount_residual invoice_table_rows += f""" {idx} -- cgit v1.2.3 From a8de47d71da75c9351da76ac87ba6046d5b152c3 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 17 Dec 2025 16:51:17 +0700 Subject: (andri) penambahan field pada tree realisasi PUM --- indoteknik_custom/models/advance_payment_request.py | 2 +- indoteknik_custom/views/advance_payment_settlement.xml | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index d379eac8..f973a9da 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -1072,7 +1072,7 @@ class AdvancePaymentSettlement(models.Model): ], string = "Banyaknya Attachment", default='one_for_one_line') move_id = fields.Many2one('account.move', string='Journal Entries', domain=[('move_type', '=', 'entry')]) - is_cab_visible = fields.Boolean(string='Is Journal Uang Muka Visible', compute='_compute_is_cab_visible') + is_cab_visible = fields.Boolean(string='Status Jurnal', compute='_compute_is_cab_visible') user_id = fields.Many2one( 'res.users', diff --git a/indoteknik_custom/views/advance_payment_settlement.xml b/indoteknik_custom/views/advance_payment_settlement.xml index a77baffe..c2b6a26f 100644 --- a/indoteknik_custom/views/advance_payment_settlement.xml +++ b/indoteknik_custom/views/advance_payment_settlement.xml @@ -163,10 +163,13 @@ - - + + + + + -- cgit v1.2.3 From 48e81bf679958286b15812ed5c8982b25e4e3843 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 18 Dec 2025 09:28:59 +0700 Subject: add customer name in commission internal line --- indoteknik_custom/models/commission_internal.py | 3 ++- indoteknik_custom/views/commission_internal.xml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/commission_internal.py b/indoteknik_custom/models/commission_internal.py index cd6da380..4de5c723 100644 --- a/indoteknik_custom/models/commission_internal.py +++ b/indoteknik_custom/models/commission_internal.py @@ -259,6 +259,7 @@ class CommissionInternal(models.Model): 'res_name': data['res_name'], 'res_id': data['res_id'], 'name': data['name'], + 'customer': data['customer'], 'salesperson': data['salesperson'], 'totalamt': data['amount_total'], 'uang_masuk_line_id': data['uang_masuk_line_id'], @@ -271,7 +272,6 @@ class CommissionInternal(models.Model): 'helper1': data['helper1'], 'helper2': data['helper2'] }]) - print(1) # this button / method works for train data in July 2025 def calculate_commission_internal_from_keyword(self): @@ -390,3 +390,4 @@ class CommissionInternalResult(models.Model): helper3 = fields.Char(string='Helper3') helper4 = fields.Char(string='Helper4') helper5 = fields.Char(string='Helper5') + customer = fields.Char(string='Customer') diff --git a/indoteknik_custom/views/commission_internal.xml b/indoteknik_custom/views/commission_internal.xml index 2f3db5b0..d84eb4b8 100644 --- a/indoteknik_custom/views/commission_internal.xml +++ b/indoteknik_custom/views/commission_internal.xml @@ -108,6 +108,7 @@ + -- cgit v1.2.3 From cd78a30609e0fa956458dabc02c4f199459cee9a Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 18 Dec 2025 10:33:07 +0700 Subject: add error if click result more than once --- indoteknik_custom/models/commission_internal.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/indoteknik_custom/models/commission_internal.py b/indoteknik_custom/models/commission_internal.py index 4de5c723..efe0f4fb 100644 --- a/indoteknik_custom/models/commission_internal.py +++ b/indoteknik_custom/models/commission_internal.py @@ -178,6 +178,9 @@ class CommissionInternal(models.Model): # fill later TODO @stephan def calculate_commission_internal_result(self): + if self.commission_internal_result: + raise UserError('Hapus semua isi table result jika ingin di create result ulang') + exception = ['ONGKOS KIRIM SO/20'] query = [ ('commission_internal_id.id', '=', self.id), -- cgit v1.2.3 From 1baaa11159d295684b54104160dbaa96215f9742 Mon Sep 17 00:00:00 2001 From: Mqdd Date: Thu, 18 Dec 2025 11:18:32 +0700 Subject: merge & add tracking button in commission internal --- indoteknik_custom/models/account_move.py | 3 ++- indoteknik_custom/models/advance_payment_request.py | 2 +- indoteknik_custom/models/commission_internal.py | 11 +++++++++-- indoteknik_custom/views/advance_payment_settlement.xml | 7 +++++-- indoteknik_custom/views/commission_internal.xml | 1 + 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index e36b9920..b05ec7ff 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -330,7 +330,8 @@ class AccountMove(models.Model): grand_total = 0 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 + # grand_total += inv.amount_total + grand_total += inv.amount_residual invoice_table_rows += f""" {idx} diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index d379eac8..f973a9da 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -1072,7 +1072,7 @@ class AdvancePaymentSettlement(models.Model): ], string = "Banyaknya Attachment", default='one_for_one_line') move_id = fields.Many2one('account.move', string='Journal Entries', domain=[('move_type', '=', 'entry')]) - is_cab_visible = fields.Boolean(string='Is Journal Uang Muka Visible', compute='_compute_is_cab_visible') + is_cab_visible = fields.Boolean(string='Status Jurnal', compute='_compute_is_cab_visible') user_id = fields.Many2one( 'res.users', diff --git a/indoteknik_custom/models/commission_internal.py b/indoteknik_custom/models/commission_internal.py index cd6da380..ce9c564d 100644 --- a/indoteknik_custom/models/commission_internal.py +++ b/indoteknik_custom/models/commission_internal.py @@ -1,4 +1,4 @@ -from odoo import models, api, fields +from odoo import models, api, fields, _ from odoo.exceptions import AccessError, UserError, ValidationError from datetime import timedelta, date import logging @@ -178,6 +178,9 @@ class CommissionInternal(models.Model): # fill later TODO @stephan def calculate_commission_internal_result(self): + if self.commission_internal_result: + raise UserError('Hapus semua isi table result jika ingin di create result ulang') + exception = ['ONGKOS KIRIM SO/20'] query = [ ('commission_internal_id.id', '=', self.id), @@ -259,6 +262,7 @@ class CommissionInternal(models.Model): 'res_name': data['res_name'], 'res_id': data['res_id'], 'name': data['name'], + 'customer': data['customer'], 'salesperson': data['salesperson'], 'totalamt': data['amount_total'], 'uang_masuk_line_id': data['uang_masuk_line_id'], @@ -271,7 +275,7 @@ class CommissionInternal(models.Model): 'helper1': data['helper1'], 'helper2': data['helper2'] }]) - print(1) + self.message_post(body=("Commission Internal Result generated by %s at %s.") % (self.env.user.name, fields.Datetime.now())) # this button / method works for train data in July 2025 def calculate_commission_internal_from_keyword(self): @@ -286,6 +290,7 @@ class CommissionInternal(models.Model): self._calculate_keyword_undefined() # execute helper2 for parse the label into INV/ or SO/ and switch SO to INV if available self._parse_label_helper2() + self.message_post(body=("Commission Internal Line calculated by %s at %s.") % (self.env.user.name, fields.Datetime.now())) def generate_commission_from_generate_ledger(self): if self.commission_internal_line: @@ -321,6 +326,7 @@ class CommissionInternal(models.Model): 'balance': ledger.balance }]) count += 1 + self.message_post(body=("Commission Internal Line generated by %s at %s") % (self.env.user.name, fields.Datetime.now())) _logger.info("Commission Internal Line generated %s" % count) @@ -390,3 +396,4 @@ class CommissionInternalResult(models.Model): helper3 = fields.Char(string='Helper3') helper4 = fields.Char(string='Helper4') helper5 = fields.Char(string='Helper5') + customer = fields.Char(string='Customer') diff --git a/indoteknik_custom/views/advance_payment_settlement.xml b/indoteknik_custom/views/advance_payment_settlement.xml index a77baffe..c2b6a26f 100644 --- a/indoteknik_custom/views/advance_payment_settlement.xml +++ b/indoteknik_custom/views/advance_payment_settlement.xml @@ -163,10 +163,13 @@ - - + + + + + diff --git a/indoteknik_custom/views/commission_internal.xml b/indoteknik_custom/views/commission_internal.xml index 2f3db5b0..d84eb4b8 100644 --- a/indoteknik_custom/views/commission_internal.xml +++ b/indoteknik_custom/views/commission_internal.xml @@ -108,6 +108,7 @@ + -- cgit v1.2.3 From cf0fdfe82fd59f58b2bd0e8d9006b8a16f8d30ca Mon Sep 17 00:00:00 2001 From: Mqdd Date: Mon, 22 Dec 2025 11:38:26 +0700 Subject: rpo create po without SO. change flow --- indoteknik_custom/models/requisition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 748642eb..f292b760 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -102,7 +102,7 @@ class Requisition(models.Model): def create_po_from_requisition(self): self.check_product_line_to_so() - if not self.sales_approve and not self.merchandise_approve: + if not self.sales_approve or not self.merchandise_approve: raise UserError('Harus Di Approve oleh Darren atau Rafly') if not self.requisition_lines: raise UserError('Tidak ada Lines, belum bisa create PO') -- cgit v1.2.3 From b48907913127a1213c183a02d7202bcd61482dd5 Mon Sep 17 00:00:00 2001 From: Mqdd Date: Mon, 22 Dec 2025 11:57:37 +0700 Subject: fix approve and create PO when no SO --- indoteknik_custom/models/requisition.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index f292b760..c2f8080f 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -102,15 +102,14 @@ class Requisition(models.Model): def create_po_from_requisition(self): self.check_product_line_to_so() - if not self.sales_approve or not self.merchandise_approve: - raise UserError('Harus Di Approve oleh Darren atau Rafly') + if not (self.sales_approve or self.merchandise_approve): + raise UserError('Tidak bisa create PO karena belukm diapprove oleh Darren atau Rafly') if not self.requisition_lines: raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: raise UserError('Sudah pernah di create PO') - if not self.sale_order_id and (not self.sales_approve or not self.merchandise_approve): + if not self.sale_order_id and not self.sales_approve or self.merchandise_approve: raise UserError('Tidak ada link dengan Sales Order, tidak bisa dihitung sebagai Plafon Qty di PO') - vendor_ids = self.env['requisition.line'].read_group([ ('requisition_id', '=', self.id), ('partner_id', '!=', False) -- cgit v1.2.3 From 56a252e8accd9c330826ea2e8e596792b5925af9 Mon Sep 17 00:00:00 2001 From: Mqdd Date: Mon, 22 Dec 2025 12:04:51 +0700 Subject: fix --- indoteknik_custom/models/requisition.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index c2f8080f..832e4c72 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -108,8 +108,11 @@ class Requisition(models.Model): raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: raise UserError('Sudah pernah di create PO') - if not self.sale_order_id and not self.sales_approve or self.merchandise_approve: - raise UserError('Tidak ada link dengan Sales Order, tidak bisa dihitung sebagai Plafon Qty di PO') + if not self.sale_order_id and not (self.sales_approve or self.merchandise_approve): + raise UserError( + 'Tidak ada link dengan Sales Order, tidak bisa dihitung sebagai Plafon Qty di PO' + ) + vendor_ids = self.env['requisition.line'].read_group([ ('requisition_id', '=', self.id), ('partner_id', '!=', False) -- cgit v1.2.3 From 739efe5bbcce20b3fdb524d9045a310ffa84c0f1 Mon Sep 17 00:00:00 2001 From: Mqdd Date: Tue, 23 Dec 2025 10:59:19 +0700 Subject: action seen purchasing job --- indoteknik_custom/models/purchasing_job.py | 52 ++++++++++++++++++------------ indoteknik_custom/views/purchasing_job.xml | 11 ++++++- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/indoteknik_custom/models/purchasing_job.py b/indoteknik_custom/models/purchasing_job.py index 3151f0f6..29928bbb 100644 --- a/indoteknik_custom/models/purchasing_job.py +++ b/indoteknik_custom/models/purchasing_job.py @@ -61,11 +61,23 @@ class PurchasingJob(models.Model): @api.depends('so_number') def _get_check_pj(self): - Seen = self.env['purchasing.job.seen'] + seen = self.env['purchasing.job.seen'] for rec in self: - seen = Seen.search([('product_id', '=', rec.product_id.id)], limit=1) + seen = seen.search([('product_id', '=', rec.product_id.id)], limit=1) rec.check_pj = bool(seen and seen.so_snapshot == rec.so_number) + + def _set_as_seen(self): + seen_model = self.env['purchasing.job.seen'] + + for rec in self: + seen_model.create({ + 'user_id': self.env.user.id, + 'product_id': rec.product_id.id, + 'so_snapshot': rec.so_number, + }) + rec.check_pj = True + def unlink(self): # Example: Delete related records from the underlying model underlying_records = self.env['purchasing.job'].search([ @@ -78,7 +90,7 @@ class PurchasingJob(models.Model): states = self.env['purchasing.job.state'].search([ ('purchasing_job_id', '=', self.id), ],limit=1, order='id desc') - + return { 'name': _('Purchasing Job State'), 'view_mode': 'form', @@ -115,12 +127,12 @@ class PurchasingJob(models.Model): END AS purchase_representative_id FROM v_procurement_monitoring_by_product pmp LEFT JOIN purchasing_job_state pjs ON pjs.purchasing_job_id = pmp.product_id - LEFT JOIN ( + LEFT JOIN ( SELECT vso.product_id, max(sol.vendor_id) as vendor_id FROM v_sales_outstanding vso LEFT JOIN sale_order_line sol ON sol.id = vso.sale_line_id - group by vso.product_id + group by vso.product_id ) sub ON sub.product_id = pmp.product_id WHERE pmp.action = 'kurang'::text AND sub.vendor_id IS NOT NULL GROUP BY pmp.product_id, pmp.brand, pmp.item_code, pmp.product, pmp.action, sub.vendor_id, pmp.so_number; @@ -132,7 +144,7 @@ class PurchasingJob(models.Model): 'product_ids': [x.id for x in self] } return action - + def generate_request_po(self): # print(1) # TODO create document automatic purchase @@ -180,7 +192,7 @@ class PurchasingJob(models.Model): class OutstandingSales(models.Model): _name = 'v.sales.outstanding' - _auto = False + _auto = False _rec_name = 'move_id' id = fields.Integer() @@ -205,21 +217,21 @@ class OutstandingSales(models.Model): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(""" CREATE OR REPLACE VIEW v_sales_outstanding AS ( - select sm.id, - sm.id as move_id, - sp.id as picking_id, - sm.product_id, - so.id as sale_id, - sol.id as sale_line_id, - rp.id as partner_id, - so.user_id as salesperson_id, + select sm.id, + sm.id as move_id, + sp.id as picking_id, + sm.product_id, + so.id as sale_id, + sol.id as sale_line_id, + rp.id as partner_id, + so.user_id as salesperson_id, so.partner_invoice_id, - sp.origin, - rp2.name as salesperson, - coalesce(pp.default_code, pt.default_code) as item_code, + sp.origin, + rp2.name as salesperson, + coalesce(pp.default_code, pt.default_code) as item_code, pt.name as product, - sm.product_uom_qty as outgoing, - xm.x_name as brand, + sm.product_uom_qty as outgoing, + xm.x_name as brand, rp.name as invoice_partner, so.create_date as sale_order_create_date from stock_move sm diff --git a/indoteknik_custom/views/purchasing_job.xml b/indoteknik_custom/views/purchasing_job.xml index 2466e7be..6b8baa53 100644 --- a/indoteknik_custom/views/purchasing_job.xml +++ b/indoteknik_custom/views/purchasing_job.xml @@ -98,6 +98,15 @@ action = records.open_form_multi_generate_request_po() + + Seen Selected Job + + + form,list + code + action = records._set_as_seen() + + - \ No newline at end of file + -- cgit v1.2.3 From 16286f2488b44b0de9b2200003ab2158b7a78fa8 Mon Sep 17 00:00:00 2001 From: Mqdd Date: Wed, 31 Dec 2025 09:55:23 +0700 Subject: remove vals rpo --- indoteknik_custom/models/requisition.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 832e4c72..c0489adc 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -90,7 +90,7 @@ class Requisition(models.Model): def button_approve(self): state = ['done', 'sale'] - self.check_product_line_to_so() + # self.check_product_line_to_so() if self.sale_order_id.state in state: raise UserError('SO sudah Confirm, akan berakibat double Purchase melalui PJ') if self.env.user.id not in [21, 19, 28]: @@ -101,7 +101,7 @@ class Requisition(models.Model): self.merchandise_approve = True def create_po_from_requisition(self): - self.check_product_line_to_so() + # self.check_product_line_to_so() if not (self.sales_approve or self.merchandise_approve): raise UserError('Tidak bisa create PO karena belukm diapprove oleh Darren atau Rafly') if not self.requisition_lines: -- cgit v1.2.3 From ab57a15ea33846c97ab67295668c4f6d42c8be33 Mon Sep 17 00:00:00 2001 From: Mqdd Date: Wed, 31 Dec 2025 11:34:49 +0700 Subject: fix eror seen pj --- indoteknik_custom/models/purchasing_job.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/indoteknik_custom/models/purchasing_job.py b/indoteknik_custom/models/purchasing_job.py index 29928bbb..7a7e70b4 100644 --- a/indoteknik_custom/models/purchasing_job.py +++ b/indoteknik_custom/models/purchasing_job.py @@ -68,14 +68,24 @@ class PurchasingJob(models.Model): def _set_as_seen(self): - seen_model = self.env['purchasing.job.seen'] + Seen = self.env['purchasing.job.seen'] + for rec in self: - seen_model.create({ - 'user_id': self.env.user.id, - 'product_id': rec.product_id.id, - 'so_snapshot': rec.so_number, - }) + seen = Seen.search([ + ('product_id', '=', rec.product_id.id) + ], limit=1) + if seen: + seen.write({ + 'so_snapshot': rec.so_number, + 'seen_date': fields.Datetime.now(), + 'user_id': rec.env.user.id, }) + else: + Seen.create({ + 'user_id': self.env.user.id, + 'product_id': rec.product_id.id, + 'so_snapshot': rec.so_number, + }) rec.check_pj = True def unlink(self): -- cgit v1.2.3 From b1cec830168ab113627bd10383f80d0e33c5b680 Mon Sep 17 00:00:00 2001 From: Mqdd Date: Wed, 31 Dec 2025 14:59:33 +0700 Subject: comment date maturity --- indoteknik_custom/models/account_move.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index b05ec7ff..37808f94 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -776,10 +776,10 @@ class AccountMove(models.Model): # if not self.env.user.is_accounting: # raise UserError('Hanya Accounting yang bisa Posting') # if self._name == 'account.move': - for entry in self: - entry.date_completed = datetime.utcnow() - for line in entry.line_ids: - line.date_maturity = entry.date + # for entry in self: + # entry.date_completed = datetime.utcnow() + # for line in entry.line_ids: + # line.date_maturity = entry.date return res def button_draft(self): @@ -957,4 +957,4 @@ class SyncPromiseDateWizardLine(models.TransientModel): new_invoice_day_to_due = fields.Integer(related="invoice_id.new_invoice_day_to_due", string="New Day Due", readonly=True) date_terima_tukar_faktur = fields.Date(related="invoice_id.date_terima_tukar_faktur", string="Tanggal Terima Tukar Faktur", readonly=True) amount_total = fields.Monetary(related="invoice_id.amount_total", string="Total", readonly=True) - currency_id = fields.Many2one(related="invoice_id.currency_id", readonly=True) \ No newline at end of file + currency_id = fields.Many2one(related="invoice_id.currency_id", readonly=True) -- cgit v1.2.3 From bd1654bf8ffb0289492515900756df23e9e18586 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Fri, 2 Jan 2026 09:45:45 +0700 Subject: fix journal ongkir --- indoteknik_custom/models/refund_sale_order.py | 81 ++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 0ff0a2f0..c22e84ab 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -348,12 +348,38 @@ class RefundSaleOrder(models.Model): domain.append(('ref', 'ilike', n)) moves3 = self.env['account.move'].search(domain) + moves_ongkir = self.env['account.move'] + if so_ids: + so_records = self.env['sale.order'].browse(so_ids) + so_names = so_records.mapped('name') + + domain = [ + ('journal_id', '=', 11), + ('state', '=', 'posted'), + ('sale_id', '=', False), + '|', + ('ref', 'ilike', 'pendapatan ongkos kirim'), + ('ref', 'ilike', 'ongkir'), + '|', + ('line_ids.account_id', '=', 450), + ('line_ids.account_id', '=', 668), + ] + + if so_names: + domain += ['|'] * (len(so_names) - 1) + for name in so_names: + domain.append(('ref', 'ilike', name)) + + moves_ongkir = self.env['account.move'].search(domain) + + has_moves = bool(moves) has_moves2 = bool(moves2) has_moves3 = bool(moves3) has_piutangmdr = bool(piutangmdr) has_piutangbca = bool(piutangbca) has_misc = bool(misc) + has_ongkir = bool(moves_ongkir) ssos = self.env['sale.order'].browse(so_ids) has_settlement = any(so.payment_status == 'settlement' for so in ssos) @@ -363,6 +389,8 @@ class RefundSaleOrder(models.Model): if has_moves: sisa_uang_masuk += sum(moves.mapped('amount_total_signed')) + if has_ongkir: + sisa_uang_masuk += sum(moves_ongkir.mapped('amount_total_signed')) if has_moves2: sisa_uang_masuk += sum(moves2.mapped('amount_total_signed')) if has_moves3: @@ -615,7 +643,31 @@ class RefundSaleOrder(models.Model): ('state', '=', 'posted'), ]) - all_moves = moves | piutangbca | piutangmdr | misc | moves2 + moves_ongkir = self.env['account.move'] + if rec.sale_order_ids: + so_records = rec.sale_order_ids + so_names = so_records.mapped('name') + + domain = [ + ('journal_id', '=', 11), + ('state', '=', 'posted'), + ('sale_id', '=', False), + '|', + ('ref', 'ilike', 'pendapatan ongkos kirim'), + ('ref', 'ilike', 'ongkir'), + '|', + ('line_ids.account_id', '=', 450), + ('line_ids.account_id', '=', 668), + ] + + if so_names: + domain += ['|'] * (len(so_names) - 1) + for name in so_names: + domain.append(('ref', 'ilike', name)) + + moves_ongkir = self.env['account.move'].search(domain) + + all_moves = moves | piutangbca | piutangmdr | misc | moves2 | moves_ongkir for move in all_moves: url = f"/web#id={move.id}&model=account.move&view_type=form" @@ -683,6 +735,30 @@ class RefundSaleOrder(models.Model): ('state', '=', 'posted'), ]) + moves_ongkir = self.env['account.move'] + if so_ids: + so_records = self.env['sale.order'].browse(so_ids) + so_names = so_records.mapped('name') + + domain = [ + ('journal_id', '=', 11), + ('state', '=', 'posted'), + ('sale_id', '=', False), + '|', + ('ref', 'ilike', 'pendapatan ongkos kirim'), + ('ref', 'ilike', 'ongkir'), + '|', + ('line_ids.account_id', '=', 450), + ('line_ids.account_id', '=', 668), + ] + + if so_names: + domain += ['|'] * (len(so_names) - 1) + for name in so_names: + domain.append(('ref', 'ilike', name)) + + moves_ongkir = self.env['account.move'].search(domain) + moves2 = self.env['account.move'] if so_ids: so_records = self.env['sale.order'].browse(so_ids) @@ -724,6 +800,7 @@ class RefundSaleOrder(models.Model): has_piutangmdr = bool(piutangmdr) has_piutangbca = bool(piutangbca) has_misc = bool(misc) + has_ongkir = bool(moves_ongkir) ssos = self.env['sale.order'].browse(so_ids) has_settlement = any(so.payment_status == 'settlement' for so in ssos) @@ -743,6 +820,8 @@ class RefundSaleOrder(models.Model): sisa_uang_masuk += sum(piutangmdr.mapped('amount_total_signed')) if has_misc: sisa_uang_masuk += sum(misc.mapped('amount_total_signed')) + if has_ongkir: + sisa_uang_masuk += sum(moves_ongkir.mapped('amount_total_signed')) if has_settlement and not has_journal: sisa_uang_masuk += sum(ssos.mapped('gross_amount')) -- cgit v1.2.3 From 7b0a84a6e834fc20784812536e17adb5f7817cc4 Mon Sep 17 00:00:00 2001 From: Mqdd Date: Mon, 5 Jan 2026 18:48:14 +0700 Subject: copy date maturity to date now --- indoteknik_custom/models/account_move.py | 84 ++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 37808f94..e1360cfa 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -49,7 +49,7 @@ class AccountMove(models.Model): states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", help="Dipakai untuk alamat tempel") - + address_invoice = fields.Char(related='real_invoice_id.street', string='Invoice Address', readonly=True) bills_efaktur_exporter = fields.Many2one('res.users', string='Efaktur Exporter') bills_date_efaktur = fields.Datetime(string="eFaktur Exported Date", required=False) @@ -176,7 +176,7 @@ class AccountMove(models.Model): lambda p: move.id in p.reconciled_invoice_ids.ids ) - if payment: + if payment: move.payment_date = payment[0].date elif move.reklas_misc_id: move.payment_date = move.reklas_misc_id.date @@ -185,7 +185,7 @@ class AccountMove(models.Model): def action_sync_promise_date(self): self.ensure_one() - finance_user_ids = [688] + finance_user_ids = [688] is_it = self.env.user.has_group('indoteknik_custom.group_role_it') if self.env.user.id not in finance_user_ids and not is_it: raise UserError('Hanya Finance (Widya) yang dapat menggunakan fitur ini.') @@ -286,7 +286,7 @@ class AccountMove(models.Model): 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 @@ -300,11 +300,11 @@ class AccountMove(models.Model): # skip semua jika partner centang dont_send_reminder_inv_all if partner.dont_send_reminder_inv_all: _logger.info(f"Partner {partner.name} skip karena dont_send_reminder_inv_all aktif") - continue + continue # cek parent hanya dengan flag dont_sent_reminder_inv_parent if not partner.dont_send_reminder_inv_parent and partner.email: emails.append(partner.email) - + # Ambil child contact yang di-checklist reminder_invoices reminder_contacts = self.env['res.partner'].search([ ('parent_id', '=', partner.id), @@ -312,7 +312,7 @@ class AccountMove(models.Model): ('email', '!=', False), ]) _logger.info(f"Email Reminder Child {reminder_contacts}") - + emails += reminder_contacts.mapped('email') if reminder_contacts: _logger.info(f"Email Reminder Child {reminder_contacts}") @@ -381,7 +381,7 @@ class AccountMove(models.Model): # tempo_link = 'http://localhost:2100/my/tempo' # payment_term = partner.previous_payment_term_id if partner.is_cbd_locked else partner.property_payment_term_id payment_term = invs[0].invoice_payment_term_id - + limit_info_html = f"""

Informasi Tambahan:

    @@ -391,11 +391,11 @@ class AccountMove(models.Model): Sisa Kredit Limit: {formatLang(self.env, blocking_limit - outstanding_amount, currency_obj=currency)}
  • - Kredit Limit Terpakai: {formatLang(self.env, outstanding_amount, currency_obj=currency)} + Kredit Limit Terpakai: {formatLang(self.env, outstanding_amount, currency_obj=currency)} ({len(outstanding_invoices)} Transaksi)
  • - Jatuh Tempo: {formatLang(self.env, overdue_amount, currency_obj=currency)} + Jatuh Tempo: {formatLang(self.env, overdue_amount, currency_obj=currency)} ({len(overdue_invoices)} Invoice)
@@ -472,7 +472,7 @@ class AccountMove(models.Model): values = { 'subject': f"Reminder Invoice Due - {partner.name}", # 'email_to': 'andrifebriyadiputra@gmail.com', - 'email_to': email_to, + 'email_to': email_to, 'email_from': 'finance@indoteknik.co.id', 'email_cc': ",".join(sorted(set(cc_list))), 'body_html': body_html, @@ -528,7 +528,7 @@ class AccountMove(models.Model): # 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 @@ -589,7 +589,7 @@ class AccountMove(models.Model): template = self.env.ref('indoteknik_custom.mail_template_efaktur_document') for record in records: - if record.invoice_payment_term_id.id == 26: + if record.invoice_payment_term_id.id == 26: attachment = self.generate_attachment(record) email_values = { 'attachment_ids': [(4, attachment.id)] @@ -605,7 +605,7 @@ class AccountMove(models.Model): @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) # Tambahan: jika ini Vendor Bill dan tanggal belum diisi @@ -640,13 +640,13 @@ class AccountMove(models.Model): record.flag_delivery_amt = True else: record.flag_delivery_amt = False - + def compute_delivery_amt_text(self): tb = Terbilang() for record in self: res = '' - + try: if record.sale_id.delivery_amt > 0: tb.parse(int(record.sale_id.delivery_amt)) @@ -654,7 +654,7 @@ class AccountMove(models.Model): record.delivery_amt_text = res + ' Rupiah' except: record.delivery_amt_text = res - + @api.constrains('bills_efaktur_document') def _constrains_efaktur_document(self): @@ -722,13 +722,35 @@ class AccountMove(models.Model): raise UserError('Data Hanya Bisa Di Cancel') return res + def copy(self, default=None): + default = dict(default or {}) + + today = fields.Date.context_today(self) + + if self.invoice_date_due: + default.update({ + 'invoice_date_due': today, + }) + + move = super().copy(default) + + for line in move.line_ids: + if ( + line.account_id.user_type_id.type in ('receivable', 'payable') + and line.date_maturity + ): + line.date_maturity = today + + return move + + def button_cancel(self): res = super(AccountMove, self).button_cancel() if self.move_type == 'entry': po = self.env['purchase.order'].search([ ('move_id', 'in', [self.id]) ]) - + for order in po: if order: order.is_create_uangmuka = False @@ -741,7 +763,7 @@ class AccountMove(models.Model): res = super(AccountMove, self).button_draft() if not self.env.user.is_accounting: raise UserError('Hanya Accounting yang bisa Reset to Draft') - + for rec in self.line_ids: if rec.write_date != rec.create_date: if rec.statement_line_id and not rec.statement_line_id.statement_id.is_edit and rec.statement_line_id.statement_id.state == 'confirm': @@ -751,7 +773,7 @@ class AccountMove(models.Model): def action_post(self): if self._name != 'account.move': return super(AccountMove, self).action_post() - + # validation cant qty invoice greater than qty order if self.move_type == 'out_invoice': query = ["&",("name","=",self.invoice_origin),"|",("state","=","sale"),("state","=","done")] @@ -777,7 +799,7 @@ class AccountMove(models.Model): # raise UserError('Hanya Accounting yang bisa Posting') # if self._name == 'account.move': # for entry in self: - # entry.date_completed = datetime.utcnow() + # entry.date_completed = datetime.utcnow() # for line in entry.line_ids: # line.date_maturity = entry.date @@ -787,7 +809,7 @@ class AccountMove(models.Model): if not self.env.user.is_accounting: raise UserError("Hanya Finence yang bisa ubah data") return res - + def _compute_invoice_day_to_due(self): for invoice in self: invoice_day_to_due = 0 @@ -801,7 +823,7 @@ class AccountMove(models.Model): new_invoice_day_to_due = new_invoice_day_to_due.days invoice.invoice_day_to_due = invoice_day_to_due invoice.new_invoice_day_to_due = new_invoice_day_to_due - + def _compute_bill_day_to_due(self): for rec in self: rec.bill_day_to_due = rec.payment_schedule or rec.invoice_date_due @@ -831,21 +853,21 @@ class AccountMove(models.Model): add_days += line.days due_date = tukar_date + timedelta(days=add_days) invoice.invoice_date_due = due_date - + def open_form_multi_update(self): action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_account_move_multi_update') action['context'] = { 'move_ids': [x.id for x in self] } return action - + def open_form_multi_update_bills(self): action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_account_move_multi_update_bills') action['context'] = { 'move_ids': [x.id for x in self] } return action - + @api.constrains('efaktur_id', 'ref', 'date', 'journal_id', 'name') def constrains_edit(self): for rec in self.line_ids: @@ -859,10 +881,10 @@ class AccountMove(models.Model): # if rec.statement_line_id and not rec.statement_line_id.statement_id.is_edit and rec.statement_line_id.statement_id.state == 'confirm': # raise UserError('Bank Statement di Lock, Minta admin reconcile untuk unlock') # return res - + def validate_faktur_for_export(self): - invoices = self.filtered(lambda inv: not inv.is_efaktur_exported and - inv.state == 'posted' and + invoices = self.filtered(lambda inv: not inv.is_efaktur_exported and + inv.state == 'posted' and inv.move_type == 'out_invoice') invalid_invoices = self - invoices @@ -874,10 +896,10 @@ class AccountMove(models.Model): )) return invoices - + def export_faktur_to_xml(self): valid_invoices = self - + coretax_faktur = self.env['coretax.faktur'].create({}) response = coretax_faktur.export_to_download( -- cgit v1.2.3 From 7b7e6e99fa88804a931125b500d02ac23082147c Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 7 Jan 2026 12:44:00 +0700 Subject: (andri) add cancel PUM reimburse --- .../models/advance_payment_request.py | 46 ++++++++++++++++++++++ indoteknik_custom/security/ir.model.access.csv | 1 + .../views/advance_payment_request.xml | 35 ++++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index f973a9da..d0805598 100644 --- a/indoteknik_custom/models/advance_payment_request.py +++ b/indoteknik_custom/models/advance_payment_request.py @@ -55,6 +55,7 @@ class AdvancePaymentRequest(models.Model): ('pengajuan2', 'Menunggu Approval AP'), ('pengajuan3', 'Menunggu Approval Pimpinan'), ('approved', 'Approved'), + ('cancel','Cancel') ], string='Status', default='draft', tracking=3, index=True, track_visibility='onchange') @@ -816,6 +817,51 @@ class AdvancePaymentRequest(models.Model): rec._compute_grand_total_reimburse() rec.nominal = rec.grand_total_reimburse return rec + + def action_open_cancel_wizard(self): + """Membuka Wizard Pop-up untuk Cancel PUM/Reimburse""" + self.ensure_one() + + if self.move_id: + raise UserError(_("Pengajuan tidak dapat dibatalkan karena Journal sudah terbentuk.")) + + if self.settlement_ids and any(s.status != 'draft' for s in self.settlement_ids): + raise UserError(_("Pengajuan tidak dapat dibatalkan karena sudah ada proses realisasi.")) + + return { + 'name': _('Alasan Pembatalan'), + 'type': 'ir.actions.act_window', + 'res_model': 'advance.payment.cancel.wizard', + 'view_mode': 'form', + 'target': 'new', + 'context': { + 'default_request_id': self.id, + } + } + +class AdvancePaymentCancelWizard(models.TransientModel): + _name = 'advance.payment.cancel.wizard' + _description = 'Wizard untuk Membatalkan PUM/Reimburse' + + request_id = fields.Many2one('advance.payment.request', string='Dokumen', readonly=True) + reason = fields.Text(string='Alasan Pembatalan', required=True) + + def action_confirm_cancel(self): + self.ensure_one() + request = self.request_id + if request.move_id: + raise UserError("Tidak bisa melakukan cancel karena Jurnal (Move ID) sudah terbentuk.") + + request.write({'status': 'cancel'}) + + request.message_post( + body=f"Pengajuan telah DIBATALKAN oleh {self.env.user.name}.
" + f"Alasan: {self.reason}", + message_type="comment", + subtype_xmlid="mail.mt_note", + ) + + return {'type': 'ir.actions.act_window_close'} class AdvancePaymentUsageLine(models.Model): diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index bc8dc2a4..d501de1a 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -199,6 +199,7 @@ access_advance_payment_settlement,access.advance.payment.settlement,model_advanc access_advance_payment_usage_line,access.advance.payment.usage.line,model_advance_payment_usage_line,,1,1,1,1 access_advance_payment_create_bill,access.advance.payment.create.bill,model_advance_payment_create_bill,,1,1,1,1 access_create_reimburse_cab_wizard_user,create.reimburse.cab.wizard user,model_create_reimburse_cab_wizard,,1,1,1,1 +access_advance_payment_cancel_wizard,advance.payment.cancel.wizard,model_advance_payment_cancel_wizard,,1,1,1,1 access_purchasing_job_seen,purchasing.job.seen,model_purchasing_job_seen,,1,1,1,1 access_tukar_guling_all_users,tukar.guling.all.users,model_tukar_guling,base.group_user,1,1,1,1 diff --git a/indoteknik_custom/views/advance_payment_request.xml b/indoteknik_custom/views/advance_payment_request.xml index dd6370c7..5abcf996 100644 --- a/indoteknik_custom/views/advance_payment_request.xml +++ b/indoteknik_custom/views/advance_payment_request.xml @@ -44,6 +44,11 @@ ('is_cab_visible', '=', True), ('type_request', '!=', 'reimburse') ]}"/> +