diff --git a/l10n_th_account_tax/models/account_withholding_move.py b/l10n_th_account_tax/models/account_withholding_move.py index f3153a1e3..c3e50d737 100644 --- a/l10n_th_account_tax/models/account_withholding_move.py +++ b/l10n_th_account_tax/models/account_withholding_move.py @@ -86,7 +86,7 @@ def _compute_move_data(self): rec.date = rec.move_id and rec.move_id.date or False rec.calendar_year = rec.date and rec.date.strftime("%Y") rec.payment_id = rec.move_id.payment_id - + @api.onchange("wht_cert_income_type") def _onchange_wht_cert_income_type(self): if self.wht_cert_income_type: diff --git a/l10n_th_account_tax/wizard/account_payment_register.py b/l10n_th_account_tax/wizard/account_payment_register.py index 8bf892b0c..2790d36d9 100644 --- a/l10n_th_account_tax/wizard/account_payment_register.py +++ b/l10n_th_account_tax/wizard/account_payment_register.py @@ -94,7 +94,9 @@ def _compute_amount(self): """ This function is the first entry point, to calculate withholding amount """ res = super()._compute_amount() # Get the sum withholding tax amount from invoice line - if self.env.context.get("active_model") == "account.move": + skip_wht_deduct = self.env.context.get("skip_wht_deduct") + active_model = self.env.context.get("active_model") + if not skip_wht_deduct and active_model == "account.move": active_ids = self.env.context.get("active_ids", []) invoices = self.env["account.move"].browse(active_ids) wht_move_lines = invoices.mapped("line_ids").filtered("wht_tax_id") diff --git a/l10n_th_account_tax_expense/models/account_move.py b/l10n_th_account_tax_expense/models/account_move.py index 76c5bfd61..536e2460f 100644 --- a/l10n_th_account_tax_expense/models/account_move.py +++ b/l10n_th_account_tax_expense/models/account_move.py @@ -13,34 +13,47 @@ def _post(self, soft=True): return res def _reconcile_withholding_tax_entry(self): - """ Re-Reconciliation, ensure the wht_move is taken into account """ + """ Re-Reconciliation, for case wht_move that clear advance only """ for move in self: clearing = self.env["hr.expense.sheet"].search( [("wht_move_id", "=", move.id)] ) if not clearing: continue + advance = clearing.advance_sheet_id clearing.ensure_one() - move_lines = clearing.account_move_id.line_ids - accounts = move_lines.mapped("account_id").filtered("reconcile") + # Find Advance account (from advance sheet) + av_account = advance.expense_line_ids.mapped("account_id") + av_account.ensure_one() # Find all related clearings and advance moves to unreconcile first - all_clearings = clearing.advance_sheet_id.clearing_sheet_ids - r_lines = all_clearings.mapped("account_move_id.line_ids").filtered( - lambda l: l.account_id.id in accounts.ids + if move.line_ids.filtered(lambda l: l.account_id == av_account): + all_clearings = clearing.advance_sheet_id.clearing_sheet_ids + r_lines = all_clearings.mapped("account_move_id.line_ids").filtered( + lambda l: l.account_id == av_account + ) + md_lines = r_lines.mapped("matched_debit_ids.debit_move_id") + mc_lines = r_lines.mapped("matched_credit_ids.credit_move_id") + # Removes reconcile + (r_lines + md_lines + mc_lines).remove_move_reconcile() + # Re-reconcile again this time with the wht_tax JV, account by account + wht_lines = all_clearings.mapped("wht_move_id.line_ids").filtered( + lambda l: l.account_id == av_account + ) + to_reconciles = (r_lines + wht_lines + md_lines + mc_lines).filtered( + lambda l: not l.reconciled + ) + to_reconciles.filtered(lambda l: l.account_id == av_account).reconcile() + # Then, in case there are left over amount to other AP, do reconcile. + ap_accounts = move.line_ids.mapped("account_id").filtered( + lambda l: l.reconcile and l != av_account ) - md_lines = r_lines.mapped("matched_debit_ids.debit_move_id") - mc_lines = r_lines.mapped("matched_credit_ids.credit_move_id") - # Removes reconcile - (r_lines + md_lines + mc_lines).remove_move_reconcile() - # Re-reconcile again this time with the wht_tax JV, account by account - wht_lines = all_clearings.mapped("wht_move_id.line_ids").filtered( - lambda l: l.account_id.id in accounts.ids - ) - to_reconciles = (r_lines + wht_lines + md_lines + mc_lines).filtered( - lambda l: not l.reconciled - ) - for account in accounts: - to_reconciles.filtered(lambda l: l.account_id == account).reconcile() + if not ap_accounts: + continue + for account in ap_accounts: + ml_lines = ( + clearing.account_move_id.line_ids + clearing.wht_move_id.line_ids + ) + ml_lines.filtered(lambda l: l.account_id == account).reconcile() def _assign_tax_invoice(self): """ Use Bill Reference and Date from Expense Line as Tax Invoice """ diff --git a/l10n_th_account_tax_expense/models/hr_expense_sheet.py b/l10n_th_account_tax_expense/models/hr_expense_sheet.py index d68ca20e9..3c9cf033c 100644 --- a/l10n_th_account_tax_expense/models/hr_expense_sheet.py +++ b/l10n_th_account_tax_expense/models/hr_expense_sheet.py @@ -50,7 +50,7 @@ def _prepare_withholding_tax_entry(self): self.ensure_one() # Prepare Dr. Advance, Cr. WHT lines line_vals_list = [] - move_lines = self.account_move_id.mapped("line_ids") + move_lines = self.account_move_id.line_ids # Cr. WHT Lines wht_move_lines = move_lines.filtered("wht_tax_id") currency = self.env.company.currency_id @@ -71,23 +71,31 @@ def _prepare_withholding_tax_entry(self): "tax_base_amount": deduction["wht_amount_base"], } ) - accounts = move_lines.mapped("account_id").filtered("reconcile") # Dr. Reconcilable Account (i.e., AP, Advance) + # amount goes to AP first, then the rest go to Advance + av_account = self.advance_sheet_id.expense_line_ids.mapped("account_id") + ap_accounts = move_lines.mapped("account_id").filtered( + lambda l: l.reconcile and l != av_account + ) + accounts = ap_accounts + av_account partner_id = self.employee_id.sudo().address_home_id.commercial_partner_id.id for account in accounts: if amount_deduct: + account_ml = move_lines.filtered(lambda l: l.account_id == account) + credit = sum(account_ml.mapped("credit")) + amount = credit if amount_deduct > credit else amount_deduct line_vals_list.append( { "name": account.name, - "amount_currency": amount_deduct, + "amount_currency": amount, "currency_id": currency.id, - "debit": amount_deduct, # Sum of all credit + "debit": amount, "credit": 0.0, "partner_id": partner_id, "account_id": account.id, } ) - amount_deduct = 0.0 + amount_deduct -= amount # Create JV move_vals = { "move_type": "entry", @@ -95,3 +103,10 @@ def _prepare_withholding_tax_entry(self): "line_ids": [(0, 0, line_vals) for line_vals in line_vals_list], } return move_vals + + def action_register_payment(self): + """ For Clearing, never deduct WHT auto """ + action = super().action_register_payment() + if self.filtered("advance_sheet_id"): + action["context"].update({"skip_wht_deduct": True}) + return action