157 lines
6.2 KiB
Python
157 lines
6.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
import logging
|
|
from odoo import models, fields, api, _
|
|
from odoo.exceptions import ValidationError
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class AccountBatchPayment(models.Model):
|
|
_inherit = "account.batch.payment"
|
|
|
|
# Add a field to store direct payment lines
|
|
direct_payment_line_ids = fields.One2many(
|
|
'account.batch.payment.line',
|
|
'batch_payment_id',
|
|
string='Direct Payment Lines'
|
|
)
|
|
|
|
def generate_payments_from_lines(self):
|
|
"""Generate actual payments from the direct payment lines"""
|
|
self.ensure_one()
|
|
payment_ids = []
|
|
|
|
# First, try to use the journal's available payment methods
|
|
available_payment_methods = self.journal_id._get_available_payment_method_lines(self.batch_type)
|
|
payment_method_line = available_payment_methods.filtered(lambda x: x.code == 'direct_batch')
|
|
|
|
if not payment_method_line:
|
|
# If no direct batch payment method found, use the first available payment method
|
|
if available_payment_methods:
|
|
payment_method_line = available_payment_methods[0]
|
|
else:
|
|
# Fallback: try to find or create a direct batch payment method line
|
|
payment_method_line = self.env['account.payment.method.line'].search([
|
|
('payment_method_id.code', '=', 'direct_batch'),
|
|
('journal_id', '=', self.journal_id.id)
|
|
], limit=1)
|
|
|
|
if not payment_method_line:
|
|
# Try to create the payment method line if it doesn't exist
|
|
payment_method = self.env['account.payment.method'].search([
|
|
('code', '=', 'direct_batch'),
|
|
('payment_type', '=', self.batch_type)
|
|
], limit=1)
|
|
|
|
if payment_method:
|
|
# Check if a payment method line already exists for this journal and method
|
|
existing_pml = self.env['account.payment.method.line'].search([
|
|
('payment_method_id', '=', payment_method.id),
|
|
('journal_id', '=', self.journal_id.id)
|
|
], limit=1)
|
|
|
|
if not existing_pml:
|
|
payment_method_line = self.env['account.payment.method.line'].create({
|
|
'name': payment_method.name,
|
|
'payment_method_id': payment_method.id,
|
|
'journal_id': self.journal_id.id,
|
|
})
|
|
else:
|
|
payment_method_line = existing_pml
|
|
else:
|
|
raise ValidationError(_("No payment method found for this journal."))
|
|
|
|
# Check that all lines have a partner
|
|
for line in self.direct_payment_line_ids:
|
|
if not line.partner_id:
|
|
raise ValidationError(_("All payment lines must have a partner selected."))
|
|
|
|
for line in self.direct_payment_line_ids:
|
|
# Determine payment type and partner type based on batch type
|
|
payment_type = self.batch_type
|
|
partner_type = 'customer' if self.batch_type == 'inbound' else 'supplier'
|
|
|
|
# Create the payment
|
|
payment_vals = {
|
|
'payment_type': payment_type,
|
|
'partner_type': partner_type,
|
|
'partner_id': line.partner_id.id,
|
|
'amount': line.amount,
|
|
'currency_id': line.currency_id.id,
|
|
'date': line.date,
|
|
'journal_id': self.journal_id.id,
|
|
'payment_method_line_id': payment_method_line.id,
|
|
'ref': line.memo,
|
|
'expense_account_id': line.expense_account_id.id,
|
|
}
|
|
|
|
payment = self.env['account.payment'].create(payment_vals)
|
|
payment.action_post()
|
|
|
|
# Link the payment to the line
|
|
line.payment_id = payment.id
|
|
payment_ids.append(payment.id)
|
|
|
|
# Add the generated payments to the batch
|
|
if payment_ids:
|
|
self.write({
|
|
'payment_ids': [(4, payment_id) for payment_id in payment_ids]
|
|
})
|
|
|
|
# Automatically validate the batch payment after generating payments
|
|
if self.state == 'draft':
|
|
try:
|
|
self.validate_batch()
|
|
except Exception as e:
|
|
# If validation fails, log the error but don't prevent payment creation
|
|
_logger.warning(f"Failed to automatically validate batch payment {self.id}: {str(e)}")
|
|
|
|
|
|
class AccountBatchPaymentLine(models.Model):
|
|
_name = "account.batch.payment.line"
|
|
_description = "Batch Payment Line"
|
|
|
|
batch_payment_id = fields.Many2one(
|
|
'account.batch.payment',
|
|
string='Batch Payment',
|
|
required=True,
|
|
ondelete='cascade'
|
|
)
|
|
partner_id = fields.Many2one(
|
|
'res.partner',
|
|
string='Partner'
|
|
# Removed required=True to avoid constraint issues
|
|
)
|
|
amount = fields.Monetary(
|
|
string='Amount',
|
|
required=True
|
|
)
|
|
currency_id = fields.Many2one(
|
|
'res.currency',
|
|
string='Currency',
|
|
related='batch_payment_id.currency_id',
|
|
store=True
|
|
)
|
|
expense_account_id = fields.Many2one(
|
|
'account.account',
|
|
string='Expense Account',
|
|
domain="[('account_type', 'not in', ('asset_receivable', 'liability_payable'))]"
|
|
)
|
|
memo = fields.Char(string='Memo')
|
|
date = fields.Date(
|
|
string='Payment Date',
|
|
default=fields.Date.context_today
|
|
)
|
|
payment_id = fields.Many2one(
|
|
'account.payment',
|
|
string='Generated Payment',
|
|
readonly=True
|
|
)
|
|
|
|
@api.onchange('partner_id')
|
|
def _onchange_partner_id(self):
|
|
if self.partner_id:
|
|
# Set default expense account from partner if available
|
|
# Note: property_account_expense doesn't exist on res.partner in standard Odoo
|
|
# We'll leave this empty for now and let the user manually select the expense account
|
|
pass |