diff --git a/inventory/__pycache__/views.cpython-311.pyc b/inventory/__pycache__/views.cpython-311.pyc index 7fa01829..2b8c0b67 100644 Binary files a/inventory/__pycache__/views.cpython-311.pyc and b/inventory/__pycache__/views.cpython-311.pyc differ diff --git a/inventory/models.py b/inventory/models.py index b06f04db..1b62f54d 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -798,4 +798,47 @@ class SalesOrder(models.Model): ) def __str__(self): - return f"Sales Order #{self.id} from Quotation #{self.quotation.id}" \ No newline at end of file + return f"Sales Order #{self.id} from Quotation #{self.quotation.id}" + + +class Payment(models.Model): + METHOD_CHOICES = [ + ('cash', _('cash')), + ('credit', _('credit')), + ('transfer', _('transfer')), + ('debit', _('debit')), + ('SADAD', _('SADAD')), + ] + quotation = models.ForeignKey(SaleQuotation, on_delete=models.CASCADE, related_name="payments") + amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name=_("amount")) + payment_method = models.CharField(choices=METHOD_CHOICES, max_length=50, verbose_name=_("method")) + reference_number = models.CharField(max_length=100, null=True, blank=True, verbose_name=_("reference number")) + payment_date = models.DateField(auto_now_add=True, verbose_name=_("date")) + + # def save(self, *args, **kwargs): + # super().save(*args, **kwargs) + # self.quotation.remaining_balance -= self.amount + # if self.quotation.remaining_balance <= 0: + # self.quotation.is_paid = True + # self.quotation.save() + + class Meta: + verbose_name = _("payment") + verbose_name_plural = _("payments") + + def __str__(self): + return f"Payment of {self.amount} on {self.date} for {self.order}" + + +class Refund(models.Model): + payment = models.OneToOneField(Payment, on_delete=models.CASCADE, related_name="refund") + amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name=_("amount")) + reason = models.TextField(blank=True, verbose_name=_("reason")) + refund_date = models.DateField(auto_now_add=True, verbose_name=_("refund date")) + + class Meta: + verbose_name = _("refund") + verbose_name_plural = _("refunds") + + def __str__(self): + return f"Refund of {self.amount} on {self.refund_date}" \ No newline at end of file diff --git a/inventory/views.py b/inventory/views.py index 71f5a81b..14d86ae2 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -1,8 +1,8 @@ -from django_ledger.models import EntityModel, InvoiceModel,EntityUnitModel,LedgerModel +from django_ledger.models import EntityModel, InvoiceModel import logging import json from decimal import Decimal -from django_ledger.models import TransactionModel, AccountModel,JournalEntryModelfrom .pdf_generator import generate_quotation_pdf +from .pdf_generator import generate_quotation_pdf from django.shortcuts import HttpResponse from django.template.loader import render_to_string # from weasyprint import HTML @@ -300,7 +300,7 @@ class CarInventory(LoginRequiredMixin, ListView): make_id = self.kwargs['make_id'] model_id = self.kwargs['model_id'] trim_id = self.kwargs['trim_id'] - + cars = models.Car.objects.filter( dealer=self.request.user.dealer.get_root_dealer, id_car_make=make_id, @@ -784,6 +784,8 @@ class QuotationListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): def get_queryset(self): status = self.request.GET.get("status") + # queryset = models.SaleQuotation.objects.all() + print(self.request.user.dealer.get_root_dealer.sales.all()) queryset = self.request.user.dealer.get_root_dealer.sales.all() if status: queryset = queryset.filter(status=status) @@ -808,99 +810,51 @@ class QuotationDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailVie @login_required def generate_invoice(request, pk): - quotation = get_object_or_404(models.SaleQuotation, pk=pk) + quotation = get_object_or_404(models.SaleQuotation, pk=pk) if not quotation.is_approved: messages.error( request, "Quotation must be approved before converting to an invoice." ) else: entity = quotation.entity - coa_qs, coa_map = entity.get_all_coa_accounts() - cash_account = coa_qs.first().get_coa_accounts().filter(name="Cash") - customer = entity.get_customers().filter(customer_name=quotation.customer.get_full_name).first() - - invoice_model = entity.create_invoice( - customer_model=customer, - terms=InvoiceModel.TERMS_NET_30, - cash_account=cash_account.first(), - coa_model=coa_qs.first(), + customer = ( + entity.get_customers() + .filter(customer_name=quotation.customer.get_full_name) + .first() ) - - name_list = [f"{instance.car.year} {instance.car.id_car_make} {instance.car.id_car_model} {instance.car.id_car_trim}" for instance in quotation.quotation_cars.all()] - - invoices_item_models = invoice_model.get_item_model_qs().filter(name__in=name_list) - invoice_itemtxs = { - im.item_number: { - "unit_cost": im.default_amount, - "quantity": 1, - "total_amount": im.default_amount, - } - for im in invoices_item_models - } - - invoice_itemtxs = invoice_model.migrate_itemtxs( - itemtxs=invoice_itemtxs, commit=True, operation=InvoiceModel.ITEMIZE_APPEND + print(customer) + invoices = entity.create_invoice( + customer_model=customer, terms=InvoiceModel.TERMS_NET_30 ) - - ledger = entity.create_ledger( - name=f"Payment Ledger for Invoice {invoice_model}", - posted=True - ) - - entity_unit,created = EntityUnitModel.objects.get_or_create( - name="Sales Department", - entity=entity, - document_prefix="SD" - ) - - journal_entry = JournalEntryModel.objects.create( - entity_unit=entity_unit, - posted=False, - description=f"Payment for Invoice {invoice_model}", - ledger=ledger, - locked=False, - origin="Payment", - ) - - - - accounts_receivable = coa_qs.first().get_coa_accounts().filter(name="Accounts Receivable").first() - if not accounts_receivable: - accounts_receivable = entity.create_account( - code="AR", - role="asset", - name="Accounts Receivable", - coa_model=coa_qs.first(), - balance_type="credit" - ) - - TransactionModel.objects.create( - journal_entry=journal_entry, - account=cash_account.first(), # Debit Cash - amount=invoice_model.amount_due, # Payment amount - tx_type='debit', - description="Payment Received", - ) - - TransactionModel.objects.create( - journal_entry=journal_entry, - account=accounts_receivable, # Credit Accounts Receivable - amount=invoice_model.amount_due, # Payment amount - tx_type='credit', - description="Payment Received", - ) - invoice_model.mark_as_review() - print("reviewed") - invoice_model.mark_as_approved(entity_slug=entity.slug, user_model=request.user.dealer.get_root_dealer.user) - print("approved") - invoice_model.mark_as_paid(entity_slug=entity.slug, user_model=request.user.dealer.get_root_dealer.user) - print("paid") - + # invoice_itemtxs = { + # f"{qc}": { + # "unit_cost": f"{qc.car.finances.selling_price}", + # "quantity": f"{qc.quantity}", + # "total_amount": f"{qc.total_vat}", + # } + # for qc in quotation.quotation_cars.all() + # } + # invoice_itemtxs = { + # "test":{ + # "unit_cost": "1000", + # "quantity": "1", + # "total_amount": "1000", + # }, + # "test1":{ + # "unit_cost": "1000", + # "quantity": "1", + # "total_amount": "1000", + # } + # } + # invoice_itemtxs = invoices.migrate_itemtxs( + # itemtxs=invoice_itemtxs, commit=True, operation=InvoiceModel.ITEMIZE_APPEND + # ) messages.success(request, "Invoice created") return redirect("quotation_detail", pk=pk) # return redirect('django_ledger:invoice-detail', entity_slug=quotation.entity.slug, invoice_pk=invoice.uuid) + @login_required def confirm_quotation(request, pk): quotation = get_object_or_404(models.SaleQuotation, pk=pk)