90 lines
4.6 KiB
Python
90 lines
4.6 KiB
Python
from odoo import models, fields, api
|
|
|
|
|
|
class AccountPayment(models.Model):
|
|
_inherit = 'account.payment'
|
|
|
|
purchase_order_id = fields.Many2one(
|
|
'purchase.order',
|
|
string='Purchase Order',
|
|
domain="[('partner_id', '=', partner_id), ('state', 'in', ('purchase', 'done'))]"
|
|
)
|
|
|
|
is_advance_payment = fields.Boolean(
|
|
string='Is Advance Payment',
|
|
default=False,
|
|
help='Identifies if this payment is an advance payment for a purchase order'
|
|
)
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
"""Override create to ensure payment_method_line_id is correctly set for advance payments"""
|
|
for vals in vals_list:
|
|
# If this is an advance payment and payment_method_line_id is set,
|
|
# ensure it matches the journal's payment methods
|
|
if vals.get('is_advance_payment') and vals.get('journal_id') and vals.get('payment_method_line_id'):
|
|
journal = self.env['account.journal'].browse(vals['journal_id'])
|
|
payment_method_line = self.env['account.payment.method.line'].browse(vals['payment_method_line_id'])
|
|
|
|
# Verify the payment method line belongs to this journal
|
|
if payment_method_line not in journal.outbound_payment_method_line_ids:
|
|
# If not, find the correct one
|
|
correct_method = journal.outbound_payment_method_line_ids.filtered(
|
|
lambda l: l.payment_method_id == payment_method_line.payment_method_id
|
|
)[:1]
|
|
if correct_method:
|
|
vals['payment_method_line_id'] = correct_method.id
|
|
|
|
return super().create(vals_list)
|
|
|
|
@api.onchange('purchase_order_id')
|
|
def _onchange_purchase_order_id(self):
|
|
if self.purchase_order_id:
|
|
self.amount = self.purchase_order_id.amount_residual
|
|
|
|
def _prepare_move_line_default_vals(self, write_off_line_vals=None, force_balance=None):
|
|
"""Override to use correct accounts for advance payments"""
|
|
line_vals_list = super()._prepare_move_line_default_vals(write_off_line_vals=write_off_line_vals, force_balance=force_balance)
|
|
|
|
if self.is_advance_payment and self.purchase_order_id:
|
|
# Get expense account from default deposit product
|
|
deposit_product_id = self.env['ir.config_parameter'].sudo().get_param(
|
|
'purchase_advance_payment.deposit_product_id')
|
|
|
|
if deposit_product_id:
|
|
product = self.env['product.product'].browse(int(deposit_product_id))
|
|
expense_account = product.property_account_expense_id or product.categ_id.property_account_expense_categ_id
|
|
|
|
if expense_account:
|
|
# Get outstanding payment account from journal
|
|
# For outbound payments, first check journal-specific account, then company default
|
|
outstanding_account = None
|
|
|
|
# Try to get from journal's outbound payment method
|
|
if self.journal_id.outbound_payment_method_line_ids:
|
|
outstanding_account = self.journal_id.outbound_payment_method_line_ids[0].payment_account_id
|
|
|
|
# Fall back to company default if not set on journal
|
|
if not outstanding_account:
|
|
outstanding_account = self.journal_id.company_id.account_journal_payment_credit_account_id
|
|
|
|
if outstanding_account:
|
|
# Modify the line vals to use correct accounts
|
|
for line_vals in line_vals_list:
|
|
# The debit line (expense) - partner line
|
|
if line_vals.get('debit', 0) > 0 and line_vals.get('partner_id'):
|
|
line_vals['account_id'] = expense_account.id
|
|
# The credit line (outstanding payment)
|
|
elif line_vals.get('credit', 0) > 0:
|
|
line_vals['account_id'] = outstanding_account.id
|
|
|
|
return line_vals_list
|
|
|
|
def action_post(self):
|
|
res = super().action_post()
|
|
# When an advance payment is posted, update deposit line in purchase order
|
|
for payment in self:
|
|
if payment.is_advance_payment and payment.purchase_order_id:
|
|
# Update the deposit line with the actual posted amount
|
|
payment.purchase_order_id._update_deposit_line()
|
|
return res |