This commit is contained in:
Marwan Alwali 2024-12-24 16:48:01 +03:00
parent 9e8ef1978f
commit 167b6862e9
3 changed files with 81 additions and 84 deletions

View File

@ -798,4 +798,47 @@ class SalesOrder(models.Model):
) )
def __str__(self): def __str__(self):
return f"Sales Order #{self.id} from Quotation #{self.quotation.id}" 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}"

View File

@ -1,8 +1,8 @@
from django_ledger.models import EntityModel, InvoiceModel,EntityUnitModel,LedgerModel from django_ledger.models import EntityModel, InvoiceModel
import logging import logging
import json import json
from decimal import Decimal 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.shortcuts import HttpResponse
from django.template.loader import render_to_string from django.template.loader import render_to_string
# from weasyprint import HTML # from weasyprint import HTML
@ -300,7 +300,7 @@ class CarInventory(LoginRequiredMixin, ListView):
make_id = self.kwargs['make_id'] make_id = self.kwargs['make_id']
model_id = self.kwargs['model_id'] model_id = self.kwargs['model_id']
trim_id = self.kwargs['trim_id'] trim_id = self.kwargs['trim_id']
cars = models.Car.objects.filter( cars = models.Car.objects.filter(
dealer=self.request.user.dealer.get_root_dealer, dealer=self.request.user.dealer.get_root_dealer,
id_car_make=make_id, id_car_make=make_id,
@ -784,6 +784,8 @@ class QuotationListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
def get_queryset(self): def get_queryset(self):
status = self.request.GET.get("status") 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() queryset = self.request.user.dealer.get_root_dealer.sales.all()
if status: if status:
queryset = queryset.filter(status=status) queryset = queryset.filter(status=status)
@ -808,99 +810,51 @@ class QuotationDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailVie
@login_required @login_required
def generate_invoice(request, pk): 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: if not quotation.is_approved:
messages.error( messages.error(
request, "Quotation must be approved before converting to an invoice." request, "Quotation must be approved before converting to an invoice."
) )
else: else:
entity = quotation.entity entity = quotation.entity
coa_qs, coa_map = entity.get_all_coa_accounts() customer = (
cash_account = coa_qs.first().get_coa_accounts().filter(name="Cash") entity.get_customers()
customer = entity.get_customers().filter(customer_name=quotation.customer.get_full_name).first() .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(),
) )
print(customer)
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 = entity.create_invoice(
customer_model=customer, terms=InvoiceModel.TERMS_NET_30
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
) )
# invoice_itemtxs = {
ledger = entity.create_ledger( # f"{qc}": {
name=f"Payment Ledger for Invoice {invoice_model}", # "unit_cost": f"{qc.car.finances.selling_price}",
posted=True # "quantity": f"{qc.quantity}",
) # "total_amount": f"{qc.total_vat}",
# }
entity_unit,created = EntityUnitModel.objects.get_or_create( # for qc in quotation.quotation_cars.all()
name="Sales Department", # }
entity=entity, # invoice_itemtxs = {
document_prefix="SD" # "test":{
) # "unit_cost": "1000",
# "quantity": "1",
journal_entry = JournalEntryModel.objects.create( # "total_amount": "1000",
entity_unit=entity_unit, # },
posted=False, # "test1":{
description=f"Payment for Invoice {invoice_model}", # "unit_cost": "1000",
ledger=ledger, # "quantity": "1",
locked=False, # "total_amount": "1000",
origin="Payment", # }
) # }
# invoice_itemtxs = invoices.migrate_itemtxs(
# itemtxs=invoice_itemtxs, commit=True, operation=InvoiceModel.ITEMIZE_APPEND
# )
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")
messages.success(request, "Invoice created") messages.success(request, "Invoice created")
return redirect("quotation_detail", pk=pk) return redirect("quotation_detail", pk=pk)
# return redirect('django_ledger:invoice-detail', entity_slug=quotation.entity.slug, invoice_pk=invoice.uuid) # return redirect('django_ledger:invoice-detail', entity_slug=quotation.entity.slug, invoice_pk=invoice.uuid)
@login_required @login_required
def confirm_quotation(request, pk): def confirm_quotation(request, pk):
quotation = get_object_or_404(models.SaleQuotation, pk=pk) quotation = get_object_or_404(models.SaleQuotation, pk=pk)