From ca5912d9f29f4bb2e7b482cce01f917285ed53cb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 4 Aug 2025 09:55:46 +0700 Subject: penyusutan, reklas, journal uang muka --- fixco_custom/models/__init__.py | 5 +- fixco_custom/models/account_move.py | 21 +++ fixco_custom/models/invoice_reklas.py | 173 +++++++++++++++++++++ fixco_custom/models/purchase_order.py | 27 ++++ fixco_custom/models/sale.py | 28 ++++ fixco_custom/models/stock_picking.py | 19 ++- fixco_custom/models/uangmuka_pembelian.py | 121 ++++++++++++++ .../models/update_depreciation_move_wizard.py | 32 ++++ 8 files changed, 424 insertions(+), 2 deletions(-) create mode 100644 fixco_custom/models/invoice_reklas.py create mode 100644 fixco_custom/models/uangmuka_pembelian.py create mode 100644 fixco_custom/models/update_depreciation_move_wizard.py (limited to 'fixco_custom/models') diff --git a/fixco_custom/models/__init__.py b/fixco_custom/models/__init__.py index 297002e..23f28a9 100755 --- a/fixco_custom/models/__init__.py +++ b/fixco_custom/models/__init__.py @@ -26,4 +26,7 @@ from . import stock_move from . import upload_bills from . import brands from . import product_public_category -from . import reordering_rule \ No newline at end of file +from . import reordering_rule +from . import update_depreciation_move_wizard +from . import invoice_reklas +from . import uangmuka_pembelian \ No newline at end of file diff --git a/fixco_custom/models/account_move.py b/fixco_custom/models/account_move.py index f491bc4..971e9e3 100644 --- a/fixco_custom/models/account_move.py +++ b/fixco_custom/models/account_move.py @@ -33,6 +33,27 @@ class AccountMove(models.Model): ) faktur_pajak = fields.Char('Faktur Pajak') count_payment = fields.Integer('Count Payment', compute='_compute_count_payment') + reklas_misc_id = fields.Many2one('account.move', string='Journal Entries Reklas') + purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order') + bill_id = fields.Many2one('account.move', string='Vendor Bill', domain=[('move_type', '=', 'in_invoice')], help='Bill asal dari proses reklas ini') + + def open_form_multi_create_reklas_penjualan(self): + action = self.env['ir.actions.act_window']._for_xml_id('fixco_custom.action_view_invoice_reklas_penjualan') + invoice = self.env['invoice.reklas.penjualan'].create([{ + 'name': '-', + }]) + for move in self: + sale_id = move.sale_id.id + self.env['invoice.reklas.penjualan.line'].create([{ + 'invoice_reklas_id': invoice.id, + 'name': move.name, + 'partner_id': move.partner_id.id, + 'sale_id': move.sale_id.id, + 'amount_untaxed_signed': move.amount_untaxed_signed, + 'amount_total_signed': move.amount_total_signed, + }]) + action['res_id'] = invoice.id + return action def _compute_count_payment(self): for move in self: diff --git a/fixco_custom/models/invoice_reklas.py b/fixco_custom/models/invoice_reklas.py new file mode 100644 index 0000000..d97d868 --- /dev/null +++ b/fixco_custom/models/invoice_reklas.py @@ -0,0 +1,173 @@ +from odoo import api, fields, models, _ +from odoo.exceptions import UserError +from datetime import datetime +from odoo.http import request + +import logging + +_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')]") + pay_amt = fields.Float(string='Yang dibayarkan') + reklas_type = fields.Selection([ + ('penjualan', 'Penjualan'), + ('pembelian', 'Pembelian'), + ], string='Reklas Tipe') + + @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_id and move.purchase_id.move_id: + cab = move.purchase_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_id and move.purchase_id.move_id: + cab = move.purchase_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 + + 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_id.name if invoice.purchase_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', + f" {invoice.name}" if invoice.name != self.reklas_id.name else '', + 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': 19 + } + + if invoice.purchase_id: + parameters_header['purchase_id'] = invoice.purchase_id.id + + account_move = request.env['account.move'].create([parameters_header]) + _logger.info('Success Reklas with %s' % account_move.name) + + # ✅ Set Bill asal sebagai source document + if invoice.move_type == 'in_invoice': + 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': 578, # penerimaan belum alokasi + 'partner_id': invoice.partner_id.id, + 'currency_id': 12, + 'debit': self.pay_amt, + 'credit': 0, + 'name': ref_name + } + parameter_credit = { + 'move_id': account_move.id, + 'account_id': 347, + 'partner_id': invoice.partner_id.id, + 'currency_id': 12, + 'debit': 0, + 'credit': self.pay_amt, + 'name': ref_name + } + else: # pembelian + parameter_debit = { + 'move_id': account_move.id, + 'account_id': 388, + 'partner_id': invoice.partner_id.id, + 'currency_id': 12, + 'debit': self.pay_amt, + 'credit': 0, + 'name': ref_name + } + parameter_credit = { + 'move_id': account_move.id, + 'account_id': 579, + 'partner_id': invoice.partner_id.id, + 'currency_id': 12, + 'debit': 0, + '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', + 'res_model': 'account.move', + 'target': 'current', + 'view_id': False, + 'type': 'ir.actions.act_window', + 'res_id': account_move.id + } diff --git a/fixco_custom/models/purchase_order.py b/fixco_custom/models/purchase_order.py index 75263b1..0869cc8 100644 --- a/fixco_custom/models/purchase_order.py +++ b/fixco_custom/models/purchase_order.py @@ -24,6 +24,7 @@ class PurchaseOrder(models.Model): index=True ) sale_order_id = fields.Many2one('sale.order', string='Sales Order') + move_entry_id = fields.Many2one('account.move', string='Journal Entries') amount_discount = fields.Monetary( string='Total Discount', compute='_compute_amount_discount', @@ -42,6 +43,32 @@ class PurchaseOrder(models.Model): ('purchasing_job', 'Purchasing Job'), ('manual', 'Manual') ], string='Source', default='manual') + count_journals = fields.Integer('Count Payment', compute='_compute_count_journals') + + def _compute_count_journals(self): + for order in self: + journals = self.env['account.move'].search([ + ('purchase_order_id', '=', order.id), + ('move_type', '!=', 'in_invoice') + ]) + order.count_journals = len(journals) + + def action_view_related_journals(self): + self.ensure_one() + + journals = self.env['account.move'].search([ + ('purchase_order_id', '=', self.id), + ('move_type', '!=', 'in_invoice') + ]) + + return { + 'name': 'Journals', + 'type': 'ir.actions.act_window', + 'res_model': 'account.move', + 'view_mode': 'tree,form', + 'target': 'current', + 'domain': [('id', 'in', journals.ids)], + } @api.depends('order_line.price_total', 'biaya_lain_lain') def _amount_all(self): diff --git a/fixco_custom/models/sale.py b/fixco_custom/models/sale.py index b77c92c..9943376 100755 --- a/fixco_custom/models/sale.py +++ b/fixco_custom/models/sale.py @@ -13,6 +13,34 @@ class SaleOrder(models.Model): count_payment = fields.Integer('Count Payment', compute='_compute_count_payment') + count_journals = fields.Integer('Count Payment', compute='_compute_count_journals') + + def _compute_count_journals(self): + for order in self: + journals = self.env['account.move'].search([ + ('sale_id', '=', order.id), + ('move_type', '!=', 'out_invoice') + ]) + order.count_journals = len(journals) + + def action_view_related_journals(self): + self.ensure_one() + + journals = self.env['account.move'].search([ + ('sale_id', '=', self.id), + ('move_type', '!=', 'out_invoice') + ]) + + return { + 'name': 'Journals', + 'type': 'ir.actions.act_window', + 'res_model': 'account.move', + 'view_mode': 'tree,form', + 'target': 'current', + 'domain': [('id', 'in', journals.ids)], + } + + def _compute_count_payment(self): for rec in self: if rec.invoice_ids: diff --git a/fixco_custom/models/stock_picking.py b/fixco_custom/models/stock_picking.py index d38f8a4..408e055 100755 --- a/fixco_custom/models/stock_picking.py +++ b/fixco_custom/models/stock_picking.py @@ -43,6 +43,7 @@ class StockPicking(models.Model): compute="_compute_pdf_binary", store=False ) + is_printed = fields.Boolean(string="Sudah Dicetak", default=False) def action_create_invoice_from_mr(self): """Create the invoice associated to the PO. @@ -464,4 +465,20 @@ class CheckProduct(models.Model): ) % (record.product_id.display_name)) # Set the quantity to the entered value - record.quantity = record.quantity \ No newline at end of file + record.quantity = record.quantity + +class PickingReportCustom(models.AbstractModel): + _name = 'report.fixco_custom.report_picking_list_custom' + _description = 'Custom Picking List Report' + + def _get_report_values(self, docids, data=None): + pickings = self.env['stock.picking'].browse(docids) + + # Update flag is_printed jadi True + pickings.write({'is_printed': True}) + + return { + 'doc_ids': docids, + 'doc_model': 'stock.picking', + 'docs': pickings, + } \ No newline at end of file diff --git a/fixco_custom/models/uangmuka_pembelian.py b/fixco_custom/models/uangmuka_pembelian.py new file mode 100644 index 0000000..9374ba2 --- /dev/null +++ b/fixco_custom/models/uangmuka_pembelian.py @@ -0,0 +1,121 @@ +from odoo import fields, models, _, api +from odoo.exceptions import UserError +from datetime import datetime +from odoo.http import request + +import logging, math + +_logger = logging.getLogger(__name__) + + +class UangmukaPembelian(models.TransientModel): + _name = 'uangmuka.pembelian' + _description = 'digunakan untuk membuat Uang Muka Pembelian' + + pay_amt = fields.Float(string='Uang Muka', help='berapa nilai yang terbentuk untuk COA Uang Muka Pembelian') + account_id = fields.Many2one('account.account', string='Bank Intransit', default=389, help='pilih COA intransit bank') + ongkir_amt = fields.Float(string='Ongkir', help='masukan nilai yang akan menjadi Pendapatan Ongkos Kirim') + selisih_amt = fields.Float(string='Selisih', help='masukan nilai yang akan menjadi Selisih Pembayaran') + total_amt = fields.Float(string='Total', help='Total yang akan masuk di journal entries') + + @api.onchange('pay_amt', 'ongkir_amt', 'selisih_amt') + def _compute_total_amt(self): + for o in self: + o.total_amt = o.pay_amt + o.ongkir_amt + o.selisih_amt + + def create_uangmukapembelian(self): + if not self.account_id: + raise UserError('Bank Intransit harus diisi') + + orders = self.env['purchase.order'].browse(self._context.get('active_ids',[])) + current_time = datetime.now() + + is_have_ongkir = is_have_selisih = False + if self.ongkir_amt > 0: + is_have_ongkir = True + if not math.isclose(self.selisih_amt, 0): + is_have_selisih = True + + for order in orders: + # if order.is_create_uangmuka == True: + # action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_purchase_order_multi_uangmuka2') + # action['context'] = { + # 'order_ids': [x.id for x in order] + # } + # return action + partner_name = order.partner_id.name + if order.partner_id.parent_id: + partner_name = order.partner_id.parent_id.name + ref_label = 'UANG MUKA PEMBELIAN '+order.name+' '+partner_name + param_header = { + 'ref': ref_label, + 'date': current_time, + 'journal_id': 23, + 'purchase_order_id': order.id + } + + 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: + partner_id = order.partner_id.id + + param_debit = { + 'move_id': account_move.id, + 'account_id': 579, # uang muka persediaan barang dagang + 'partner_id': partner_id, + 'currency_id': 12, + 'debit': self.pay_amt, + 'credit': 0, + 'name': ref_label, + } + param_debit_ongkir = { + 'move_id': account_move.id, + 'account_id': 758, # biaya ongkos kirim + 'partner_id': partner_id, + 'currency_id': 12, + 'debit': self.ongkir_amt, + 'credit': 0, + 'name': ref_label, + } + param_debit_selisih = { + 'move_id': account_move.id, + 'account_id': 767, # selisih pembayaran + 'partner_id': partner_id, + 'currency_id': 12, + 'debit': self.selisih_amt, + 'credit': 0, + 'name': ref_label, + } + + param_credit = { + 'move_id': account_move.id, + 'account_id': self.account_id.id, # bank in transit + 'partner_id': partner_id, + 'currency_id': 12, + 'debit': 0, + 'credit': self.pay_amt + self.ongkir_amt + self.selisih_amt, + 'name': ref_label, + } + if is_have_ongkir and is_have_selisih: + request.env['account.move.line'].create([param_debit, param_debit_ongkir, param_debit_selisih, param_credit]) + elif is_have_ongkir: + request.env['account.move.line'].create([param_debit, param_debit_ongkir, param_credit]) + elif is_have_selisih: + request.env['account.move.line'].create([param_debit, param_debit_selisih, param_credit]) + else: + request.env['account.move.line'].create([param_debit, param_credit]) + # order.is_create_uangmuka = True + order.move_entry_id = account_move.id + return { + 'name': _('Journal Entries'), + 'view_mode': 'form', + 'res_model': 'account.move', + 'target': 'current', + 'view_id': False, + 'type': 'ir.actions.act_window', + 'res_id': account_move.id + } diff --git a/fixco_custom/models/update_depreciation_move_wizard.py b/fixco_custom/models/update_depreciation_move_wizard.py new file mode 100644 index 0000000..094494b --- /dev/null +++ b/fixco_custom/models/update_depreciation_move_wizard.py @@ -0,0 +1,32 @@ +from odoo import models, fields, api +from odoo.exceptions import UserError + +class UpdateDepreciationMoveWizard(models.TransientModel): + _name = 'update.depreciation.move.wizard' + _description = 'Wizard untuk Update Move Check Depreciation Line' + + target_date = fields.Date(string="Tanggal Depresiasi", required=True) + + def action_update_move_check(self): + lines = self.env['account.asset.depreciation.line'].search([ + ('depreciation_date', '=', self.target_date), + ]) + if not lines: + raise UserError("Tidak ada baris depresiasi dengan tanggal tersebut.") + + updated_count = 0 + for line in lines: + if not line.move_check: + line.move_check = True + updated_count += 1 + + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': 'Update Selesai', + 'message': f'{updated_count} baris berhasil di-update.', + 'type': 'success', + 'sticky': False, + } + } -- cgit v1.2.3