fix some bugs in reconcile process
This commit is contained in:
parent
842eb4ca4a
commit
cca358b590
@ -14,6 +14,8 @@ This Odoo 17 module enhances the bank reconciliation process by providing a stre
|
|||||||
- Wizard-based interface for selecting journal entries to reconcile with
|
- Wizard-based interface for selecting journal entries to reconcile with
|
||||||
- Individual line processing for precise control
|
- Individual line processing for precise control
|
||||||
- Automatic journal entry creation for reconciliation transactions
|
- Automatic journal entry creation for reconciliation transactions
|
||||||
|
- Intelligent automatic reconciliation of journal entry lines with created entries
|
||||||
|
- Proper account matching for accurate reconciliation
|
||||||
|
|
||||||
### 3. Smart Filtering
|
### 3. Smart Filtering
|
||||||
- "Hide Reconciled" filter to focus on unreconciled lines
|
- "Hide Reconciled" filter to focus on unreconciled lines
|
||||||
@ -73,6 +75,8 @@ No additional configuration is required after installation. The module works wit
|
|||||||
1. **Lines not hiding when filter applied**: Ensure the `is_reconciled` computed field is properly stored in the database
|
1. **Lines not hiding when filter applied**: Ensure the `is_reconciled` computed field is properly stored in the database
|
||||||
2. **Reconciliation errors**: Verify that journal entries have proper account mappings
|
2. **Reconciliation errors**: Verify that journal entries have proper account mappings
|
||||||
3. **Performance issues**: For large datasets, use the filter to reduce the number of displayed lines
|
3. **Performance issues**: For large datasets, use the filter to reduce the number of displayed lines
|
||||||
|
4. **Automatic reconciliation not working**: Check that journal entry lines have matching accounts and sufficient balances for reconciliation
|
||||||
|
5. **Reconciliation journal created but not properly linked**: Verify that the reconciliation process is correctly matching accounts between the bank line and journal entry line
|
||||||
|
|
||||||
### Support
|
### Support
|
||||||
For issues or feature requests, please contact your Odoo administrator or module developer.
|
For issues or feature requests, please contact your Odoo administrator or module developer.
|
||||||
|
|||||||
Binary file not shown.
@ -5,14 +5,6 @@ from odoo.exceptions import UserError
|
|||||||
class AccountBankStatementLine(models.Model):
|
class AccountBankStatementLine(models.Model):
|
||||||
_inherit = 'account.bank.statement.line'
|
_inherit = 'account.bank.statement.line'
|
||||||
|
|
||||||
is_reconciled = fields.Boolean(string='Is Reconciled', compute='_compute_is_reconciled', store=True)
|
|
||||||
|
|
||||||
@api.depends('move_id')
|
|
||||||
def _compute_is_reconciled(self):
|
|
||||||
"""Compute whether the bank line has been reconciled"""
|
|
||||||
for line in self:
|
|
||||||
line.is_reconciled = bool(line.move_id and 'Reconciliation:' in line.move_id.name)
|
|
||||||
|
|
||||||
def action_reconcile_selected_lines(self):
|
def action_reconcile_selected_lines(self):
|
||||||
"""Open the reconciliation wizard for selected lines"""
|
"""Open the reconciliation wizard for selected lines"""
|
||||||
# Get the selected records from the context
|
# Get the selected records from the context
|
||||||
@ -26,7 +18,7 @@ class AccountBankStatementLine(models.Model):
|
|||||||
selected_lines = self
|
selected_lines = self
|
||||||
|
|
||||||
# Filter out already reconciled lines by checking if they have a move_id with reconciliation in the name
|
# Filter out already reconciled lines by checking if they have a move_id with reconciliation in the name
|
||||||
unreconciled_lines = selected_lines.filtered(lambda line: not (line.move_id and 'Reconciliation:' in line.move_id.name))
|
unreconciled_lines = selected_lines.filtered(lambda line: not line.move_id)
|
||||||
|
|
||||||
if not unreconciled_lines:
|
if not unreconciled_lines:
|
||||||
raise UserError("All selected bank statement lines have already been reconciled.")
|
raise UserError("All selected bank statement lines have already been reconciled.")
|
||||||
|
|||||||
@ -37,14 +37,14 @@
|
|||||||
<field name="name">account.bank.statement.line.tree</field>
|
<field name="name">account.bank.statement.line.tree</field>
|
||||||
<field name="model">account.bank.statement.line</field>
|
<field name="model">account.bank.statement.line</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree string="Bank Statement Lines" create="0" delete="0" decoration-danger="amount < 0">
|
<tree string="Bank Statement Lines" create="0" delete="0" decoration-danger="amount < 0" decoration-muted="move_id and 'Reconciliation:' in move_id.name">
|
||||||
<field name="date"/>
|
<field name="date"/>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="partner_id"/>
|
<field name="partner_id"/>
|
||||||
<field name="amount"/>
|
<field name="amount"/>
|
||||||
<field name="journal_id"/>
|
<field name="journal_id"/>
|
||||||
<field name="statement_id"/>
|
<field name="statement_id"/>
|
||||||
<field name="move_id" invisible="1"/>
|
<field name="move_id"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
@ -60,6 +60,7 @@
|
|||||||
</header>
|
</header>
|
||||||
<sheet>
|
<sheet>
|
||||||
<group>
|
<group>
|
||||||
|
<group>
|
||||||
<field name="date"/>
|
<field name="date"/>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="ref"/>
|
<field name="ref"/>
|
||||||
@ -69,6 +70,7 @@
|
|||||||
<field name="partner_id"/>
|
<field name="partner_id"/>
|
||||||
<field name="journal_id" readonly="1"/>
|
<field name="journal_id" readonly="1"/>
|
||||||
</group>
|
</group>
|
||||||
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="statement_id"/>
|
<field name="statement_id"/>
|
||||||
<field name="move_id"/>
|
<field name="move_id"/>
|
||||||
@ -91,7 +93,7 @@
|
|||||||
<field name="date"/>
|
<field name="date"/>
|
||||||
<filter name="positive_amount" string="Income" domain="[('amount', '>', 0)]"/>
|
<filter name="positive_amount" string="Income" domain="[('amount', '>', 0)]"/>
|
||||||
<filter name="negative_amount" string="Expense" domain="[('amount', '<', 0)]"/>
|
<filter name="negative_amount" string="Expense" domain="[('amount', '<', 0)]"/>
|
||||||
<filter name="hide_reconciled" string="Hide Reconciled" domain="[('is_reconciled', '=', False)]" help="Hide lines that have been reconciled"/>
|
<filter name="hide_reconciled" string="Hide Reconciled" domain="[('move_id', '=', False)]" help="Hide lines that have been reconciled"/>
|
||||||
<filter name="show_all" string="Show All" domain="[]" help="Show all lines including reconciled"/>
|
<filter name="show_all" string="Show All" domain="[]" help="Show all lines including reconciled"/>
|
||||||
<group expand="0" string="Group By">
|
<group expand="0" string="Group By">
|
||||||
<filter name="group_by_journal" string="Journal" context="{'group_by': 'journal_id'}"/>
|
<filter name="group_by_journal" string="Journal" context="{'group_by': 'journal_id'}"/>
|
||||||
|
|||||||
Binary file not shown.
@ -40,13 +40,6 @@ class BankReconcileWizard(models.TransientModel):
|
|||||||
if not self.journal_entry_line_id:
|
if not self.journal_entry_line_id:
|
||||||
raise UserError("Please select a journal entry line to reconcile.")
|
raise UserError("Please select a journal entry line to reconcile.")
|
||||||
|
|
||||||
# Validate that the total of individual line amounts doesn't exceed the journal entry line amount
|
|
||||||
journal_line_amount = self.journal_entry_line_id.debit or self.journal_entry_line_id.credit
|
|
||||||
if len(self.bank_line_ids) > 1:
|
|
||||||
total_bank_amount = sum(abs(line.amount) for line in self.bank_line_ids)
|
|
||||||
if total_bank_amount > journal_line_amount:
|
|
||||||
raise UserError(f"Total bank line amounts ({total_bank_amount}) cannot exceed the journal entry line amount ({journal_line_amount}).")
|
|
||||||
|
|
||||||
# Process each selected bank line individually
|
# Process each selected bank line individually
|
||||||
for bank_line in self.bank_line_ids:
|
for bank_line in self.bank_line_ids:
|
||||||
self._reconcile_single_line(bank_line, self.journal_entry_line_id)
|
self._reconcile_single_line(bank_line, self.journal_entry_line_id)
|
||||||
@ -56,76 +49,40 @@ class BankReconcileWizard(models.TransientModel):
|
|||||||
|
|
||||||
def _reconcile_single_line(self, bank_line, journal_entry_line):
|
def _reconcile_single_line(self, bank_line, journal_entry_line):
|
||||||
"""Reconcile a single bank line with a journal entry line"""
|
"""Reconcile a single bank line with a journal entry line"""
|
||||||
# Get the account from the journal entry line that will be on the opposite side
|
|
||||||
reconcile_account = journal_entry_line.account_id
|
|
||||||
|
|
||||||
# Use the individual bank line amount for each line
|
# Create a journal entry to balance the transaction
|
||||||
reconcile_amount = abs(bank_line.amount)
|
# This mimics the standard Odoo reconciliation widget behavior.
|
||||||
|
move = self.env['account.move'].create({
|
||||||
# According to requirement #5: if the bank line is debit,
|
|
||||||
# then the new journal entry after reconcile will have that bank account in debit
|
|
||||||
bank_account = bank_line.journal_id.default_account_id
|
|
||||||
bank_line_amount = bank_line.amount
|
|
||||||
|
|
||||||
# Determine if the bank line is debit (positive) or credit (negative)
|
|
||||||
if bank_line_amount >= 0: # Bank line is debit (money coming in)
|
|
||||||
# Bank account should be debited (requirement #5)
|
|
||||||
debit_account = bank_account
|
|
||||||
# The account from the selected journal entry line goes to credit (requirement #6)
|
|
||||||
credit_account = reconcile_account
|
|
||||||
else: # Bank line is credit (money going out)
|
|
||||||
# Bank account should be credited
|
|
||||||
credit_account = bank_account
|
|
||||||
# The account from the selected journal entry line goes to debit
|
|
||||||
debit_account = reconcile_account
|
|
||||||
|
|
||||||
# Set the amounts - make sure they are balanced
|
|
||||||
debit_amount = reconcile_amount
|
|
||||||
credit_amount = reconcile_amount
|
|
||||||
|
|
||||||
# Create a new journal entry for reconciliation with lines
|
|
||||||
reconciling_move = self.env['account.move'].create({
|
|
||||||
'journal_id': bank_line.journal_id.id,
|
'journal_id': bank_line.journal_id.id,
|
||||||
'date': bank_line.date,
|
'date': bank_line.date,
|
||||||
'ref': f'Reconciliation: {bank_line.name or "Bank Line"}',
|
'ref': f'Reconciliation: {bank_line.name or "Bank Line"}',
|
||||||
'move_type': 'entry',
|
'move_type': 'entry',
|
||||||
'line_ids': [
|
'line_ids': [
|
||||||
(0, 0, {
|
(0, 0, {
|
||||||
'account_id': debit_account.id,
|
'account_id': bank_line.journal_id.default_account_id.id,
|
||||||
'debit': debit_amount,
|
'debit': bank_line.amount if bank_line.amount > 0 else 0,
|
||||||
'credit': 0,
|
'credit': -bank_line.amount if bank_line.amount < 0 else 0,
|
||||||
'name': f'Bank Reconciliation: {bank_line.name or ""}',
|
'name': f'Bank Reconciliation: {bank_line.name or ""}',
|
||||||
}),
|
}),
|
||||||
(0, 0, {
|
(0, 0, {
|
||||||
'account_id': credit_account.id,
|
'account_id': journal_entry_line.account_id.id,
|
||||||
'debit': 0,
|
'debit': -bank_line.amount if bank_line.amount < 0 else 0,
|
||||||
'credit': credit_amount,
|
'credit': bank_line.amount if bank_line.amount > 0 else 0,
|
||||||
'name': f'Bank Reconciliation: {bank_line.name or ""}',
|
'name': f'Bank Reconciliation: {journal_entry_line.name or ""}',
|
||||||
})
|
}),
|
||||||
]
|
],
|
||||||
|
})
|
||||||
|
move.action_post()
|
||||||
|
|
||||||
|
# Link the bank statement line to the new journal entry
|
||||||
|
bank_line.write({
|
||||||
|
'move_id': move.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
# Post the reconciling journal entry
|
# Find the corresponding line in the new move and reconcile with the journal entry line
|
||||||
reconciling_move.action_post()
|
move_line = move.line_ids.filtered(lambda l: l.account_id.id == journal_entry_line.account_id.id)
|
||||||
|
if move_line:
|
||||||
# Link the bank line to the reconciling move
|
|
||||||
bank_line.sudo().write({
|
|
||||||
'move_id': reconciling_move.id,
|
|
||||||
})
|
|
||||||
|
|
||||||
# Mark the bank line as reconciled in a separate operation
|
|
||||||
bank_line.sudo().write({
|
|
||||||
'is_reconciled': True,
|
|
||||||
})
|
|
||||||
|
|
||||||
# Try to reconcile the selected journal entry line with the corresponding line in the reconciling move
|
|
||||||
# Find the line in the reconciling move that has the same account as the journal entry line
|
|
||||||
reconciling_line = reconciling_move.line_ids.filtered(lambda l: l.account_id.id == reconcile_account.id and l.credit > 0)
|
|
||||||
|
|
||||||
# Try to reconcile the journal entry line with our reconciling line
|
|
||||||
if reconciling_line:
|
|
||||||
try:
|
try:
|
||||||
(journal_entry_line + reconciling_line).reconcile()
|
(journal_entry_line + move_line).reconcile()
|
||||||
except:
|
except:
|
||||||
# If reconcile fails, we'll just link the moves
|
pass
|
||||||
pass
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user