from django.db import models from osinacore.models import * import requests # Create your models here. class Item(models.Model): TYPE = ( ('Product', 'Product'), ('Service', 'Service'), ) type = models.CharField(max_length=200, choices=TYPE, null=True) title = models.CharField(max_length=200) description = models.TextField(blank=True) customer = models.ForeignKey(CustomerProfile, null=True, blank=True, on_delete=models.CASCADE) item_type = models.ForeignKey(ProjectType, on_delete=models.CASCADE, null=True, blank=True) amount = models.FloatField(null=True) recurring = models.BooleanField(default=False) photo = models.ImageField(null=True, blank=True) def __str__(self): return self.title class RecurringCycle(models.Model): item = models.ForeignKey(Item, on_delete=models.CASCADE, null=True) months = models.IntegerField() cycle_price = models.FloatField(null=True) def __str__(self): if self.months > 1: return f"{self.months} months - {self.item}" else: return f"{self.months} month - {self.item}" class Order(models.Model): customer = models.ForeignKey(CustomerProfile, on_delete=models.CASCADE) business = models.ForeignKey(Business, on_delete=models.SET_NULL, null=True, blank=True) order_id = models.CharField(max_length=100, null=True, blank=True) date = models.DateField(null=True, blank=True) @property def get_cart_total(self): orderitems = self.orderitem_set.all() total = sum([item.get_total for item in orderitems]) return total @property def get_paid_amount(self): payments = self.orderpayment_set.filter(date_paid__isnull=False) total_paid = sum([payment.amount for payment in payments]) return total_paid @property def remaining_balance(self): return self.get_cart_total - self.get_paid_amount @property def get_purchased_date(self): first_orderitem = self.orderitem_set.first() if first_orderitem: return first_orderitem.purchased_at return None def save(self, *args, **kwargs): if not self.order_id: current_year_last_two_digits = timezone.now().strftime('%y') last_order = Order.objects.filter(order_id__startswith=f'O{current_year_last_two_digits}').order_by('-order_id').first() if last_order: last_order_number = int(last_order.order_id[4:]) new_order_number = last_order_number + 1 else: new_order_number = 0 new_order_number_str = str(new_order_number).zfill(4) self.order_id = f'O{current_year_last_two_digits}{new_order_number_str}' super(Order, self).save(*args, **kwargs) class OrderStatus(models.Model): STATUS = ( ('Completed', 'Completed'), ('Pending', 'Pending'), ('Failed', 'Failed'), ('Cancelled', 'Cancelled'), ('In Progress', 'In Progress') ) order = models.ForeignKey(Order, on_delete=models.CASCADE) status = models.CharField(max_length=200, choices=STATUS, default='Pending') date = models.DateTimeField() class OrderItem(models.Model): order = models.ForeignKey(Order, on_delete=models.CASCADE) item = models.ForeignKey(Item, on_delete=models.CASCADE) active = models.BooleanField(null=True, blank=True) purchased_at = models.DateField(null=True, blank=True) end_at = models.DateField(blank=True, null=True) terminated_at = models.DateField(blank=True, null=True) recurring_cycle = models.ForeignKey(RecurringCycle, on_delete=models.SET_NULL, null=True, blank=True) @property def get_total(self): if self.recurring_cycle: total = self.recurring_cycle.cycle_price else: total = self.item.amount total = round(total, 2) return total class Invoice(models.Model): invoice_number = models.CharField(max_length=100, null=True, blank=True) order = models.OneToOneField(Order, on_delete=models.SET_NULL, null=True) date_created = models.DateField() pdf = models.FileField(upload_to='generated_invoices', null=True, blank=True) def __str__(self): return self.invoice_number @property def status(self): payments = OrderPayment.objects.filter(order=self.order) if all(payment.date_paid for payment in payments): return "Completed" else: return "Not Completed" def save(self, *args, **kwargs): if not self.invoice_number: current_year = str(timezone.now().year)[-2:] last_invoice = Invoice.objects.all().last() if last_invoice: last_invoice_number = int(last_invoice.invoice_number.split('-')[1].split('+')[0]) new_invoice_number = f"$0{current_year}-{last_invoice_number + 1}" else: new_invoice_number = f"$0{current_year}-1425" self.invoice_number = new_invoice_number super().save(*args, **kwargs) class PaymentType(models.Model): name = models.CharField(max_length=100) description = models.TextField(null=True, blank=True) image = models.ImageField(null=True, blank=True) def __str__(self): return self.name class OrderPayment(models.Model): order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True) amount = models.FloatField(null=True) date_paid = models.DateField(null=True,blank=True) date_due = models.DateField(null=True, blank=True) type = models.ManyToManyField(PaymentType, null=True) comment = models.TextField(null=True, blank=True) def __str__(self): return f"Payment for {self.order}" class Receipt(models.Model): receipt_number = models.CharField(max_length=100) payment = models.ManyToManyField(OrderPayment) date_generated = models.DateField() def __str__(self): return self.receipt_number