From ef5418ec79e17a4b233e6ea51ba66126a97ab0eb Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Fri, 19 Sep 2025 14:05:23 +0700 Subject: (andri) add validasi jika pengajuan assets harus isi notes --- indoteknik_custom/models/purchase_order.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 0304b5e2..b34ec926 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -1057,8 +1057,19 @@ class PurchaseOrder(models.Model): message="Produk "+line.product_id.name+" memiliki vendor berbeda dengan SO (Vendor PO: "+str(self.partner_id.name)+", Vendor SO: "+str(line.so_line_id.vendor_id.name)+")", sticky=True ) + + def _check_assets_note(self): + for order in self: + # Cari apakah ada line dengan produk ID 614469 ('Assets Mesin & Peralatan') + asset_line = order.order_line.filtered(lambda l: l.product_id.id == 595346) + if asset_line and not order.notes: + raise UserError(_( + "%s berisi produk 'Assets Mesin & Peralatan'. " + "Harap isi Notes untuk menjelaskan kebutuhan dan divisi terkait." + ) % order.name) def button_confirm(self): + self._check_assets_note() # self._check_payment_term() # check payment term res = super(PurchaseOrder, self).button_confirm() current_time = datetime.now() -- cgit v1.2.3 From b73575cc51ec58c02bccb711689d52e99e915c4e Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Sun, 21 Sep 2025 22:06:00 +0700 Subject: (andri) link PO to stock journal after validate BD --- indoteknik_custom/models/stock_picking.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 35d408a1..67106073 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1352,6 +1352,19 @@ class StockPicking(models.Model): if self.picking_type_code == 'outgoing' and 'BU/OUT/' in self.name: self.check_koli() res = super(StockPicking, self).button_validate() + + # Penambahan link PO di Stock Journal untuk Picking BD + for picking in self: + if picking.name and 'BD/' in picking.name and picking.purchase_id: + stock_journal = self.env['account.move'].search([ + ('ref', 'ilike', picking.name + '%'), + ('journal_id', '=', 3) # Stock Journal ID + ], limit = 1) + if stock_journal: + stock_journal.write({ + 'purchase_order_id': picking.purchase_id.id + }) + self.date_done = datetime.datetime.utcnow() self.state_reserve = 'done' self.final_seq = 0 -- cgit v1.2.3 From 7f97c16e662903d42b405c618c2e26a0b7ba5146 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 22 Sep 2025 10:44:51 +0700 Subject: (andri) cc email --- indoteknik_custom/models/letter_receivable.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/letter_receivable.py b/indoteknik_custom/models/letter_receivable.py index 1445800f..16034938 100644 --- a/indoteknik_custom/models/letter_receivable.py +++ b/indoteknik_custom/models/letter_receivable.py @@ -323,11 +323,23 @@ class SuratPiutang(models.Model): 'mimetype': 'application/pdf', }) + cc_list = [ + 'finance@indoteknik.co.id', + 'akbar@indoteknik.co.id', + 'stephan@indoteknik.co.id', + 'darren@indoteknik.co.id' + ] + + sales_email = self.sales_person_id.email if self.sales_person_id else None + if sales_email and sales_email not in cc_list: + cc_list.append(sales_email) + values = { # 'subject': template.subject.replace('${object.name}', self.name or ''), 'subject': perihal_map.get(self.perihal, self.perihal or '') + " - " + (self.partner_id.name or ''), 'email_to': self.tujuan_email, 'email_from': 'finance@indoteknik.co.id', + 'email_cc': ",".join(sorted(set(cc_list))), 'body_html': body_html, 'attachments': [(attachment.name, attachment.datas)], 'reply_to': 'finance@indoteknik.co.id', -- cgit v1.2.3 From a68f3c46bb02d7205ed1209e2b30b786bf4c7a3c Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 22 Sep 2025 11:19:17 +0700 Subject: (andri) payment difficulty pada inv --- indoteknik_custom/models/account_move.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 96f791c5..79bf5581 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -99,6 +99,8 @@ class AccountMove(models.Model): reminder_sent_date = fields.Date(string="Tanggal Reminder Terkirim") + payment_difficulty = fields.Selection(string="Payment Difficulty", related='partner_id.payment_difficulty', readonly=True) + customer_promise_date = fields.Date( string="Janji Bayar", help="Tanggal janji bayar dari customer setelah reminder dikirim.", -- cgit v1.2.3 From 327835caeb892b66813383456d83156c37b666e1 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 22 Sep 2025 15:39:32 +0700 Subject: (andri) add previous pt --- indoteknik_custom/models/res_partner.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 36570e8f..8aaee47e 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -194,6 +194,12 @@ class ResPartner(models.Model): default=_default_payment_term, tracking=3 ) + previous_payment_term_id = fields.Many2one( + 'account.payment.term', + string='Previous Payment Term', + readonly=True + ) + @api.depends("street", "street2", "city", "state_id", "country_id", "blok", "nomor", "rt", "rw", "kelurahan_id", "kecamatan_id") -- cgit v1.2.3 From 21f46424f4d879b8c703d8da7a6f8b3c20193ced Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 22 Sep 2025 17:23:21 +0700 Subject: (andri) fix reminder mail --- indoteknik_custom/models/account_move.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 96f791c5..d1485f1f 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -334,11 +334,13 @@ class AccountMove(models.Model): tempo_link = 'https://indoteknik.com/my/tempo' # 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 + limit_info_html = f"""

Informasi Tambahan:

  • Kredit Limit Anda: {formatLang(self.env, blocking_limit, currency_obj=currency)}
  • -
  • Status Detail Tempo: {partner.property_payment_term_id.name or 'Review'}
  • +
  • Status Detail Tempo: {partner.payment_term.name or 'Review'}
  • Sisa Kredit Limit: {formatLang(self.env, blocking_limit - outstanding_amount, currency_obj=currency)}
  • -- cgit v1.2.3 From d373212e2da13ef478b70c6d354807ee62484464 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 22 Sep 2025 17:25:34 +0700 Subject: (andri) fix --- indoteknik_custom/models/account_move.py | 1 - 1 file changed, 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index d1485f1f..edcfbdd5 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -333,7 +333,6 @@ class AccountMove(models.Model): currency = invs[0].currency_id if invs else partner.company_id.currency_id tempo_link = 'https://indoteknik.com/my/tempo' # 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 limit_info_html = f""" -- cgit v1.2.3 From ec0277a049ea2048785dba61711a24e9a4eb3363 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 22 Sep 2025 17:38:15 +0700 Subject: fix --- indoteknik_custom/models/account_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index edcfbdd5..60f0da74 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -339,7 +339,7 @@ class AccountMove(models.Model):

    Informasi Tambahan:

    • Kredit Limit Anda: {formatLang(self.env, blocking_limit, currency_obj=currency)}
    • -
    • Status Detail Tempo: {partner.payment_term.name or 'Review'}
    • +
    • Status Detail Tempo: {payment_term.name or 'Review'}
    • Sisa Kredit Limit: {formatLang(self.env, blocking_limit - outstanding_amount, currency_obj=currency)}
    • -- cgit v1.2.3 From 68594ca366d77396d9d2c8e707043fcb28a303f7 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Mon, 22 Sep 2025 17:38:45 +0700 Subject: fix --- indoteknik_custom/models/account_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 60f0da74..c7feac9e 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -339,7 +339,7 @@ class AccountMove(models.Model):

      Informasi Tambahan:

      • Kredit Limit Anda: {formatLang(self.env, blocking_limit, currency_obj=currency)}
      • -
      • Status Detail Tempo: {payment_term.name or 'Review'}
      • +
      • Status Detail Tempo: {payment_term.name or ''}
      • Sisa Kredit Limit: {formatLang(self.env, blocking_limit - outstanding_amount, currency_obj=currency)}
      • -- cgit v1.2.3 From f58e6e2fa013789bfa8ac8456cd29735a83a56d0 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 23 Sep 2025 05:34:07 +0700 Subject: (andri) fix --- indoteknik_custom/models/account_move.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 28e9156a..44b3cb76 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -335,7 +335,8 @@ class AccountMove(models.Model): currency = invs[0].currency_id if invs else partner.company_id.currency_id tempo_link = 'https://indoteknik.com/my/tempo' # 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 = 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:

        -- cgit v1.2.3 From fca5c08671169703d935161fc4bb0c5c05548a62 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 23 Sep 2025 08:32:19 +0700 Subject: fix validation error when creating SO in midnight --- indoteknik_custom/models/sale_order.py | 88 +++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 22 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 39830ffc..02ceb62b 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1700,57 +1700,101 @@ class SaleOrder(models.Model): # .format(eta_minimum.strftime('%d-%m-%Y'), eta_minimum.strftime('%d-%m-%Y')) # ) + # def _validate_expected_ready_ship_date(self): + # """ + # Pastikan expected_ready_to_ship tidak lebih awal dari SLA minimum. + # Dipanggil setiap onchange / simpan SO. + # """ + # for rec in self: + # # ───────────────────────────────────────────────────── + # # 1. Hanya validasi kalau field sudah terisi + # # (quotation baru / belum ada tanggal → abaikan) + # # ───────────────────────────────────────────────────── + # if not rec.expected_ready_to_ship: + # continue + # + # current_date = datetime.now() + # + # # ───────────────────────────────────────────────────── + # # 2. Hitung SLA berdasarkan product lines (jika ada) + # # ───────────────────────────────────────────────────── + # products = rec.order_line + # if products: + # sla_data = rec.calculate_sla_by_vendor(products) + # max_sla_time = sla_data.get('slatime', 1) + # else: + # # belum ada item → gunakan default 1 hari + # max_sla_time = 1 + # + # # offset hari libur / weekend + # offset, is3pm = rec.get_days_until_next_business_day(current_date) + # min_days = max_sla_time + offset - 1 + # eta_minimum = current_date + timedelta(days=min_days) + # + # # ───────────────────────────────────────────────────── + # # 3. Validasi - raise error bila terlalu cepat + # # ───────────────────────────────────────────────────── + # if rec.expected_ready_to_ship.date() < eta_minimum.date(): + # # set otomatis ke tanggal minimum supaya user tidak perlu + # # menekan Save dua kali + # rec.expected_ready_to_ship = eta_minimum + # + # raise ValidationError( + # _("Tanggal 'Expected Ready to Ship' tidak boleh " + # "lebih kecil dari %(tgl)s. Mohon pilih minimal %(tgl)s.") + # % {'tgl': eta_minimum.strftime('%d-%m-%Y')} + # ) + # else: + # # sinkronkan ke field commitment_date + # rec.commitment_date = rec.expected_ready_to_ship + def _validate_expected_ready_ship_date(self): """ Pastikan expected_ready_to_ship tidak lebih awal dari SLA minimum. Dipanggil setiap onchange / simpan SO. """ for rec in self: - # ───────────────────────────────────────────────────── - # 1. Hanya validasi kalau field sudah terisi - # (quotation baru / belum ada tanggal → abaikan) - # ───────────────────────────────────────────────────── if not rec.expected_ready_to_ship: continue - current_date = datetime.now() + # ADDED: gunakan "sekarang" lokal user, bukan datetime.now() server + current_date = fields.Datetime.context_timestamp(rec, fields.Datetime.now()) - # ───────────────────────────────────────────────────── - # 2. Hitung SLA berdasarkan product lines (jika ada) - # ───────────────────────────────────────────────────── + # Hitung SLA products = rec.order_line if products: sla_data = rec.calculate_sla_by_vendor(products) max_sla_time = sla_data.get('slatime', 1) else: - # belum ada item → gunakan default 1 hari max_sla_time = 1 - # offset hari libur / weekend + # offset hari libur/weekend offset, is3pm = rec.get_days_until_next_business_day(current_date) min_days = max_sla_time + offset - 1 eta_minimum = current_date + timedelta(days=min_days) - # ───────────────────────────────────────────────────── - # 3. Validasi - raise error bila terlalu cepat - # ───────────────────────────────────────────────────── - if rec.expected_ready_to_ship.date() < eta_minimum.date(): - # set otomatis ke tanggal minimum supaya user tidak perlu - # menekan Save dua kali - rec.expected_ready_to_ship = eta_minimum + if rec._fields['expected_ready_to_ship'].type == 'date': + exp_date_local = rec.expected_ready_to_ship + else: + exp_date_local = fields.Datetime.context_timestamp( + rec, rec.expected_ready_to_ship + ).date() + + if exp_date_local < eta_minimum.date(): + # (opsional) auto-set ke minimum → konversi balik ke UTC naive bila field Datetime + if rec._fields['expected_ready_to_ship'].type == 'date': + rec.expected_ready_to_ship = eta_minimum.date() + else: + rec.expected_ready_to_ship = eta_minimum.astimezone(pytz.UTC).replace(tzinfo=None) raise ValidationError( _("Tanggal 'Expected Ready to Ship' tidak boleh " - "lebih kecil dari %(tgl)s. Mohon pilih minimal %(tgl)s.") + "lebih kecil dari %(tgl)s. Mohon pilih minimal %(tgl)s.") % {'tgl': eta_minimum.strftime('%d-%m-%Y')} ) else: - # sinkronkan ke field commitment_date rec.commitment_date = rec.expected_ready_to_ship - - - @api.onchange('expected_ready_to_ship') #Hangle Onchange form Expected Ready to Ship def _onchange_expected_ready_ship_date(self): self._validate_expected_ready_ship_date() -- cgit v1.2.3 From 6d50b35724592c4f8c302204adcfbc0f5db3727f Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Tue, 23 Sep 2025 11:30:45 +0700 Subject: pull odoo backup --- indoteknik_custom/models/refund_sale_order.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index b8350829..d89954cc 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -859,19 +859,19 @@ class RefundSaleOrder(models.Model): if not rec.status or rec.status == 'draft': rec.status = 'pengajuan1' - elif rec.status == 'pengajuan1' and self.env.user.id == 19: + elif rec.status == 'pengajuan1': rec.status = 'pengajuan2' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_sales = now rec.position_sales = 'Sales Manager' - elif rec.status == 'pengajuan2' and self.env.user.id == 688: + elif rec.status == 'pengajuan2': rec.status = 'pengajuan3' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_ar = now rec.position_ar = 'AR' - elif rec.status == 'pengajuan3' and self.env.user.id == 7: + elif rec.status == 'pengajuan3': rec.status = 'refund' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_pimpinan = now @@ -902,6 +902,14 @@ class RefundSaleOrder(models.Model): for rec in self: if not is_fat: raise UserError("Hanya Finance yang dapat mengkonfirmasi pembayaran refund.") + is_journal = self.env['account.move'].search([ + ('refund_id', '=', rec.id), + ('state', '=', 'posted') + ]) + if not is_journal: + raise UserError("Journal Payment Refund belum dibuat, buat Journal Payment Refund sebelum confirm refund.") + if is_journal and rec.amount_refund != sum(is_journal.mapped('amount_total_signed')): + raise UserError("Total Refund dengan Total Journal Harus Sama.") if rec.status_payment == 'pending': rec.status_payment = 'done' rec.refund_date = fields.Date.context_today(self) -- cgit v1.2.3 From 5abefd1181a148c4caf9b5dd2082ee3b3e884751 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Tue, 23 Sep 2025 15:49:18 +0700 Subject: validate confirm journal refund --- indoteknik_custom/models/refund_sale_order.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index d4702210..eab25452 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -859,19 +859,19 @@ class RefundSaleOrder(models.Model): if not rec.status or rec.status == 'draft': rec.status = 'pengajuan1' - elif rec.status == 'pengajuan1': + elif rec.status == 'pengajuan1' and self.env.user.id == 19: rec.status = 'pengajuan2' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_sales = now rec.position_sales = 'Sales Manager' - elif rec.status == 'pengajuan2': + elif rec.status == 'pengajuan2' and self.env.user.id == 688: rec.status = 'pengajuan3' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_ar = now rec.position_ar = 'AR' - elif rec.status == 'pengajuan3': + elif rec.status == 'pengajuan3' and self.env.user.id == 7: rec.status = 'refund' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_pimpinan = now -- cgit v1.2.3 From 62f151bb1a2287d83844d5a838485b06948d531c Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 23 Sep 2025 17:13:13 +0700 Subject: bd return --- indoteknik_custom/models/stock_picking_return.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking_return.py b/indoteknik_custom/models/stock_picking_return.py index 88acf83c..6fc2d5c7 100644 --- a/indoteknik_custom/models/stock_picking_return.py +++ b/indoteknik_custom/models/stock_picking_return.py @@ -110,7 +110,7 @@ class ReturnPicking(models.TransientModel): if mapping_koli_vals: context['default_mapping_koli_ids'] = mapping_koli_vals - if picking.purchase_id or 'PO' in (picking.origin or ''): + if 'PO' in picking.name: _logger.info("Redirect ke Tukar Guling PO via purchase_id / origin") return { 'name': _('Tukar Guling PO'), -- cgit v1.2.3 From 7d09b515d62c9578301d3365d441958889aedc0f Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 23 Sep 2025 17:26:47 +0700 Subject: fix eror --- indoteknik_custom/models/stock_picking_return.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking_return.py b/indoteknik_custom/models/stock_picking_return.py index 6fc2d5c7..53a85f67 100644 --- a/indoteknik_custom/models/stock_picking_return.py +++ b/indoteknik_custom/models/stock_picking_return.py @@ -110,7 +110,7 @@ class ReturnPicking(models.TransientModel): if mapping_koli_vals: context['default_mapping_koli_ids'] = mapping_koli_vals - if 'PO' in picking.name: + if picking.name and any(k in picking.name.upper() for k in ('PUT', 'INPUT')): _logger.info("Redirect ke Tukar Guling PO via purchase_id / origin") return { 'name': _('Tukar Guling PO'), -- cgit v1.2.3 From 22c5def88445676675e1978e77471ef939f46daa Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 24 Sep 2025 09:37:15 +0700 Subject: pushh --- indoteknik_custom/models/sale_order.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 02ceb62b..fd872b53 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -398,6 +398,23 @@ class SaleOrder(models.Model): compute="_compute_partner_is_cbd_locked" ) + def action_open_partial_delivery_wizard(self): + self.ensure_one() + pickings = self.picking_ids.filtered(lambda p: p.state not in ['done', 'cancel'] and p.name and 'BU/PICK/' in p.name) + return { + 'type': 'ir.actions.act_window', + 'name': 'Partial Delivery', + 'res_model': 'partial.delivery.wizard', + 'view_mode': 'form', + 'target': 'new', + 'context': { + 'default_sale_id': self.id, + # kasih langsung list of int biar ga ribet di wizard + 'default_picking_ids': pickings.ids, + } + } + + @api.depends('partner_id.is_cbd_locked') def _compute_partner_is_cbd_locked(self): for order in self: @@ -1795,6 +1812,7 @@ class SaleOrder(models.Model): else: rec.commitment_date = rec.expected_ready_to_ship + @api.onchange('expected_ready_to_ship') #Hangle Onchange form Expected Ready to Ship def _onchange_expected_ready_ship_date(self): self._validate_expected_ready_ship_date() @@ -2258,7 +2276,7 @@ class SaleOrder(models.Model): raise UserError("Terdapat DUPLIKASI data pada Product {}".format(line.product_id.display_name)) def sale_order_approve(self): - self.check_duplicate_product() + # self.check_duplicate_product() self.check_product_bom() self.check_credit_limit() self.check_limit_so_to_invoice() @@ -2528,7 +2546,7 @@ class SaleOrder(models.Model): for order in self: order._validate_delivery_amt() order._validate_uniform_taxes() - order.check_duplicate_product() + # order.check_duplicate_product() order.check_product_bom() order.check_credit_limit() order.check_limit_so_to_invoice() -- cgit v1.2.3 From 80f811a7ccca771990fcbf59df6e92dc8e0acc14 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 24 Sep 2025 09:41:18 +0700 Subject: balikin validate erts --- indoteknik_custom/models/sale_order.py | 132 ++++++++++++++++----------------- 1 file changed, 66 insertions(+), 66 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index fd872b53..85f0d274 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1717,101 +1717,101 @@ class SaleOrder(models.Model): # .format(eta_minimum.strftime('%d-%m-%Y'), eta_minimum.strftime('%d-%m-%Y')) # ) - # def _validate_expected_ready_ship_date(self): - # """ - # Pastikan expected_ready_to_ship tidak lebih awal dari SLA minimum. - # Dipanggil setiap onchange / simpan SO. - # """ - # for rec in self: - # # ───────────────────────────────────────────────────── - # # 1. Hanya validasi kalau field sudah terisi - # # (quotation baru / belum ada tanggal → abaikan) - # # ───────────────────────────────────────────────────── - # if not rec.expected_ready_to_ship: - # continue - # - # current_date = datetime.now() - # - # # ───────────────────────────────────────────────────── - # # 2. Hitung SLA berdasarkan product lines (jika ada) - # # ───────────────────────────────────────────────────── - # products = rec.order_line - # if products: - # sla_data = rec.calculate_sla_by_vendor(products) - # max_sla_time = sla_data.get('slatime', 1) - # else: - # # belum ada item → gunakan default 1 hari - # max_sla_time = 1 - # - # # offset hari libur / weekend - # offset, is3pm = rec.get_days_until_next_business_day(current_date) - # min_days = max_sla_time + offset - 1 - # eta_minimum = current_date + timedelta(days=min_days) - # - # # ───────────────────────────────────────────────────── - # # 3. Validasi - raise error bila terlalu cepat - # # ───────────────────────────────────────────────────── - # if rec.expected_ready_to_ship.date() < eta_minimum.date(): - # # set otomatis ke tanggal minimum supaya user tidak perlu - # # menekan Save dua kali - # rec.expected_ready_to_ship = eta_minimum - # - # raise ValidationError( - # _("Tanggal 'Expected Ready to Ship' tidak boleh " - # "lebih kecil dari %(tgl)s. Mohon pilih minimal %(tgl)s.") - # % {'tgl': eta_minimum.strftime('%d-%m-%Y')} - # ) - # else: - # # sinkronkan ke field commitment_date - # rec.commitment_date = rec.expected_ready_to_ship - def _validate_expected_ready_ship_date(self): """ Pastikan expected_ready_to_ship tidak lebih awal dari SLA minimum. Dipanggil setiap onchange / simpan SO. """ for rec in self: + # ───────────────────────────────────────────────────── + # 1. Hanya validasi kalau field sudah terisi + # (quotation baru / belum ada tanggal → abaikan) + # ───────────────────────────────────────────────────── if not rec.expected_ready_to_ship: continue - # ADDED: gunakan "sekarang" lokal user, bukan datetime.now() server - current_date = fields.Datetime.context_timestamp(rec, fields.Datetime.now()) + current_date = datetime.now() - # Hitung SLA + # ───────────────────────────────────────────────────── + # 2. Hitung SLA berdasarkan product lines (jika ada) + # ───────────────────────────────────────────────────── products = rec.order_line if products: sla_data = rec.calculate_sla_by_vendor(products) max_sla_time = sla_data.get('slatime', 1) else: + # belum ada item → gunakan default 1 hari max_sla_time = 1 - # offset hari libur/weekend + # offset hari libur / weekend offset, is3pm = rec.get_days_until_next_business_day(current_date) min_days = max_sla_time + offset - 1 eta_minimum = current_date + timedelta(days=min_days) - if rec._fields['expected_ready_to_ship'].type == 'date': - exp_date_local = rec.expected_ready_to_ship - else: - exp_date_local = fields.Datetime.context_timestamp( - rec, rec.expected_ready_to_ship - ).date() - - if exp_date_local < eta_minimum.date(): - # (opsional) auto-set ke minimum → konversi balik ke UTC naive bila field Datetime - if rec._fields['expected_ready_to_ship'].type == 'date': - rec.expected_ready_to_ship = eta_minimum.date() - else: - rec.expected_ready_to_ship = eta_minimum.astimezone(pytz.UTC).replace(tzinfo=None) + # ───────────────────────────────────────────────────── + # 3. Validasi - raise error bila terlalu cepat + # ───────────────────────────────────────────────────── + if rec.expected_ready_to_ship.date() < eta_minimum.date(): + # set otomatis ke tanggal minimum supaya user tidak perlu + # menekan Save dua kali + rec.expected_ready_to_ship = eta_minimum raise ValidationError( _("Tanggal 'Expected Ready to Ship' tidak boleh " - "lebih kecil dari %(tgl)s. Mohon pilih minimal %(tgl)s.") + "lebih kecil dari %(tgl)s. Mohon pilih minimal %(tgl)s.") % {'tgl': eta_minimum.strftime('%d-%m-%Y')} ) else: + # sinkronkan ke field commitment_date rec.commitment_date = rec.expected_ready_to_ship + # def _validate_expected_ready_ship_date(self): + # """ + # Pastikan expected_ready_to_ship tidak lebih awal dari SLA minimum. + # Dipanggil setiap onchange / simpan SO. + # """ + # for rec in self: + # if not rec.expected_ready_to_ship: + # continue + # + # # ADDED: gunakan "sekarang" lokal user, bukan datetime.now() server + # current_date = fields.Datetime.context_timestamp(rec, fields.Datetime.now()) + # + # # Hitung SLA + # products = rec.order_line + # if products: + # sla_data = rec.calculate_sla_by_vendor(products) + # max_sla_time = sla_data.get('slatime', 1) + # else: + # max_sla_time = 1 + # + # # offset hari libur/weekend + # offset, is3pm = rec.get_days_until_next_business_day(current_date) + # min_days = max_sla_time + offset - 1 + # eta_minimum = current_date + timedelta(days=min_days) + # + # if rec._fields['expected_ready_to_ship'].type == 'date': + # exp_date_local = rec.expected_ready_to_ship + # else: + # exp_date_local = fields.Datetime.context_timestamp( + # rec, rec.expected_ready_to_ship + # ).date() + # + # if exp_date_local < eta_minimum.date(): + # # (opsional) auto-set ke minimum → konversi balik ke UTC naive bila field Datetime + # if rec._fields['expected_ready_to_ship'].type == 'date': + # rec.expected_ready_to_ship = eta_minimum.date() + # else: + # rec.expected_ready_to_ship = eta_minimum.astimezone(pytz.UTC).replace(tzinfo=None) + # + # raise ValidationError( + # _("Tanggal 'Expected Ready to Ship' tidak boleh " + # "lebih kecil dari %(tgl)s. Mohon pilih minimal %(tgl)s.") + # % {'tgl': eta_minimum.strftime('%d-%m-%Y')} + # ) + # else: + # rec.commitment_date = rec.expected_ready_to_ship + @api.onchange('expected_ready_to_ship') #Hangle Onchange form Expected Ready to Ship def _onchange_expected_ready_ship_date(self): -- cgit v1.2.3 From 5dc3710a5008cbbd3d2e6cbc1fca12bc0bd31eda Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 24 Sep 2025 13:29:15 +0700 Subject: (andri) fix validasi --- indoteknik_custom/models/sale_order.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 85f0d274..f80941d2 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -423,13 +423,13 @@ class SaleOrder(models.Model): @api.constrains('payment_term_id', 'partner_id', 'state') def _check_cbd_lock_sale_order(self): - # cbd_term = self.env['account.payment.term'].browse(26) + cbd_term = self.env['account.payment.term'].browse(26) for rec in self: if rec.state == 'draft' and rec.partner_id.is_cbd_locked: - # if rec.payment_term_id and rec.payment_term_id != cbd_term: - raise ValidationError( - "Customer ini terkunci ke CBD, hanya boleh pakai Payment Term CBD." - ) + if rec.payment_term_id and rec.payment_term_id != cbd_term: + raise ValidationError( + "Customer ini terkunci ke CBD, hanya boleh pakai Payment Term CBD." + ) @api.depends('invoice_ids.payment_state', 'invoice_ids.amount_total', 'invoice_ids.amount_residual') def _compute_payment_state_custom(self): -- cgit v1.2.3 From fa4d124243688f4a74dd605a21b7b402ee632191 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Wed, 24 Sep 2025 16:46:18 +0700 Subject: refund --- indoteknik_custom/models/refund_sale_order.py | 28 ++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index eab25452..6a6d10ea 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -51,6 +51,7 @@ class RefundSaleOrder(models.Model): account_no = fields.Char(string='Account No', required=True) kcp = fields.Char(string='Alamat KCP') finance_note = fields.Text(string='Finance Note') + biaya_admin = fields.Float(string='Biaya Admin Transfer') invoice_names = fields.Html(string="Group Invoice Number", compute="_compute_invoice_names") so_names = fields.Html(string="Group SO Number", compute="_compute_so_names") @@ -280,8 +281,11 @@ class RefundSaleOrder(models.Model): if refund_type == 'salah_transfer' and vals.get('transfer_move_id'): move = self.env['account.move'].browse(vals['transfer_move_id']) if move: + sisa_uang_masuk = move.amount_total_signed # ← set dengan nilai move vals['uang_masuk'] = move.amount_total_signed vals['remaining_refundable'] = 0 + else: + sisa_uang_masuk = 0.0 else: # ==== perhitungan normal ==== moves = self.env['account.move'].search([ @@ -906,9 +910,10 @@ class RefundSaleOrder(models.Model): ('refund_id', '=', rec.id), ('state', '=', 'posted') ]) + amount = rec.amount_refund + rec.biaya_admin if not is_journal: raise UserError("Journal Payment Refund belum dibuat, buat Journal Payment Refund sebelum confirm refund.") - if is_journal and rec.amount_refund != sum(is_journal.mapped('amount_total_signed')): + if is_journal and amount != sum(is_journal.mapped('amount_total_signed')): raise UserError("Total Refund dengan Total Journal Harus Sama.") if rec.status_payment == 'pending': rec.status_payment = 'done' @@ -966,6 +971,7 @@ class RefundSaleOrder(models.Model): # Ref format ref_text = f"{refund_type_label} {refund.name or ''} {partner.display_name}".upper() + admintex = f"BIAYA ADMIN BANK {refund_type_label} {refund.name or ''} {partner.display_name}".upper() # Buat Account Move (Journal Entry) account_move = self.env['account.move'].create({ @@ -976,10 +982,10 @@ class RefundSaleOrder(models.Model): 'refund_so_ids': [(6, 0, refund.sale_order_ids.ids)], 'partner_id': partner.id, }) - + admintf = refund.biaya_admin amount = refund.amount_refund # 450 Penerimaan Belum Teridentifikasi, 668 Penerimaan Belum Alokasi - second_account_id = 450 if refund.refund_type not in ['barang_kosong', 'barang_kosong_sebagian'] else 668 + second_account_id = 450 if refund.refund_type not in ['barang_kosong', 'barang_kosong_sebagian', 'barang_kosong_indent'] else 668 debit_line = { 'move_id': account_move.id, @@ -991,17 +997,29 @@ class RefundSaleOrder(models.Model): 'name': ref_text, } + adminline = { + 'move_id': account_move.id, + 'account_id': 555, + 'partner_id': partner.id, + 'currency_id': 12, + 'debit': admintf, + 'credit': 0.0, + 'name': admintex, + } + credit_line = { 'move_id': account_move.id, 'account_id': 389, # Intransit BCA 'partner_id': partner.id, 'currency_id': 12, 'debit': 0.0, - 'credit': amount, + 'credit': amount + admintf, 'name': ref_text, } - self.env['account.move.line'].create([debit_line, credit_line]) + journal_line = [debit_line, adminline, credit_line] if admintf > 0 else [debit_line, credit_line] + + self.env['account.move.line'].create(journal_line) return { 'name': _('Journal Entries'), -- cgit v1.2.3 From 2bfd932b541351452dda67039740ac1e72ca2326 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Wed, 24 Sep 2025 17:16:35 +0700 Subject: refund --- indoteknik_custom/models/refund_sale_order.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 6a6d10ea..96082447 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -1013,11 +1013,21 @@ class RefundSaleOrder(models.Model): 'partner_id': partner.id, 'currency_id': 12, 'debit': 0.0, - 'credit': amount + admintf, + 'credit': amount, 'name': ref_text, } - journal_line = [debit_line, adminline, credit_line] if admintf > 0 else [debit_line, credit_line] + credit_admin_line = { + 'move_id': account_move.id, + 'account_id': 389, # Intransit BCA + 'partner_id': partner.id, + 'currency_id': 12, + 'debit': 0.0, + 'credit': admintf, + 'name': admintex, + } + + journal_line = [debit_line, credit_line, adminline, credit_admin_line] if admintf > 0 else [debit_line, credit_line] self.env['account.move.line'].create(journal_line) -- cgit v1.2.3 From 9fa63c564fd46db5c3d412626bcf6e6e3f3032ca Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 24 Sep 2025 17:18:48 +0700 Subject: fix --- indoteknik_custom/models/res_partner.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 8aaee47e..ef1a5cf4 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -196,8 +196,7 @@ class ResPartner(models.Model): previous_payment_term_id = fields.Many2one( 'account.payment.term', - string='Previous Payment Term', - readonly=True + string='Previous Payment Term' ) -- cgit v1.2.3