From eda7a6948f7d6be6431b80ccf8968a91aba53896 Mon Sep 17 00:00:00 2001 From: Mazen Abdo Date: Wed, 8 Oct 2025 13:18:49 +0300 Subject: [PATCH] fix --- .../purchase_budget_fix/models/model.py | 57 +++++++++++-------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/odex25_purchase/purchase_budget_fix/models/model.py b/odex25_purchase/purchase_budget_fix/models/model.py index 0fe7b25f9..f928563d2 100644 --- a/odex25_purchase/purchase_budget_fix/models/model.py +++ b/odex25_purchase/purchase_budget_fix/models/model.py @@ -70,37 +70,46 @@ class PurchaseOrder(models.Model): "- Product: %s") % (account_id.name, analytic_account.name, rec.product_id.name) ) + final_budget_line = False + remaining_amount = rec.price_subtotal - if len(valid_budget_positions) > 1: - raise ValidationError( - _("Multiple budget positions found for expense account %s with analytic account %s:\n%s\n\n" - "Please contact your administrator to fix the budget configuration.") - % (account_id.name, analytic_account.name, ', '.join(valid_budget_positions.mapped('name'))) + for budget_position in valid_budget_positions: + candidate_lines = budget_lines.filtered( + lambda x: x.general_budget_id.id == budget_position.id ) + for line in candidate_lines: + line_remain = abs(line.remain) + if line_remain <= 0: + continue - final_budget_line = budget_lines.filtered( - lambda x: x.general_budget_id.id == valid_budget_positions.id - ) + used_amount = min(line_remain, remaining_amount) - if not final_budget_line: - raise ValidationError(_("Budget line not found for the configuration")) + confirmation_lines.append((0, 0, { + 'amount': used_amount, + 'analytic_account_id': analytic_account.id, + 'description': f"{rec.product_id.name} ({budget_position.name})", + 'budget_line_id': line.id, + 'remain': line_remain, + 'new_balance': line_remain - used_amount, + 'account_id': account_id.id + })) + remaining_amount -= used_amount + amount += used_amount + final_budget_line = line - final_budget_line = final_budget_line[0] + if remaining_amount <= 0: + break + if remaining_amount <= 0: + break - self.budget_id = final_budget_line.crossovered_budget_id.id - remain = abs(final_budget_line.remain) - amount += rec.price_subtotal - new_balance = remain - amount + if remaining_amount > 0: + raise ValidationError(_( + "Not enough budget available for analytic account '%s' (Expense account: %s).\n" + "Remaining unallocated amount: %.2f" + ) % (analytic_account.name, account_id.name, remaining_amount)) - confirmation_lines.append((0, 0, { - 'amount': rec.price_subtotal, - 'analytic_account_id': analytic_account.id, - 'description': rec.product_id.name, - 'budget_line_id': final_budget_line.id, - 'remain': remain, - 'new_balance': new_balance, - 'account_id': account_id.id - })) + if final_budget_line: + self.budget_id = final_budget_line.crossovered_budget_id.id data = { 'name': self.name,