from odoo import models, fields, api, _, Command from odoo.exceptions import UserError class AccountPayment(models.Model): _inherit = 'account.payment' second_move_id = fields.Many2one( 'account.move', string='Second Journal Entry', copy=False, ondelete='set null', help='The second journal entry automatically created to transfer funds from branch cash to Kas Kecil.' ) def action_post(self): # Call super first to post the main entry super().action_post() for payment in self: # Only generate/post the second entry if the journal type is 'general' if payment.journal_id.type == 'general': if not payment.second_move_id: # Find the cash journal for this branch/company cash_journal = self.env['account.journal'].search([ ('company_id', '=', payment.company_id.id), ('type', '=', 'cash') ], limit=1) if not cash_journal or not cash_journal.default_account_id: raise UserError(_("No cash journal with a default account found for company %s.") % payment.company_id.name) if not payment.journal_id.default_account_id: raise UserError(_("No default account found on general journal %s.") % payment.journal_id.name) debit_account = payment.journal_id.default_account_id credit_account = cash_journal.default_account_id amount = payment.amount currency = payment.currency_id company = payment.company_id if currency != company.currency_id: balance = currency._convert( amount, company.currency_id, company, payment.date or fields.Date.today() ) else: balance = amount debit_line_vals = { 'name': _("Second Entry Debit for %s") % payment.name, 'account_id': debit_account.id, 'debit': balance, 'credit': 0.0, 'partner_id': payment.partner_id.id, } credit_line_vals = { 'name': _("Second Entry Credit for %s") % payment.name, 'account_id': credit_account.id, 'debit': 0.0, 'credit': balance, 'partner_id': payment.partner_id.id, } if currency != company.currency_id: debit_line_vals.update({ 'currency_id': currency.id, 'amount_currency': amount, }) credit_line_vals.update({ 'currency_id': currency.id, 'amount_currency': -amount, }) line_ids = [ Command.create(debit_line_vals), Command.create(credit_line_vals), ] move_vals = { 'move_type': 'entry', 'ref': payment.name, 'date': payment.date, 'journal_id': payment.journal_id.id, 'company_id': payment.company_id.id, 'partner_id': payment.partner_id.id, 'currency_id': payment.currency_id.id, 'line_ids': line_ids, } # Create and post the second move second_move = self.env['account.move'].create(move_vals) second_move.action_post() payment.write({'second_move_id': second_move.id}) elif payment.second_move_id.state == 'draft': # If it already exists and is draft (e.g. after resetting payment to draft), post it payment.second_move_id.action_post() def action_draft(self): super().action_draft() for payment in self: if payment.second_move_id: if payment.second_move_id.state != 'draft': payment.second_move_id.button_draft() def action_cancel(self): super().action_cancel() for payment in self: if payment.second_move_id: if payment.second_move_id.state == 'draft': payment.second_move_id.unlink() else: payment.second_move_id.button_cancel() def unlink(self): for payment in self: if payment.second_move_id: second_move = payment.second_move_id if second_move.state != 'draft': second_move.button_draft() second_move.unlink() return super().unlink() def button_open_second_journal_entry(self): self.ensure_one() return { 'name': _("Second Journal Entry"), 'type': 'ir.actions.act_window', 'res_model': 'account.move', 'context': {'create': False}, 'view_mode': 'form', 'res_id': self.second_move_id.id, }