fix auto complete final invoice
This commit is contained in:
		
							parent
							
								
									23f50aacd4
								
							
						
					
					
						commit
						6367d34f0c
					
				
					 7 changed files with 160 additions and 39 deletions
				
			
		| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue