account_shared_bank_cash/models/account_move.py

180 lines
8.5 KiB
Python

# -*- coding: utf-8 -*-
from odoo import models, api, fields, _
from odoo.exceptions import UserError, ValidationError
class AccountMove(models.Model):
_inherit = 'account.move'
rk_payment_journal_id = fields.Many2one(
'account.journal',
string='RK Payment Journal',
help='The bank/cash journal used for this Hubungan RK process'
)
def _get_last_sequence(self, relaxed=False, with_prefix=None):
self.ensure_one()
if not self.rk_payment_journal_id:
return super()._get_last_sequence(relaxed=relaxed, with_prefix=with_prefix)
if self._sequence_field not in self._fields or not self._fields[self._sequence_field].store:
raise ValidationError(_('%s is not a stored field', self._sequence_field))
where_string, param = self._get_last_sequence_domain(relaxed)
if self._origin.id:
where_string += " AND id != %(id)s "
param['id'] = self._origin.id
prefix_base = f"{self.journal_id.code}-{self.rk_payment_journal_id.code}"
if with_prefix is not None:
where_string += " AND sequence_prefix = %(with_prefix)s "
param['with_prefix'] = with_prefix
else:
where_string += " AND sequence_prefix LIKE %(prefix_like)s "
param['prefix_like'] = f"{prefix_base}/%"
query = f"""
SELECT {self._sequence_field} FROM {self._table}
{where_string}
AND sequence_prefix = (SELECT sequence_prefix FROM {self._table} {where_string} ORDER BY id DESC LIMIT 1)
ORDER BY sequence_number DESC
LIMIT 1
"""
self.flush_model([self._sequence_field, 'sequence_number', 'sequence_prefix'])
self.env.cr.execute(query, param)
return (self.env.cr.fetchone() or [None])[0]
def _get_starting_sequence(self):
self.ensure_one()
if self.rk_payment_journal_id:
move_date = self.date or self.invoice_date or fields.Date.context_today(self)
year_part = "%04d" % move_date.year
prefix_base = f"{self.journal_id.code}-{self.rk_payment_journal_id.code}"
return f"{prefix_base}/{year_part}/{move_date.month:02d}/0000"
return super()._get_starting_sequence()
def action_post(self):
res = super().action_post()
# 1. Handle Centralized entries in Parent when payment moves are posted
for move in self:
payments = move.payment_ids or move.origin_payment_id
if not payments:
continue
centralized_payments = payments.filtered(
lambda p: p.journal_id.sudo().is_centralized and
p.company_id != p.journal_id.sudo().parent_company_id
)
for payment in centralized_payments:
journal_sudo = payment.journal_id.sudo()
parent_company = journal_sudo.parent_company_id
parent_journal = journal_sudo.parent_journal_id
parent_rk_account = journal_sudo.parent_intercompany_account_id
if not journal_sudo.branch_intercompany_account_id:
raise UserError(_("Please configure the Branch Inter-company Account on journal %s", payment.journal_id.name))
if not parent_journal or not parent_rk_account:
raise UserError(_("Please configure the Parent Journal and RK Account on journal %s", payment.journal_id.name))
parent_journal_sudo = parent_journal.sudo()
parent_rk_account_sudo = parent_rk_account.sudo()
print(f">>> DEBUG: Centralized Payment for {payment.name}")
print(f" Company: {payment.company_id.id}, Parent Co: {parent_company.id}")
print(f" Parent Journal: {parent_journal_sudo.name} (ID: {parent_journal_sudo.id})")
print(f" Parent RK: {parent_rk_account_sudo.code} (ID: {parent_rk_account_sudo.id})")
# Calculate currency-adjusted amount for the parent company
parent_currency = parent_company.currency_id
if payment.currency_id != parent_currency:
amount_parent_curr = payment.currency_id._convert(
payment.amount, parent_currency, parent_company, payment.date
)
else:
amount_parent_curr = payment.amount
# Create the mirroring entry in Parent using sudo
parent_move = self.env['account.move'].sudo().with_company(parent_company).create({
'move_type': 'entry',
'date': payment.date,
'company_id': parent_company.id,
'journal_id': parent_journal.id,
'partner_id': payment.company_id.partner_id.id,
'currency_id': parent_currency.id,
'ref': f"Centralized Payment: {payment.name} ({payment.company_id.name})",
'line_ids': [
(0, 0, {
'name': payment.memo or f"Centralized Payment: {payment.name}",
'account_id': parent_rk_account.id,
'debit': amount_parent_curr,
'credit': 0.0,
'partner_id': payment.company_id.partner_id.id,
'company_id': parent_company.id,
'currency_id': payment.currency_id.id,
'amount_currency': payment.amount,
'display_type': 'product',
}),
(0, 0, {
'name': payment.memo or f"Centralized Payment: {payment.name}",
'account_id': parent_journal_sudo.default_account_id.id,
'debit': 0.0,
'credit': amount_parent_curr,
'partner_id': payment.company_id.partner_id.id,
'company_id': parent_company.id,
'currency_id': payment.currency_id.id,
'amount_currency': -payment.amount,
'display_type': 'product',
}),
]
})
parent_move.sudo().action_post()
print(f" Parent Move Posted: {parent_move.name}")
return res
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
@api.model
def _search_account_id(self, operator, value):
res = super()._search_account_id(operator, value)
if res and isinstance(res, list) and len(res) == 1:
term = res[0]
if len(term) == 3 and term[0] == 'account_id' and term[1] in ('in', 'not in') and isinstance(term[2], (list, tuple, set)):
resolved_ids = list(term[2])
reconcile_accounts = self.env['account.account'].sudo().browse(resolved_ids).filtered('reconcile')
if reconcile_accounts:
cash_accounts = self.env['account.account'].sudo().search([('account_type', '=', 'asset_cash')])
if cash_accounts:
if term[1] == 'in':
res = [
'|',
('account_id', 'in', tuple(reconcile_accounts.ids)),
'&',
'&',
('account_id', 'in', tuple(cash_accounts.ids)),
('journal_id.type', '=', 'cash'),
('journal_id.company_id', '=', self.env.company.id)
]
elif term[1] == 'not in':
res = [
'&',
('account_id', 'not in', tuple(reconcile_accounts.ids)),
'|',
'|',
('account_id', 'not in', tuple(cash_accounts.ids)),
('journal_id.type', '!=', 'cash'),
('journal_id.company_id', '!=', self.env.company.id)
]
return res
def _related_analytic_distribution(self):
res = super()._related_analytic_distribution()
if res:
return self.env['analytic.mixin']._clean_analytic_distribution(res)
return res