fix auto complete final invoice

This commit is contained in:
aminhashemi92 2025-10-09 14:37:59 +03:30
parent 23f50aacd4
commit 6367d34f0c
7 changed files with 160 additions and 39 deletions

View file

@ -564,6 +564,7 @@ def add_quote_payment(request, instance_id, step_id):
amount=amount_dec,
payment_date=payment_date,
payment_method=payment_method,
payment_stage='quote',
reference_number=reference_number,
receipt_image=receipt_image,
notes=notes,
@ -1049,10 +1050,56 @@ def final_settlement_step(request, instance_id, step_id):
# Ensure step instance exists
step_instance, _ = StepInstance.objects.get_or_create(process_instance=instance, step=step, defaults={'status': 'in_progress'})
# Check if there are changes that require approval
# (used for both auto-complete and UI display)
has_special_charges = False
has_installation_changes = False
has_final_settlement_payments = False
try:
has_special_charges = invoice.items.filter(item__is_special=True, is_deleted=False).exists()
except Exception:
pass
try:
from installations.models import InstallationAssignment
assignment = InstallationAssignment.objects.filter(process_instance=instance).first()
if assignment:
reports = assignment.reports.all()
for report in reports:
if report.item_changes.filter(is_deleted=False).exists():
has_installation_changes = True
break
except Exception:
pass
# Check if there are payments added during final settlement step
# using the payment_stage field
try:
final_settlement_payments = invoice.payments.filter(
is_deleted=False,
payment_stage='final_settlement'
)
if final_settlement_payments.exists():
has_final_settlement_payments = True
except Exception:
pass
# Auto-complete step when invoice is fully settled (no approvals needed)
# BUT only if no special charges were added in final_invoice step
# AND no installation item changes were made
# AND no payments were added in this final settlement step
# (meaning the remaining amount is from the original quote_payment step)
try:
invoice.calculate_totals()
if invoice.get_remaining_amount() == 0:
remaining = invoice.get_remaining_amount()
# Only auto-complete if:
# 1. Remaining amount is zero
# 2. No special charges were added (meaning this is settling the original quote)
# 3. No installation item changes (meaning no items added/removed in installation step)
# 4. No payments added in final settlement step (meaning no new receipts need approval)
if remaining == 0 and not has_special_charges and not has_installation_changes and not has_final_settlement_payments:
if step_instance.status != 'completed':
step_instance.status = 'completed'
step_instance.completed_at = timezone.now()
@ -1199,6 +1246,21 @@ def final_settlement_step(request, instance_id, step_id):
except Exception:
is_broker = False
# Determine if approval is needed
# Approval is needed if:
# 1. Remaining amount is not zero, OR
# 2. Special charges were added (meaning new balance was created in final_invoice step), OR
# 3. Installation item changes were made (meaning items were added/removed in installation step), OR
# 4. Payments were added in final settlement step (new receipts need approval)
needs_approval = True
try:
remaining = invoice.get_remaining_amount()
# No approval needed only if: remaining is zero AND no special charges AND no installation changes AND no final settlement payments
if remaining == 0 and not has_special_charges and not has_installation_changes and not has_final_settlement_payments:
needs_approval = False
except Exception:
needs_approval = True
return render(request, 'invoices/final_settlement_step.html', {
'instance': instance,
'step': step,
@ -1211,6 +1273,7 @@ def final_settlement_step(request, instance_id, step_id):
'can_approve_reject': can_approve_reject,
'is_broker': is_broker,
'current_user_has_decided': current_user_has_decided,
'needs_approval': needs_approval,
'is_manager': bool(getattr(getattr(request.user, 'profile', None), 'roles', Role.objects.none()).filter(slug=UserRoles.MANAGER.value).exists()) if getattr(request.user, 'profile', None) else False,
})
@ -1283,6 +1346,7 @@ def add_final_payment(request, instance_id, step_id):
amount=amount_dec,
payment_date=payment_date,
payment_method=payment_method,
payment_stage='final_settlement',
reference_number=reference_number,
direction='in' if direction != 'out' else 'out',
receipt_image=receipt_image,