fix final invoice and certificatre
This commit is contained in:
		
							parent
							
								
									0cfa86bde3
								
							
						
					
					
						commit
						dd37ac3720
					
				
					 11 changed files with 120 additions and 66 deletions
				
			
		| 
						 | 
				
			
			@ -228,18 +228,6 @@ class Invoice(NameSlugModel):
 | 
			
		|||
        default=0, 
 | 
			
		||||
        verbose_name="مبلغ نهایی"
 | 
			
		||||
    )
 | 
			
		||||
    paid_amount = models.DecimalField(
 | 
			
		||||
        max_digits=15, 
 | 
			
		||||
        decimal_places=2, 
 | 
			
		||||
        default=0, 
 | 
			
		||||
        verbose_name="مبلغ پرداخت شده"
 | 
			
		||||
    )
 | 
			
		||||
    remaining_amount = models.DecimalField(
 | 
			
		||||
        max_digits=15, 
 | 
			
		||||
        decimal_places=2, 
 | 
			
		||||
        default=0, 
 | 
			
		||||
        verbose_name="مبلغ باقیمانده"
 | 
			
		||||
    )
 | 
			
		||||
    due_date = models.DateField(verbose_name="تاریخ سررسید")
 | 
			
		||||
    notes = models.TextField(verbose_name="یادداشتها", blank=True)
 | 
			
		||||
    created_by = models.ForeignKey(
 | 
			
		||||
| 
						 | 
				
			
			@ -278,22 +266,31 @@ class Invoice(NameSlugModel):
 | 
			
		|||
        vat_amount = base_amount * vat_rate
 | 
			
		||||
        self.final_amount = base_amount + vat_amount
 | 
			
		||||
        
 | 
			
		||||
        # خالص مانده به نفع شرکت (مثبت) یا به نفع مشتری (منفی)
 | 
			
		||||
        net_due = self.final_amount - self.paid_amount
 | 
			
		||||
        self.remaining_amount = net_due
 | 
			
		||||
 | 
			
		||||
        # وضعیت بر اساس مانده خالص
 | 
			
		||||
        # وضعیت بر اساس مانده خالص (استفاده از تابعها)
 | 
			
		||||
        paid = self.get_paid_amount()
 | 
			
		||||
        net_due = self.final_amount - paid
 | 
			
		||||
        
 | 
			
		||||
        if net_due == 0:
 | 
			
		||||
            self.status = 'paid'
 | 
			
		||||
        elif net_due > 0:
 | 
			
		||||
            # مشتری هنوز باید پرداخت کند
 | 
			
		||||
            self.status = 'partially_paid' if self.paid_amount > 0 else 'sent'
 | 
			
		||||
            self.status = 'partially_paid' if paid > 0 else 'sent'
 | 
			
		||||
        else:
 | 
			
		||||
            # شرکت باید به مشتری پرداخت کند
 | 
			
		||||
            self.status = 'partially_paid'
 | 
			
		||||
        
 | 
			
		||||
        self.save()
 | 
			
		||||
 | 
			
		||||
    def get_paid_amount(self):
 | 
			
		||||
        """مبلغ پرداخت شده بر اساس پرداختها (مثل Quote)"""
 | 
			
		||||
        return sum((p.amount if p.direction == 'in' else -p.amount) for p in self.payments.filter(is_deleted=False).all())
 | 
			
		||||
 | 
			
		||||
    def get_remaining_amount(self):
 | 
			
		||||
        """مبلغ باقیمانده بر اساس پرداختها (مثل Quote)"""
 | 
			
		||||
        paid = self.get_paid_amount()
 | 
			
		||||
        remaining = self.final_amount - paid
 | 
			
		||||
        return remaining
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_status_display_with_color(self):
 | 
			
		||||
        """نمایش وضعیت با رنگ"""
 | 
			
		||||
| 
						 | 
				
			
			@ -373,17 +370,13 @@ class Payment(BaseModel):
 | 
			
		|||
    def save(self, *args, **kwargs):
 | 
			
		||||
        """بروزرسانی مبالغ فاکتور"""
 | 
			
		||||
        super().save(*args, **kwargs)
 | 
			
		||||
        # بروزرسانی مبلغ پرداخت شده فاکتور
 | 
			
		||||
        total_paid = sum((p.amount if p.direction == 'in' else -p.amount) for p in self.invoice.payments.filter(is_deleted=False).all())
 | 
			
		||||
        self.invoice.paid_amount = total_paid
 | 
			
		||||
        # فقط مجدداً calculate_totals را صدا کن (مثل Quote)
 | 
			
		||||
        self.invoice.calculate_totals()
 | 
			
		||||
 | 
			
		||||
    def delete(self, using=None, keep_parents=False):
 | 
			
		||||
        """حذف نرم و بروزرسانی مبالغ فاکتور پس از حذف"""
 | 
			
		||||
        result = super().delete(using=using, keep_parents=keep_parents)
 | 
			
		||||
        try:
 | 
			
		||||
            total_paid = sum((p.amount if p.direction == 'in' else -p.amount) for p in self.invoice.payments.filter(is_deleted=False).all())
 | 
			
		||||
            self.invoice.paid_amount = total_paid
 | 
			
		||||
            self.invoice.calculate_totals()
 | 
			
		||||
        except Exception:
 | 
			
		||||
            pass
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue