diff options
| author | FIN-IT_AndriFP <andrifebriyadiputra@gmail.com> | 2026-01-09 14:43:31 +0700 |
|---|---|---|
| committer | FIN-IT_AndriFP <andrifebriyadiputra@gmail.com> | 2026-01-09 14:43:31 +0700 |
| commit | e8291422441d48909252471282c4b72372cccefb (patch) | |
| tree | 60e1e280dc5bfc8d670523b04ff4582a8a35e9bb | |
| parent | ff058e22f64cd3e2dbd69d835f68877f530820c3 (diff) | |
| parent | ae961c97d736359f6611db82ee484707f581ab0f (diff) | |
Merge branch 'odoo-backup' of https://bitbucket.org/altafixco/indoteknik-addons into magento-solr-v1
| -rw-r--r-- | indoteknik_custom/models/account_move.py | 95 | ||||
| -rw-r--r-- | indoteknik_custom/models/advance_payment_request.py | 48 | ||||
| -rw-r--r-- | indoteknik_custom/models/commission_internal.py | 12 | ||||
| -rwxr-xr-x | indoteknik_custom/models/purchase_order.py | 15 | ||||
| -rw-r--r-- | indoteknik_custom/models/purchasing_job.py | 62 | ||||
| -rw-r--r-- | indoteknik_custom/models/refund_sale_order.py | 81 | ||||
| -rw-r--r-- | indoteknik_custom/models/requisition.py | 14 | ||||
| -rw-r--r-- | indoteknik_custom/report/purchase_report.xml | 2 | ||||
| -rwxr-xr-x | indoteknik_custom/security/ir.model.access.csv | 1 | ||||
| -rw-r--r-- | indoteknik_custom/views/advance_payment_request.xml | 39 | ||||
| -rw-r--r-- | indoteknik_custom/views/advance_payment_settlement.xml | 9 | ||||
| -rw-r--r-- | indoteknik_custom/views/commission_internal.xml | 1 | ||||
| -rw-r--r-- | indoteknik_custom/views/purchasing_job.xml | 11 |
13 files changed, 311 insertions, 79 deletions
diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index e36b9920..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}") @@ -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""" <tr> <td>{idx}</td> @@ -380,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""" <p><b>Informasi Tambahan:</b></p> <ul style="font-size:12px; color:#333; line-height:1.4; margin:0; padding-left:0; list-style-position:inside;"> @@ -390,11 +391,11 @@ class AccountMove(models.Model): Sisa Kredit Limit: {formatLang(self.env, blocking_limit - outstanding_amount, currency_obj=currency)} </li> <li style="color:red;"> - Kredit Limit Terpakai: {formatLang(self.env, outstanding_amount, currency_obj=currency)} + Kredit Limit Terpakai: {formatLang(self.env, outstanding_amount, currency_obj=currency)} <span style="font-size:12px; color:#666;">({len(outstanding_invoices)} Transaksi)</span> </li> <li style="color:red;"> - Jatuh Tempo: {formatLang(self.env, overdue_amount, currency_obj=currency)} + Jatuh Tempo: {formatLang(self.env, overdue_amount, currency_obj=currency)} <span style="font-size:12px; color:#666;">({len(overdue_invoices)} Invoice)</span> </li> </ul> @@ -471,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, @@ -527,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 @@ -588,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)] @@ -604,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 @@ -639,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)) @@ -653,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): @@ -721,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 @@ -740,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': @@ -750,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")] @@ -775,10 +798,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): @@ -786,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 @@ -800,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 @@ -830,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: @@ -858,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 @@ -873,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( @@ -956,4 +979,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) diff --git a/indoteknik_custom/models/advance_payment_request.py b/indoteknik_custom/models/advance_payment_request.py index d379eac8..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 <b>DIBATALKAN</b> oleh {self.env.user.name}.<br/>" + f"<b>Alasan:</b> {self.reason}", + message_type="comment", + subtype_xmlid="mail.mt_note", + ) + + return {'type': 'ir.actions.act_window_close'} class AdvancePaymentUsageLine(models.Model): @@ -1072,7 +1118,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..840700c6 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,11 @@ 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') + + self.message_post(body=("Commission Internal Result generated by %s at %s.") % (self.env.user.name, fields.Datetime.now())) + exception = ['ONGKOS KIRIM SO/20'] query = [ ('commission_internal_id.id', '=', self.id), @@ -259,6 +264,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 +277,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): @@ -286,6 +291,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 +327,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 +397,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/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 3d22b0f0..a114743f 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -1081,13 +1081,16 @@ class PurchaseOrder(models.Model): def button_confirm(self): if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan if '/PJ/' in self.name: - low_margin_lines = self.order_sales_match_line.filtered( - lambda match: match.so_header_margin <= 15.0 - ) price_change_detected = any(line.price_unit_before for line in self.order_line) - if low_margin_lines and price_change_detected: - # raise UserError("Matches SO terdapat item dengan header margin SO <= 15%. Approval Pimpinan diperlukan.") - raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line yang Matches SO item memiliki header margin SO <= 15%") + if price_change_detected: + if self.total_percent_margin <= 15.0: + raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") + else: + low_margin_match_so = self.order_sales_match_line.filtered( + lambda match: match.so_header_margin <= 15.0 + ) + if low_margin_match_so: + raise UserError("Approval Pimpinan diperlukan jika pada PO Line yang Matches SO item memiliki header margin SO <= 15%") # else: # is_po_manual = '/A/' not in self.name and '/MO/' not in self.name # if is_po_manual: diff --git a/indoteknik_custom/models/purchasing_job.py b/indoteknik_custom/models/purchasing_job.py index 3151f0f6..7a7e70b4 100644 --- a/indoteknik_custom/models/purchasing_job.py +++ b/indoteknik_custom/models/purchasing_job.py @@ -61,11 +61,33 @@ 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 = self.env['purchasing.job.seen'] + + + for rec in self: + 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): # Example: Delete related records from the underlying model underlying_records = self.env['purchasing.job'].search([ @@ -78,7 +100,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 +137,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 +154,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 +202,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 +227,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/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')) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 748642eb..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,15 +101,17 @@ class Requisition(models.Model): self.merchandise_approve = True def create_po_from_requisition(self): - self.check_product_line_to_so() - if not self.sales_approve and not self.merchandise_approve: - raise UserError('Harus Di Approve oleh Darren atau Rafly') + # 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: 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): - 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), diff --git a/indoteknik_custom/report/purchase_report.xml b/indoteknik_custom/report/purchase_report.xml index 54ac6193..a6804ca4 100644 --- a/indoteknik_custom/report/purchase_report.xml +++ b/indoteknik_custom/report/purchase_report.xml @@ -106,7 +106,7 @@ <div style="display:flex; flex-direction:column; flex:1;"> <span style="font-weight:bold; margin-bottom:2px;"> <t t-esc="line_index + 1"/>. - <t t-if="line.product_id.id in [114360, 595346, 610166]"> + <t t-if="line.product_id.id in [114360, 595346, 610166, 420315]"> <t t-esc="line.name"/> </t> <t t-else=""> 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..b1d20406 100644 --- a/indoteknik_custom/views/advance_payment_request.xml +++ b/indoteknik_custom/views/advance_payment_request.xml @@ -4,7 +4,7 @@ <field name="name">advance.payment.request.form</field> <field name="model">advance.payment.request</field> <field name="arch" type="xml"> - <form string="Advance Payment Request & Reimburse" duplicate="0"> + <form string="Advance Payment Request & Reimburse" duplicate="0" delete="false"> <header> <button name="action_realisasi_pum" type="object" @@ -44,6 +44,11 @@ ('is_cab_visible', '=', True), ('type_request', '!=', 'reimburse') ]}"/> + <button name="action_open_cancel_wizard" + string="Cancel" + type="object" + class="btn-danger" + attrs="{'invisible': [('status', 'in', ['draft', 'cancel'])]}"/> <field name="status" widget="statusbar" statusbar_visible="draft,pengajuan1,pengajuan2,pengajuan3,approved" statusbar_colors='{"reject":"red"}' @@ -194,7 +199,7 @@ <field name="name">advance.payment.request.tree</field> <field name="model">advance.payment.request</field> <field name="arch" type="xml"> - <tree> + <tree delete="false"> <field name="number"/> <field name="applicant_name"/> <field name="nominal"/> @@ -316,4 +321,34 @@ <field name="view_id" ref="view_form_create_reimburse_cab_wizard"/> <field name="target">new</field> </record> + + <record id="view_advance_payment_cancel_wizard_form" model="ir.ui.view"> + <field name="name">advance.payment.cancel.wizard.form</field> + <field name="model">advance.payment.cancel.wizard</field> + <field name="arch" type="xml"> + <form string="Batalkan Pengajuan"> + <sheet> + <group> + <div class="alert alert-warning" role="alert" style="margin-bottom: 10px;"> + Apakah Anda yakin ingin membatalkan pengajuan ini? + Silakan isi alasan pembatalan di bawah ini. + </div> + </group> + <group> + <field name="reason"/> + </group> + </sheet> + <footer> + <button name="action_confirm_cancel" + string="Konfirmasi Cancel" + type="object" + class="btn-danger"/> + + <button string="Tutup" + class="btn-secondary" + special="cancel"/> + </footer> + </form> + </field> + </record> </odoo>
\ No newline at end of file diff --git a/indoteknik_custom/views/advance_payment_settlement.xml b/indoteknik_custom/views/advance_payment_settlement.xml index a77baffe..a8bf1de7 100644 --- a/indoteknik_custom/views/advance_payment_settlement.xml +++ b/indoteknik_custom/views/advance_payment_settlement.xml @@ -3,7 +3,7 @@ <field name="name">advance.payment.settlement.form</field> <field name="model">advance.payment.settlement</field> <field name="arch" type="xml"> - <form string="Advance Payment Settlement" duplicate="0"> + <form string="Advance Payment Settlement" duplicate="0" delete="false"> <header> <button name="action_cab" type="object" @@ -163,10 +163,13 @@ <field name="arch" type="xml"> <tree create="false" delete="false"> <field name="name"/> - <field name="pum_id"/> - <field name="grand_total_use" string="Total Realisasi"/> + <field name="applicant_name"/> + <!-- <field name="pum_id"/> --> + <field name="nominal_pum" string="Total Pengajuan"/> + <field name="grand_total_use" string="Total Penggunaan"/> <field name="remaining_value" string="Sisa PUM"/> <field name="status" widget="badge" decoration-success="status == 'approved'"/> + <field name="is_cab_visible" widget="boolean"/> </tree> </field> </record> 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 @@ <field name="res_name" optional="hide"/> <field name="res_id" optional="hide"/> <field name="name"/> + <field name="customer"/> <field name="salesperson"/> <field name="totalamt"/> <field name="uang_masuk_line_id" optional="hide"/> 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 @@ <field name="code">action = records.open_form_multi_generate_request_po()</field> </record> + <record id="purchasing_job_action_seen_ir_actions_server" model="ir.actions.server"> + <field name="name">Seen Selected Job</field> + <field name="model_id" ref="model_v_purchasing_job"/> + <field name="binding_model_id" ref="model_v_purchasing_job"/> + <field name="binding_view_types">form,list</field> + <field name="state">code</field> + <field name="code">action = records._set_as_seen()</field> + </record> + <menuitem id="menu_purchasing_job" name="Purchasing Job" @@ -106,4 +115,4 @@ action="v_purchasing_job_action" /> -</odoo>
\ No newline at end of file +</odoo> |
