diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2025-06-12 16:18:32 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2025-06-12 16:18:32 +0700 |
| commit | 6616f73259c9e146449af3f2579263b42270bf8b (patch) | |
| tree | 0dfebb75f458c738f63593313b0e19e917e85860 | |
| parent | b6f63fcf96355bc11f9843a9f661cea0a458475e (diff) | |
Revert "<hafid> commit"
This reverts commit 95cef4d4d3936f8a612dadf00e83f9cddcccc0dc, reversing
changes made to 626e93d3a0bfad2bc87002d9e0a7ae860ea9baba.
| -rw-r--r-- | indoteknik_api/controllers/api_v1/stock_picking.py | 6 | ||||
| -rw-r--r-- | indoteknik_custom/models/account_move.py | 19 | ||||
| -rw-r--r-- | indoteknik_custom/models/invoice_reklas.py | 112 | ||||
| -rw-r--r-- | indoteknik_custom/models/invoice_reklas_penjualan.py | 60 | ||||
| -rw-r--r-- | indoteknik_custom/models/mail_mail.py | 19 | ||||
| -rwxr-xr-x | indoteknik_custom/models/purchase_order.py | 30 | ||||
| -rw-r--r-- | indoteknik_custom/models/requisition.py | 12 | ||||
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 261 | ||||
| -rw-r--r-- | indoteknik_custom/models/sale_order_line.py | 25 | ||||
| -rw-r--r-- | indoteknik_custom/models/stock_picking.py | 9 | ||||
| -rw-r--r-- | indoteknik_custom/models/uangmuka_pembelian.py | 2 | ||||
| -rw-r--r-- | indoteknik_custom/views/account_move.xml | 8 | ||||
| -rwxr-xr-x | indoteknik_custom/views/purchase_order.xml | 15 | ||||
| -rwxr-xr-x | indoteknik_custom/views/sale_order.xml | 9 | ||||
| -rwxr-xr-x | indoteknik_custom/views/x_manufactures.xml | 40 |
15 files changed, 123 insertions, 504 deletions
diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index 7cbd3c96..49547779 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -164,9 +164,9 @@ class StockPicking(controller.Controller): # except Exception as e: # return {'success': False, 'message': str(e)} - # @http.route(prefix + 'webhook/biteship', auth='public', methods=['POST'], csrf=False) - # def udpate_status_from_bitehsip(self, **kw): - # return "ok" + @http.route(prefix + 'webhook/biteship', type='json', auth='public', methods=['POST'], csrf=False) + def udpate_status_from_bitehsip(self, **kw): + return "ok" def process_order_status(self, data): picking_model = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 54eaabcf..30de67be 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -67,25 +67,6 @@ 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='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 = [] - # 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: diff --git a/indoteknik_custom/models/invoice_reklas.py b/indoteknik_custom/models/invoice_reklas.py index 5145e098..d10d4c31 100644 --- a/indoteknik_custom/models/invoice_reklas.py +++ b/indoteknik_custom/models/invoice_reklas.py @@ -11,7 +11,7 @@ _logger = logging.getLogger(__name__) class InvoiceReklas(models.TransientModel): _name = 'invoice.reklas' _description = "digunakan untuk reklas Uang Muka Penjualan" - reklas_id = fields.Many2one('account.move', string='Nomor CAB', domain="[('move_type','=','entry')]") + reklas_id = fields.Many2one('account.move', string='Nomor CAB') pay_amt = fields.Float(string='Yang dibayarkan') reklas_type = fields.Selection([ ('penjualan', 'Penjualan'), @@ -20,105 +20,42 @@ class InvoiceReklas(models.TransientModel): @api.onchange('reklas_type') def _onchange_reklas_type(self): - active_ids = self._context.get('active_ids', []) - if not active_ids: - return - - move = self.env['account.move'].browse(active_ids[0]) - cab = False - - # Deteksi dari mana asal CAB - if move.move_type == 'entry': - cab = move - elif move.move_type == 'in_invoice': - if move.reklas_misc_id: - cab = move.reklas_misc_id - elif move.purchase_order_id and move.purchase_order_id.move_id: - cab = move.purchase_order_id.move_id - - # Isi field Nomor CAB jika ditemukan - if cab: - self.reklas_id = cab.id - - # Nilai yang dibayarkan harus tetap ambil dari invoice/bill - self.pay_amt = move.amount_total - - - @api.model - def default_get(self, fields): - res = super().default_get(fields) - active_ids = self._context.get('active_ids', []) - if active_ids: - move = self.env['account.move'].browse(active_ids[0]) - cab = False - - if move.move_type == 'entry': - cab = move - elif move.move_type == 'in_invoice': - if move.reklas_misc_id: - cab = move.reklas_misc_id - elif move.purchase_order_id and move.purchase_order_id.move_id: - cab = move.purchase_order_id.move_id - - if cab: - res['reklas_id'] = cab.id - - res['pay_amt'] = move.amount_total - return res - - - # @api.onchange('reklas_type') - # def _onchange_reklas_type(self): - # if self.reklas_type == 'penjualan': - # invoices = self.env['account.move'].browse(self._context.get('active_ids', [])) - # self.pay_amt = invoices.amount_total + if self.reklas_type == 'penjualan': + invoices = self.env['account.move'].browse(self._context.get('active_ids', [])) + self.pay_amt = invoices.amount_total def create_reklas(self): if not self.reklas_type: raise UserError('Reklas Tipe harus diisi') if not self.reklas_id: raise UserError('Nomor CAB harus diisi') - invoices = self.env['account.move'].browse(self._context.get('active_ids', [])) current_time = datetime.now() - for invoice in invoices: - # Ambil nama PO jika ada - po_name = invoice.purchase_order_id.name if invoice.purchase_order_id else '' - - # Susun nama referensi dengan aman - ref_name = 'REKLAS {} UANG MUKA {} {}{} {}'.format( - self.reklas_id.name or '', - 'PENJUALAN' if self.reklas_type == 'penjualan' else 'PEMBELIAN', - invoice.name or '', - f" - {po_name}" if po_name else '', - invoice.partner_id.name or '' - ) - - # Header jurnal reklas - parameters_header = { - 'ref': ref_name, - 'date': current_time, - 'journal_id': 13 - } + if self.reklas_type == 'penjualan': + ref_name = 'REKLAS '+self.reklas_id.name+" UANG MUKA PENJUALAN "+invoice.name+" "+invoice.partner_id.name + else: + ref_name = 'REKLAS '+self.reklas_id.name+" UANG MUKA PEMBELIAN "+invoice.name+" "+invoice.partner_id.name + if self.reklas_type == 'penjualan': + parameters_header = { + 'ref': ref_name, + 'date': current_time, + 'journal_id': 13 + } + else: + parameters_header = { + 'ref': ref_name, + 'date': current_time, + 'journal_id': 13 + } account_move = request.env['account.move'].create([parameters_header]) _logger.info('Success Reklas with %s' % account_move.name) - # ✅ Set Bill asal sebagai source document - account_move.bill_id = invoice.id - - # Tambahkan info asal invoice ke jurnal (opsional) - account_move.invoice_origin = invoice.name - - # Simpan hubungan balik ke invoice - invoice.reklas_misc_id = account_move.id - - # Buat line debit dan kredit if self.reklas_type == 'penjualan': parameter_debit = { 'move_id': account_move.id, - 'account_id': 668, # penerimaan belum alokasi + 'account_id': 668, # penerimaan belum alokasi 'partner_id': invoice.partner_id.id, 'currency_id': 12, 'debit': self.pay_amt, @@ -134,7 +71,7 @@ class InvoiceReklas(models.TransientModel): 'credit': self.pay_amt, 'name': ref_name } - else: # pembelian + else: parameter_debit = { 'move_id': account_move.id, 'account_id': 438, @@ -153,11 +90,7 @@ class InvoiceReklas(models.TransientModel): 'credit': self.pay_amt, 'name': ref_name } - - # Simpan journal lines request.env['account.move.line'].create([parameter_debit, parameter_credit]) - - # Tampilkan hasil jurnal reklas return { 'name': _('Journal Entries'), 'view_mode': 'form', @@ -167,3 +100,4 @@ class InvoiceReklas(models.TransientModel): 'type': 'ir.actions.act_window', 'res_id': account_move.id } +
\ No newline at end of file diff --git a/indoteknik_custom/models/invoice_reklas_penjualan.py b/indoteknik_custom/models/invoice_reklas_penjualan.py index 2f5ee160..80c3ed43 100644 --- a/indoteknik_custom/models/invoice_reklas_penjualan.py +++ b/indoteknik_custom/models/invoice_reklas_penjualan.py @@ -17,70 +17,43 @@ class InvoiceReklasPenjualan(models.TransientModel): def create_reklas_penjualan(self): invoices = self.invoice_reklas_line + current_time = datetime.now() account_move_ids = [] - - for line in invoices: - # Ambil nama SO jika ada - so_name = line.sale_id.name if line.sale_id else '' - - # Susun referensi nama jurnal - ref_name = 'REKLAS {} UANG MUKA PENJUALAN {}{} {}'.format( - line.reklas_id.name or '', - line.name or '', - f" - {so_name}" if so_name else '', - line.partner_id.name or '' - ) - - # Header jurnal + for invoice in invoices: + ref_name = 'REKLAS ' + invoice.reklas_id.name + " UANG MUKA PENJUALAN " + invoice.name + " " + invoice.partner_id.name parameters_header = { 'ref': ref_name, 'date': current_time, - 'journal_id': 13, - # ⬇️ Tambahkan jika tahu invoice asal (name = ID Bill) - 'bill_id': int(line.name) if line.name and line.name.isdigit() else False, + 'journal_id': 13 } account_move = self.env['account.move'].create([parameters_header]) _logger.info('Success Reklas with %s' % account_move.name) - # Simpan info asal (optional) - account_move.invoice_origin = line.name - - # Simpan juga ke `reklas_misc_id` jika ditemukan invoice valid - if line.name and line.name.isdigit(): - invoice_id = self.env['account.move'].browse(int(line.name)) - if invoice_id.exists(): - invoice_id.reklas_misc_id = account_move.id - - # Buat debit kredit line - debit_line = { + parameter_debit = { 'move_id': account_move.id, - 'account_id': 668, # akun penerimaan belum alokasi - 'partner_id': line.partner_id.id, + 'account_id': 668, # uang muka penjualan + 'partner_id': invoice.partner_id.id, 'currency_id': 12, - 'debit': line.pay_amt, + 'debit': invoice.pay_amt, 'credit': 0, 'name': ref_name } - credit_line = { + parameter_credit = { 'move_id': account_move.id, - 'account_id': 395, # akun pengurang - 'partner_id': line.partner_id.id, + 'account_id': 395, + 'partner_id': invoice.partner_id.id, 'currency_id': 12, 'debit': 0, - 'credit': line.pay_amt, + 'credit': invoice.pay_amt, 'name': ref_name } - - self.env['account.move.line'].create([debit_line, credit_line]) + self.env['account.move.line'].create([parameter_debit, parameter_credit]) account_move_ids.append(account_move.id) - - line.unlink() # bersihkan line setelah selesai - - self.unlink() # hapus wizard utama setelah selesai - - # Tampilkan hasil jurnal reklas + invoice.unlink() + + self.unlink() return { 'name': _('Journal Entries'), 'view_mode': 'tree,form', @@ -90,7 +63,6 @@ class InvoiceReklasPenjualan(models.TransientModel): 'domain': [('id', 'in', account_move_ids)], } - class InvoiceReklasPenjualanLine(models.TransientModel): _name = 'invoice.reklas.penjualan.line' _description = "digunakan untuk reklas Uang Muka Penjualan" diff --git a/indoteknik_custom/models/mail_mail.py b/indoteknik_custom/models/mail_mail.py index cbcd883a..82b1fcca 100644 --- a/indoteknik_custom/models/mail_mail.py +++ b/indoteknik_custom/models/mail_mail.py @@ -1,27 +1,12 @@ from odoo import fields, models, api, _ -from datetime import timedelta -import logging -_logger = logging.getLogger(__name__) class MailMail(models.Model): _inherit = 'mail.mail' - @api.model def retry_send_mail(self): - now = fields.Datetime.now() - seven_days_ago = now - timedelta(days=7) - - # Filter hanya email gagal dalam 7 hari terakhir - mails = self.search([ - ('state', 'in', 'exception'), - ('create_date', '>=', seven_days_ago), - ('create_date', '<=', now), + mails = self.env['mail.mail'].search([ + ('state', 'in', ['exception', 'cancel']), ], limit=250) - - _logger.info("Found %s failed emails in last 7 days to retry.", len(mails)) - for mail in mails: - _logger.info("Retrying email ID %s - To: %s - Subject: %s", - mail.id, mail.email_to, mail.subject) mail.state = 'outgoing' diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 004a1fa4..21ca55eb 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -65,7 +65,7 @@ class PurchaseOrder(models.Model): sale_order = fields.Char(string='Sale Order') matches_so = fields.Many2many('sale.order', string='Matches SO', compute='_compute_matches_so') is_create_uangmuka = fields.Boolean(string='Uang Muka?') - move_id = fields.Many2one('account.move', string='Journal Entries Uang Muka', domain=[('move_type', '=', 'entry')]) + move_id = fields.Many2one('account.move', string='Account Move') logbook_bill_id = fields.Many2one('report.logbook.bill', string='Logbook Bill') status_printed = fields.Selection([ ('not_printed', 'Belum Print'), @@ -89,28 +89,6 @@ class PurchaseOrder(models.Model): store_name = fields.Char(string='Nama Toko') purchase_order_count = fields.Integer('Purchase Order Count', related='partner_id.purchase_order_count') - is_cab_visible = fields.Boolean(string='Tampilkan Tombol CAB', compute='_compute_is_cab_visible') - - @api.depends('move_id.state') - def _compute_is_cab_visible(self): - for order in self: - move = order.move_id - order.is_cab_visible = bool(move and move.state == 'posted') - - def action_view_journal_uangmuka(self): - self.ensure_one() - if not self.move_id: - raise UserError("Journal Uang Muka belum tersedia.") - - return { - 'type': 'ir.actions.act_window', - 'name': 'Journal Entry', - 'res_model': 'account.move', - 'res_id': self.move_id.id, - 'view_mode': 'form', - 'target': 'current', - } - # cek payment term def _check_payment_term(self): _logger.info("Check Payment Term Terpanggil") @@ -838,7 +816,7 @@ class PurchaseOrder(models.Model): for line in self.order_line: if not line.so_line_id: continue - if line.so_line_id.vendor_id.id != vendor_po: + if line.so_line_id.vendor_id.id != vendor_po and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): self.env.user.notify_danger( title='WARNING!!!', 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)+")", @@ -856,7 +834,7 @@ class PurchaseOrder(models.Model): if self.amount_untaxed >= 50000000 and not self.env.user.id == 21: raise UserError("Hanya Rafly Hanggara yang bisa approve") - if self.total_percent_margin < self.total_so_percent_margin: + if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: self.env.user.notify_danger( title='WARNING!!!', message='Beda Margin dengan Sale Order', @@ -1024,7 +1002,7 @@ class PurchaseOrder(models.Model): self.approval_status_unlock = 'approvedFinance' else: raise UserError("Bisa langsung Confirm, menunggu persetujuan Finance jika ingin unlock PO") - elif self.env.user.is_leader or self.env.user.has_group('indoteknik_custom.group_role_purchasing'): + elif self.env.user.is_leader or self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): raise UserError("Bisa langsung Confirm") elif self.total_percent_margin == self.total_so_percent_margin and self.matches_so and not greater_than_plafon and not different_vendor_message: raise UserError("Bisa langsung Confirm") diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index bcdafb12..25133e72 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -48,8 +48,8 @@ class Requisition(models.Model): is_po = fields.Boolean(string='Is PO') requisition_match = fields.One2many('requisition.purchase.match', 'requisition_id', string='Matches', auto_join=True) sale_order_id = fields.Many2one('sale.order', string='SO', help='harus diisi nomor SO yang ingin digenerate') - sales_approve = fields.Boolean(string='Approval Status', tracking=3, copy=False) - merchandise_approve = fields.Boolean(string='Approval Status', tracking=3, copy=False) + sales_approve = fields.Boolean(string='Sales Approve', tracking=3, copy=False) + merchandise_approve = fields.Boolean(string='Merchandise Approve', tracking=3, copy=False) def generate_requisition_from_so(self): state = ['done', 'sale'] @@ -87,11 +87,15 @@ class Requisition(models.Model): if self.env.user.id == 19 or self.env.user.id == 28: self.sales_approve = True elif self.env.user.id == 21 or self.env.user.id == 28: + if not self.sales_approve: + raise UserError('Darren Belum Approve') self.merchandise_approve = True def create_po_from_requisition(self): - if not self.sales_approve and not self.merchandise_approve: - raise UserError('Harus Di Approve oleh Darren atau Rafly') + if not self.sales_approve: + raise UserError('Harus Di Approve oleh Darren') + if not self.merchandise_approve: + raise UserError('Harus Di Approve oleh Rafly') if not self.requisition_lines: raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index baa8207f..fa570819 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -148,8 +148,8 @@ class SaleOrder(models.Model): help="Total Margin in Sales Order Header") total_percent_margin = fields.Float('Total Percent Margin', compute='_compute_total_percent_margin', help="Total % Margin in Sales Order Header") - total_margin_excl_third_party = fields.Float('Before Margin', help="Before Margin in Sales Order Header") - + total_margin_excl_third_party = fields.Float('Before Margin', help="Before Margin in Sales Order Header", + compute='_compute_total_margin_excl_third_party') approval_status = fields.Selection([ ('pengajuan1', 'Approval Manager'), ('pengajuan2', 'Approval Pimpinan'), @@ -340,16 +340,16 @@ class SaleOrder(models.Model): date_unhold = fields.Datetime(string='Date Unhold', tracking=True, readonly=True, help='Waktu ketika SO di Unhold' ) - # def _compute_total_margin_excl_third_party(self): - # for order in self: - # if order.amount_untaxed == 0: - # order.total_margin_excl_third_party = 0 - # continue - # - # # order.total_percent_margin = round((order.total_margin / (order.amount_untaxed-delivery_amt-order.fee_third_party)) * 100, 2) - # order.total_margin_excl_third_party = round((order.total_before_margin / (order.amount_untaxed)) * 100, 2) - # # order.total_percent_margin = round((order.total_margin / (order.amount_untaxed)) * 100, 2) - # + def _compute_total_margin_excl_third_party(self): + for order in self: + if order.amount_untaxed == 0: + order.total_margin_excl_third_party = 0 + continue + + # order.total_percent_margin = round((order.total_margin / (order.amount_untaxed-delivery_amt-order.fee_third_party)) * 100, 2) + order.total_margin_excl_third_party = round((order.total_before_margin / (order.amount_untaxed)) * 100, 2) + # order.total_percent_margin = round((order.total_margin / (order.amount_untaxed)) * 100, 2) + def ask_retur_cancel_purchasing(self): for rec in self: if self.env.user.has_group('indoteknik_custom.group_role_purchasing'): @@ -403,14 +403,14 @@ class SaleOrder(models.Model): if len(tax_sets) > 1: raise ValidationError("Semua produk dalam Sales Order harus memiliki kombinasi pajak yang sama.") - # @api.constrains('fee_third_party', 'delivery_amt', 'biaya_lain_lain', 'ongkir_ke_xpdc') + # @api.constrains('fee_third_party', 'delivery_amt', 'biaya_lain_lain') # def _check_total_margin_excl_third_party(self): # for rec in self: # if rec.fee_third_party == 0 and rec.total_margin_excl_third_party != rec.total_percent_margin: # # Gunakan direct SQL atau flag context untuk menghindari rekursi # self.env.cr.execute(""" - # UPDATE sale_order - # SET total_margin_excl_third_party = %s + # UPDATE sale_order + # SET total_margin_excl_third_party = %s # WHERE id = %s # """, (rec.total_percent_margin, rec.id)) # self.invalidate_cache() @@ -866,6 +866,7 @@ class SaleOrder(models.Model): def _validate_delivery_amt(self): is_indoteknik = self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik' is_active_id = not self.env.context.get('active_id', []) + if is_indoteknik and is_active_id: if self.delivery_amt == 0: if self.carrier_id.id == 1: @@ -1034,11 +1035,11 @@ class SaleOrder(models.Model): line_no += 1 line.line_no = line_no - # def write(self, vals): - # if 'carrier_id' in vals: - # for picking in self.picking_ids: - # if picking.state == 'assigned': - # picking.carrier_id = self.carrier_id + def write(self, vals): + if 'carrier_id' in vals: + for picking in self.picking_ids: + if picking.state == 'assigned': + picking.carrier_id = self.carrier_id def calculate_so_status(self): so_state = ['sale'] @@ -1156,12 +1157,12 @@ class SaleOrder(models.Model): helper_ids_str = self.env['ir.config_parameter'].sudo().get_param('sale.order.user_helper_ids') return helper_ids_str.split(', ') - # def write(self, values): - # helper_ids = self._get_helper_ids() - # if str(self.env.user.id) in helper_ids: - # values['helper_by_id'] = self.env.user.id - # - # return super(SaleOrder, self).write(values) + def write(self, values): + helper_ids = self._get_helper_ids() + if str(self.env.user.id) in helper_ids: + values['helper_by_id'] = self.env.user.id + + return super(SaleOrder, self).write(values) def check_due(self): """To show the due amount and warning stage""" @@ -1692,95 +1693,20 @@ class SaleOrder(models.Model): total_before_margin = sum(line.item_before_margin for line in order.order_line if line.product_id) order.total_before_margin = total_before_margin - # Perhitungan Lama - # def _compute_total_percent_margin(self): - # for order in self: - # if order.amount_untaxed == 0: - # order.total_percent_margin = 0 - # continue - # if order.shipping_cost_covered == 'indoteknik': - # delivery_amt = order.delivery_amt - # else: - # delivery_amt = 0 - # - # net_margin = order.total_margin - order.biaya_lain_lain - # - # order.total_percent_margin = round( - # (net_margin / (order.amount_untaxed - order.fee_third_party)) * 100, 2) - - # order.total_percent_margin = round((order.total_margin / (order.amount_untaxed-delivery_amt-order.fee_third_party)) * 100, 2) - # order.total_percent_margin = round( - # (order.total_margin / (order.amount_untaxed - order.fee_third_party - order.biaya_lain_lain)) * 100, 2) - # order.total_percent_margin = round((order.total_margin / (order.amount_untaxed)) * 100, 2) - def _compute_total_percent_margin(self): for order in self: if order.amount_untaxed == 0: order.total_percent_margin = 0 continue - if order.shipping_cost_covered == 'indoteknik': delivery_amt = order.delivery_amt else: delivery_amt = 0 - net_margin = order.total_margin - order.fee_third_party - order.biaya_lain_lain - - - if order.amount_untaxed > 0: - order.total_percent_margin = round((net_margin / order.amount_untaxed) * 100, 2) - else: - order.total_percent_margin = 0 - - # @api.onchange('biaya_lain_lain') - # def _onchange_biaya_lain_lain(self): - # """Ketika biaya_lain_lain berubah, simpan nilai margin sebelumnya""" - # if hasattr(self, '_origin') and self._origin.id: - # # Hitung margin sebelum biaya_lain_lain ditambahkan - # if self.amount_untaxed > 0: - # original_net_margin = self.total_margin # tanpa biaya_lain_lain - # self.total_margin_excl_third_party = round( - # (original_net_margin / (self.amount_untaxed - self.fee_third_party)) * 100, 2) - - def _prepare_before_margin_values(self, vals): - margin_sebelumnya = {} - - margin_affecting_fields = [ - 'biaya_lain_lain', 'fee_third_party', 'delivery_amt', - 'ongkir_ke_xpdc', 'shipping_cost_covered', 'order_line' - ] - - if not any(field in vals for field in margin_affecting_fields): - return {} - - for order in self: - if order.amount_untaxed <= 0: - continue - - current_before = order.total_margin_excl_third_party or 0 - - # CASE 1: Before margin masih kosong → ambil dari item_percent_margin - if current_before == 0: - line_margin = 0 - for line in order.order_line: - if line.item_percent_margin is not None: - line_margin = line.item_percent_margin - break - margin_sebelumnya[order.id] = line_margin - _logger.info(f"[BEFORE] SO {order.name}: Before margin kosong, ambil dari order line: {line_margin}%") - else: - # CASE 2: Ada perubahan field yang mempengaruhi margin - for field in margin_affecting_fields: - if field in vals: - old_val = getattr(order, field, 0) or 0 - new_val = vals[field] or 0 - if old_val != new_val: - margin_sebelumnya[order.id] = order.total_percent_margin - _logger.info( - f"[BEFORE] SO {order.name}: {field} berubah dari {old_val} ke {new_val}, simpan {order.total_percent_margin}%") - break - - return margin_sebelumnya + # order.total_percent_margin = round((order.total_margin / (order.amount_untaxed-delivery_amt-order.fee_third_party)) * 100, 2) + order.total_percent_margin = round( + (order.total_margin / (order.amount_untaxed - order.fee_third_party - order.biaya_lain_lain)) * 100, 2) + # order.total_percent_margin = round((order.total_margin / (order.amount_untaxed)) * 100, 2) @api.onchange('sales_tax_id') def onchange_sales_tax_id(self): @@ -2071,42 +1997,31 @@ class SaleOrder(models.Model): 'customer_type': partner.customer_type, }) - # def write(self, vals): - # for order in self: - # if order.state in ['sale', 'cancel']: - # if 'order_line' in vals: - # new_lines = vals.get('order_line', []) - # for command in new_lines: - # if command[0] == 0: # A new line is being added - # raise UserError( - # "SO tidak dapat ditambahkan produk baru karena SO sudah menjadi sale order.") - # - # res = super(SaleOrder, self).write(vals) - # # self._check_total_margin_excl_third_party() - # if any(fields in vals for fields in ['delivery_amt', 'carrier_id', 'shipping_cost_covered']): - # self._validate_delivery_amt() - # if any(field in vals for field in ["order_line", "client_order_ref"]): - # self._calculate_etrts_date() - # return res + def write(self, vals): + for order in self: + if order.state in ['sale', 'cancel']: + if 'order_line' in vals: + new_lines = vals.get('order_line', []) + for command in new_lines: + if command[0] == 0: # A new line is being added + raise UserError( + "SO tidak dapat ditambahkan produk baru karena SO sudah menjadi sale order.") + + res = super(SaleOrder, self).write(vals) + # self._check_total_margin_excl_third_party() + if any(fields in vals for fields in ['delivery_amt', 'carrier_id', 'shipping_cost_covered']): + self._validate_delivery_amt() + if any(field in vals for field in ["order_line", "client_order_ref"]): + self._calculate_etrts_date() + return res # @api.depends('commitment_date') def _compute_ready_to_ship_status_detail(self): - def is_empty(val): - """Helper untuk cek data kosong yang umum di Odoo.""" - return val is None or val == "" or val == [] or val == {} - for order in self: - order.ready_to_ship_status_detail = 'On Track' # Default value - - # Skip if no commitment date - if is_empty(order.commitment_date): - continue - eta = order.commitment_date match_lines = self.env['purchase.order.sales.match'].search([ ('sale_id', '=', order.id) ]) - if match_lines: for match in match_lines: po = match.purchase_order_id @@ -2115,77 +2030,17 @@ class SaleOrder(models.Model): ('order_id', '=', po.id), ('product_id', '=', product.id) ], limit=1) - - if is_empty(po_line): - continue - stock_move = self.env['stock.move'].search([ ('purchase_line_id', '=', po_line.id) ], limit=1) - - if is_empty(stock_move) or is_empty(stock_move.picking_id): - continue - picking_in = stock_move.picking_id - result_date = picking_in.date_done - - if is_empty(result_date): - continue - - try: - if result_date < eta: - order.ready_to_ship_status_detail = f"Early (Actual: {result_date.strftime('%m/%d/%Y')})" - else: - order.ready_to_ship_status_detail = f"Delay (Actual: {result_date.strftime('%m/%d/%Y')})" - except Exception as e: - _logger.error(f"Error computing ready to ship status: {str(e)}") - continue - - def write(self, vals): - - margin_sebelumnya = self._prepare_before_margin_values(vals) - - for order in self: - if order.state in ['sale', 'cancel']: - if 'order_line' in vals: - for command in vals.get('order_line', []): - if command[0] == 0: - raise UserError( - "SO tidak dapat ditambahkan produk baru karena SO sudah menjadi sale order.") - - if 'carrier_id' in vals: - for order in self: - for picking in order.picking_ids: - if picking.state == 'assigned': - picking.carrier_id = vals['carrier_id'] - - try: - helper_ids = self._get_helper_ids() - if str(self.env.user.id) in helper_ids: - vals['helper_by_id'] = self.env.user.id - except: - pass - - res = super(SaleOrder, self).write(vals) - - # Update before margin setelah write - if margin_sebelumnya: - for order_id, margin_value in margin_sebelumnya.items(): - _logger.info(f"[UPDATE] SO ID {order_id}: Set before margin ke {margin_value}%") - self.env.cr.execute(""" - UPDATE sale_order - SET total_margin_excl_third_party = %s - WHERE id = %s - """, (margin_value, order_id)) - - self.env.cr.commit() - self.invalidate_cache(['total_margin_excl_third_party']) - - # Validasi setelah write - if any(field in vals for field in ['delivery_amt', 'carrier_id', 'shipping_cost_covered']): - self._validate_delivery_amt() - - if any(field in vals for field in ["order_line", "client_order_ref"]): - self._calculate_etrts_date() - - return res
\ No newline at end of file + result_date = picking_in.date_done if picking_in else None + if result_date: + status = "Early" if result_date < eta else "Delay" + result_date_str = result_date.strftime('%m/%d/%Y') + eta_str = eta.strftime('%m/%d/%Y') + order.ready_to_ship_status_detail = f"Expected: {eta_str} | Realtime: {result_date_str} | {status}" + else: + order.ready_to_ship_status_detail = "On Track" + else: + order.ready_to_ship_status_detail = 'On Track'
\ No newline at end of file diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 291940ed..c8066961 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -10,8 +10,6 @@ class SaleOrderLine(models.Model): help="Total Margin in Sales Order Header") item_percent_margin = fields.Float('%Margin', compute='compute_item_margin', help="Total % Margin in Sales Order Header") - item_percent_margin_before = fields.Float('%Margin Before', compute='_compute_item_percent_margin_before', - help="Total % Margin excluding third party in Sales Order Header") initial_discount = fields.Float('Initial Discount') vendor_id = fields.Many2one( 'res.partner', string='Vendor', readonly=True, @@ -136,29 +134,6 @@ class SaleOrderLine(models.Model): else: line.item_percent_margin_without_deduction = 0 - def _compute_item_percent_margin_before(self): - for line in self: - if not line.product_id or line.product_id.type == 'service' \ - or line.price_unit <= 0 or line.product_uom_qty <= 0 \ - or not line.vendor_id: - line.item_percent_margin_before = 0 - continue - - sales_price = line.price_reduce_taxexcl * line.product_uom_qty - - purchase_price = line.purchase_price - if line.purchase_tax_id and line.purchase_tax_id.price_include: - purchase_price = line.purchase_price / 1.11 - - purchase_price = purchase_price * line.product_uom_qty - - margin_before = sales_price - purchase_price - - if sales_price > 0: - line.item_percent_margin_before = round((margin_before / sales_price), 2) * 100 - else: - line.item_percent_margin_before = 0 - def compute_item_margin(self): for line in self: if not line.product_id or line.product_id.type == 'service' \ diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 9dfc8b78..a215eb74 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -529,7 +529,13 @@ class StockPicking(models.Model): record.kgx_pod_photo = "No image available." def action_fetch_lalamove_order(self): - for picking in self: + pickings = self.env['stock.picking'].search([ + ('picking_type_code', '=', 'outgoing'), + ('state', '=', 'done'), + ('carrier_id', '=', 9), + ('lalamove_order_id', '!=', False) + ]) + for picking in pickings: try: order_id = picking.lalamove_order_id apikey = self.env['ir.config_parameter'].sudo().get_param('lalamove.apikey') @@ -578,7 +584,6 @@ class StockPicking(models.Model): self.lalamove_phone = phone self.lalamove_status = pod.get("status") self.lalamove_delivered_at = delivered_at_dt - self.driver_arrival_date = delivered_at_dt return data raise UserError("No delivered data found in Lalamove response.") diff --git a/indoteknik_custom/models/uangmuka_pembelian.py b/indoteknik_custom/models/uangmuka_pembelian.py index 13d51dcf..ba41f814 100644 --- a/indoteknik_custom/models/uangmuka_pembelian.py +++ b/indoteknik_custom/models/uangmuka_pembelian.py @@ -57,8 +57,6 @@ class UangmukaPembelian(models.TransientModel): account_move = request.env['account.move'].create([param_header]) _logger.info('Success Create Uang Muka Pembelian %s' % account_move.name) - account_move.purchase_order_id = order.id # isi field purchase_order_id - if order.partner_id.parent_id: partner_id = order.partner_id.parent_id.id else: diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index 0c2f9a68..46737a40 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -6,12 +6,6 @@ <field name="model">account.move</field> <field name="inherit_id" ref="account.view_move_form"/> <field name="arch" type="xml"> - <xpath expr="//div[@name='journal_div']" position="after"> - <field name="reklas_misc_id" - string="Journal Entries Reklas" - attrs="{'invisible': [('move_type', '!=', 'in_invoice')]}" - readonly="1"/> - </xpath> <button name="action_register_payment" position="after"> <button name="indoteknik_custom.action_view_invoice_reklas" string="Reklas" type="action" class="btn-primary" attrs="{'invisible': [('state', '!=', 'posted')]}"/> @@ -37,8 +31,6 @@ </field> <field name="ref" position="after"> <field name="sale_id" readonly="1" attrs="{'invisible': [('move_type', '!=', 'entry')]}"/> - <!-- <field name="purchase_order_id" context="{'form_view_ref': 'purchase.purchase_order_form'}" options="{'no_create': True}"/> --> - <field name="bill_id" readonly="1" attrs="{'invisible': ['|', ('move_type', '!=', 'entry'), ('purchase_order_id', '!=', False)]}"/> </field> <field name="partner_shipping_id" position="before"> <field name="real_invoice_id" readonly="1" attrs="{'invisible': [('move_type', '!=', 'out_invoice')]}"/> diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 9084bcbb..0fbbb5e7 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -14,20 +14,6 @@ attrs="{'invisible': ['|', ('sale_order_id', '=', False), ('state', 'not in', ['draft'])]}" /> </div> - <xpath expr="//button[@name='action_view_invoice']" position="before"> - <field name="is_cab_visible" invisible="1"/> - <button type="object" - name="action_view_journal_uangmuka" - class="oe_stat_button" - icon="fa-book" - attrs="{'invisible': [('is_cab_visible', '=', False)]}" - style="width: 200px;"> - <field name="move_id" widget="statinfo" string="Journal Uang Muka"/> - <span class="o_stat_text"> - <t t-esc="record.move_id.name"/> - </span> - </button> - </xpath> <button id="draft_confirm" position="after"> <button name="po_approve" string="Ask Approval" @@ -79,7 +65,6 @@ <field name="total_cost_service" attrs="{'required': [('partner_id', 'in', [9688, 29712])]}"/> <field name="total_delivery_amt" attrs="{'required': [('partner_id', 'in', [9688, 29712])]}"/> <field name="product_bom_id"/> - <!-- <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"> <field name="total_margin"/> diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 4b74825e..0fabf279 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -208,11 +208,6 @@ <label for="item_percent_margin"/> <field name="item_percent_margin"/> </div> - <div name="item_percent_margin_before" groups="base.group_no_one" - attrs="{'invisible': [('display_type', '!=', False)]}"> - <label for="item_percent_margin_before"/> - <field name="item_percent_margin_before"/> - </div> </div> <div name="invoice_lines" position="before"> <div name="price_subtotal" groups="base.group_no_one" @@ -244,7 +239,6 @@ attrs="{'readonly': [('parent.approval_status', '!=', False)]}" domain="[('type_tax_use','=','purchase')]" options="{'no_create':True}"/> <field name="item_percent_margin"/> - <field name="item_percent_margin_before"/> <field name="item_margin" optional="hide"/> <field name="margin_md" optional="hide"/> <field name="note" optional="hide"/> @@ -409,7 +403,7 @@ <field name="state" position="after"> <field name="approval_status"/> <field name="client_order_ref"/> - <field name="notes" optional="hide"/> + <field name="notes"/> <field name="payment_type" optional="hide"/> <field name="payment_status" optional="hide"/> <field name="pareto_status" optional="hide"/> @@ -434,7 +428,6 @@ <field name="payment_type" optional="hide"/> <field name="payment_status" optional="hide"/> <field name="pareto_status" optional="hide"/> - <field name="notes" optional="hide"/> </field> </field> </record> diff --git a/indoteknik_custom/views/x_manufactures.xml b/indoteknik_custom/views/x_manufactures.xml index 02061251..01e90a1e 100755 --- a/indoteknik_custom/views/x_manufactures.xml +++ b/indoteknik_custom/views/x_manufactures.xml @@ -3,7 +3,7 @@ <record id="x_manufactures_action" model="ir.actions.act_window"> <field name="name">Manufacture</field> <field name="res_model">x_manufactures</field> - <field name="view_mode">kanban,tree,form</field> <!-- Tambahkan kanban di sini --> + <field name="view_mode">tree,form</field> <field name="help" type="html"> <p class="o_view_nocontent_smiling_face"> Add Manufactures! @@ -11,44 +11,6 @@ </field> </record> - <record id="x_manufactures_kanban" model="ir.ui.view"> - <field name="name">Manufactures Kanban</field> - <field name="model">x_manufactures</field> - <field name="arch" type="xml"> - <kanban default_group_by="x_manufacture_level"> - <field name="id"/> <!-- Tambahkan ini --> - <field name="x_name"/> - <field name="x_logo_manufacture"/> - <field name="x_manufacture_level"/> - <templates> - <t t-name="kanban-box"> - <div class="oe_kanban_global_click"> - <div class="o_kanban_image"> - <img t-if="record.x_logo_manufacture.raw_value" - t-att-src="kanban_image('x_manufactures', 'x_logo_manufacture', record.id.raw_value)" - alt="Logo" class="img-fluid" width="64" height="64"/> - <img t-else="" - src="/web/static/src/img/placeholder.png" - alt="No Logo" class="img-fluid" width="64" height="64"/> - </div> - <div class="o_kanban_details"> - <strong><field name="x_name"/></strong> - <div> - <span class="badge badge-secondary"> - <field name="x_manufacture_level"/> - </span> - </div> - <div t-if="record.x_short_desc.raw_value"> - <small><field name="x_short_desc"/></small> - </div> - </div> - </div> - </t> - </templates> - </kanban> - </field> - </record> - <record id="x_manufactures_tree" model="ir.ui.view"> <field name="name">Manufactures</field> <field name="model">x_manufactures</field> |
