Compare commits

..

1 Commits
19.0 ... main

15 changed files with 27 additions and 38 deletions

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
{ {
'name': 'Vendor Payment Diff Amount', 'name': 'Vendor Payment Diff Amount',
'version': '19.0.2.1.0', 'version': '17.0.2.1.0',
'category': 'Accounting/Accounting', 'category': 'Accounting/Accounting',
'summary': 'Support multiple payment deductions for vendor payments (withholding tax, fees, etc.)', 'summary': 'Support multiple payment deductions for vendor payments (withholding tax, fees, etc.)',
'description': """ 'description': """

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -58,7 +58,7 @@ class PaymentDeductionLine(models.Model):
'account.account', 'account.account',
string='Deduction Account', string='Deduction Account',
required=True, required=True,
domain="[('account_type', 'not in', ['asset_cash', 'asset_cash_bank', 'asset_receivable', 'liability_payable']), ('active', '=', True)]", domain="[('account_type', 'not in', ['asset_cash', 'asset_cash_bank', 'asset_receivable', 'liability_payable']), ('deprecated', '=', False)]",
help='Account where the deduction will be recorded (use tax payable or expense accounts, NOT payable/receivable accounts)', help='Account where the deduction will be recorded (use tax payable or expense accounts, NOT payable/receivable accounts)',
) )
name = fields.Char( name = fields.Char(

Binary file not shown.

Binary file not shown.

View File

@ -1,12 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from odoo import fields from odoo import fields
from odoo.tests import TransactionCase, tagged from odoo.tests import TransactionCase
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from hypothesis import given, strategies as st, settings from hypothesis import given, strategies as st, settings
@tagged('post_install', '-at_install')
class TestAccountPayment(TransactionCase): class TestAccountPayment(TransactionCase):
"""Test cases for vendor payment deduction functionality""" """Test cases for vendor payment deduction functionality"""
@ -38,7 +37,7 @@ class TestAccountPayment(TransactionCase):
'name': 'Withholding Tax Account', 'name': 'Withholding Tax Account',
'code': 'WHT001', 'code': 'WHT001',
'account_type': 'expense', 'account_type': 'expense',
'company_ids': [self.env.company.id], 'company_id': self.env.company.id,
}) })
@given( @given(

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from odoo import fields from odoo import fields
from odoo.tests import TransactionCase, tagged from odoo.tests import TransactionCase
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
@tagged('post_install', '-at_install')
class TestBatchPaymentIntegration(TransactionCase): class TestBatchPaymentIntegration(TransactionCase):
"""Test cases for batch payment integration with deduction functionality""" """Test cases for batch payment integration with deduction functionality"""

View File

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Add deduction lines field to batch payment line list view --> <!-- Add deduction lines field to batch payment line tree view -->
<record id="view_batch_payment_form_inherit_diff_amount" model="ir.ui.view"> <record id="view_batch_payment_form_inherit_diff_amount" model="ir.ui.view">
<field name="name">account.batch.payment.form.inherit.diff.amount</field> <field name="name">account.batch.payment.form.inherit.diff.amount</field>
<field name="model">account.batch.payment</field> <field name="model">account.batch.payment</field>
<field name="inherit_id" ref="vendor_batch_payment_merge.view_batch_payment_form_inherit"/> <field name="inherit_id" ref="vendor_batch_payment_merge.view_batch_payment_form_inherit"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<!-- Replace the list view with one that includes a form view for deduction lines --> <!-- Replace the tree view with one that includes a form view for deduction lines -->
<xpath expr="//field[@name='direct_payment_line_ids']" position="replace"> <xpath expr="//field[@name='direct_payment_line_ids']" position="replace">
<field name="direct_payment_line_ids"> <field name="direct_payment_line_ids">
<list editable="bottom"> <tree editable="bottom">
<field name="partner_id" domain="parent.batch_type == 'outbound' and [('supplier_rank', '>', 0)] or [('customer_rank', '>', 0)]" options="{'no_create': True}"/> <field name="partner_id" domain="parent.batch_type == 'outbound' and [('supplier_rank', '>', 0)] or [('customer_rank', '>', 0)]" options="{'no_create': True}"/>
<field name="amount" sum="Total"/> <field name="amount" sum="Total"/>
<field name="expense_account_id"/> <field name="expense_account_id"/>
@ -17,7 +17,7 @@
<field name="memo"/> <field name="memo"/>
<field name="date"/> <field name="date"/>
<field name="payment_id" readonly="1"/> <field name="payment_id" readonly="1"/>
</list> </tree>
<form> <form>
<group> <group>
<group name="payment_info"> <group name="payment_info">
@ -32,13 +32,13 @@
</group> </group>
<group string="Deductions" name="deductions"> <group string="Deductions" name="deductions">
<field name="deduction_line_ids" nolabel="1" context="{'default_currency_id': currency_id}"> <field name="deduction_line_ids" nolabel="1" context="{'default_currency_id': currency_id}">
<list editable="bottom"> <tree editable="bottom">
<field name="sequence" widget="handle"/> <field name="sequence" widget="handle"/>
<field name="substract_account_id" required="1"/> <field name="substract_account_id" required="1"/>
<field name="name" placeholder="Description (optional)"/> <field name="name" placeholder="Description (optional)"/>
<field name="amount_substract" required="1" sum="Total"/> <field name="amount_substract" required="1" sum="Total"/>
<field name="currency_id" column_invisible="1"/> <field name="currency_id" column_invisible="1"/>
</list> </tree>
</field> </field>
<field name="amount_substract" readonly="1"/> <field name="amount_substract" readonly="1"/>
</group> </group>

View File

@ -12,14 +12,14 @@
invisible="payment_type != 'outbound'" invisible="payment_type != 'outbound'"
readonly="state != 'draft'" readonly="state != 'draft'"
nolabel="1"> nolabel="1">
<list editable="bottom"> <tree editable="bottom">
<field name="sequence" widget="handle"/> <field name="sequence" widget="handle"/>
<field name="substract_account_id" required="1"/> <field name="substract_account_id" required="1"/>
<field name="name" placeholder="Description (optional)"/> <field name="name" placeholder="Description (optional)"/>
<field name="amount_substract" required="1" sum="Total Deductions"/> <field name="amount_substract" required="1" sum="Total Deductions"/>
<field name="currency_id" column_invisible="1"/> <field name="currency_id" column_invisible="1"/>
<field name="company_id" column_invisible="1"/> <field name="company_id" column_invisible="1"/>
</list> </tree>
</field> </field>
<label for="amount_substract" string="Total Deductions" <label for="amount_substract" string="Total Deductions"

View File

@ -28,17 +28,12 @@ class PaymentAmountFixWizard(models.TransientModel):
payments_to_fix = [] payments_to_fix = []
for payment in payments: for payment in payments:
if payment.move_id: if payment.move_id:
liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines() counterpart_lines = payment.move_id.line_ids.filtered(
non_liquidity_lines = counterpart_lines + writeoff_lines lambda l: l.debit > 0 and l.account_id.account_type in ('liability_payable', 'expense')
)
if payment.payment_type == 'outbound': if counterpart_lines:
gross_lines = non_liquidity_lines.filtered(lambda l: l.debit > 0) correct_amount = counterpart_lines[0].debit
else: if abs(payment.amount - correct_amount) > 0.01:
gross_lines = non_liquidity_lines.filtered(lambda l: l.credit > 0)
if gross_lines:
correct_amount = sum(abs(l.amount_currency) for l in gross_lines)
if abs(payment.amount - correct_amount) > 0.001:
payments_to_fix.append(payment.id) payments_to_fix.append(payment.id)
res['payment_ids'] = [(6, 0, payments_to_fix)] res['payment_ids'] = [(6, 0, payments_to_fix)]
@ -50,17 +45,13 @@ class PaymentAmountFixWizard(models.TransientModel):
for payment in self.payment_ids: for payment in self.payment_ids:
if payment.move_id: if payment.move_id:
liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines() counterpart_lines = payment.move_id.line_ids.filtered(
non_liquidity_lines = counterpart_lines + writeoff_lines lambda l: l.debit > 0 and l.account_id.account_type in ('liability_payable', 'expense')
)
if payment.payment_type == 'outbound': if counterpart_lines:
gross_lines = non_liquidity_lines.filtered(lambda l: l.debit > 0) correct_amount = counterpart_lines[0].debit
else: if abs(payment.amount - correct_amount) > 0.01:
gross_lines = non_liquidity_lines.filtered(lambda l: l.credit > 0)
if gross_lines:
correct_amount = sum(abs(l.amount_currency) for l in gross_lines)
if abs(payment.amount - correct_amount) > 0.001:
# Fix using SQL to avoid sync issues # Fix using SQL to avoid sync issues
payment.env.cr.execute( payment.env.cr.execute(
"UPDATE account_payment SET amount = %s WHERE id = %s", "UPDATE account_payment SET amount = %s WHERE id = %s",

View File

@ -12,14 +12,14 @@
</p> </p>
<group> <group>
<field name="payment_ids" nolabel="1"> <field name="payment_ids" nolabel="1">
<list> <tree>
<field name="name"/> <field name="name"/>
<field name="partner_id"/> <field name="partner_id"/>
<field name="amount"/> <field name="amount"/>
<field name="amount_substract"/> <field name="amount_substract"/>
<field name="final_payment_amount"/> <field name="final_payment_amount"/>
<field name="date"/> <field name="date"/>
</list> </tree>
</field> </field>
</group> </group>
<footer> <footer>