lMerge branch 'main' of http://10.10.1.120:3000/tenhal_admin/haikal
This commit is contained in:
commit
8a9ccf26c7
Binary file not shown.
Binary file not shown.
@ -810,3 +810,46 @@ 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}"
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
from nltk.app.wordnet_app import page_from_reference
|
||||||
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
|
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
|
||||||
from reportlab.lib import colors
|
from reportlab.lib import colors
|
||||||
from reportlab.lib.pagesizes import A4
|
from reportlab.lib.pagesizes import A4
|
||||||
@ -62,7 +63,7 @@ def generate_quotation_pdf(response, quotation, services):
|
|||||||
|
|
||||||
# Car Details Table
|
# Car Details Table
|
||||||
elements.append(Paragraph("Car Details", heading_style))
|
elements.append(Paragraph("Car Details", heading_style))
|
||||||
car_data = [["VIN", "Model", "Year", "Quantity", "Price", "VAT %", "Total"]]
|
car_data = [["رقم الهيكل", "الموديل", "سنة الصنع", "الكمية", "السعر", "الضريبة", "الإجمالي"]]
|
||||||
for item in quotation.quotation_cars.all():
|
for item in quotation.quotation_cars.all():
|
||||||
car_data.append([
|
car_data.append([
|
||||||
item.car.vin,
|
item.car.vin,
|
||||||
@ -117,5 +118,6 @@ def generate_quotation_pdf(response, quotation, services):
|
|||||||
]))
|
]))
|
||||||
elements.append(additional_table)
|
elements.append(additional_table)
|
||||||
|
|
||||||
|
|
||||||
# Build PDF
|
# Build PDF
|
||||||
doc.build(elements)
|
doc.build(elements)
|
||||||
@ -1,6 +1,6 @@
|
|||||||
from random import randint
|
from random import randint
|
||||||
|
|
||||||
from django.db.models.signals import post_save, post_delete, pre_delete
|
from django.db.models.signals import post_save, post_delete,pre_delete
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django_ledger.views import JournalEntryCreateView
|
from django_ledger.views import JournalEntryCreateView
|
||||||
from django_ledger.models import (
|
from django_ledger.models import (
|
||||||
@ -19,6 +19,7 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# @receiver(post_save, sender=models.SaleQuotation)
|
# @receiver(post_save, sender=models.SaleQuotation)
|
||||||
# def link_quotation_to_entity(sender, instance, created, **kwargs):
|
# def link_quotation_to_entity(sender, instance, created, **kwargs):
|
||||||
# if created:
|
# if created:
|
||||||
@ -31,72 +32,21 @@ from . import models
|
|||||||
# user = instance.user
|
# user = instance.user
|
||||||
# if user:
|
# if user:
|
||||||
# user.delete()
|
# user.delete()
|
||||||
|
|
||||||
User = get_user_model()
|
|
||||||
|
|
||||||
@receiver(post_save, sender=User)
|
|
||||||
def create_user_profile(sender, instance, created, **kwargs):
|
|
||||||
if created:
|
|
||||||
dealer = models.Dealer.objects.create(user=instance, name=instance.username)
|
|
||||||
# dealer.user.set_password("Tenhal@123")
|
|
||||||
dealer.save()
|
|
||||||
|
|
||||||
@receiver(post_save, sender=models.Car)
|
|
||||||
def create_product_for_car(sender, instance, created, **kwargs):
|
|
||||||
if created:
|
|
||||||
entity = EntityModel.objects.get(name=instance.dealer.get_root_dealer.name)
|
|
||||||
|
|
||||||
product_model = entity.create_item_product(
|
|
||||||
name=f"{instance.year} {instance.id_car_make} {instance.id_car_model} {instance.id_car_trim}",
|
|
||||||
uom_model=entity.get_uom_all().first(),
|
|
||||||
item_type=ItemModel.ITEM_TYPE_OTHER,
|
|
||||||
coa_model=entity.get_default_coa(),
|
|
||||||
)
|
|
||||||
print(f"Created product: {product_model.name}")
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=models.CarFinance)
|
|
||||||
def update_product_default_value(sender, instance, **kwargs):
|
|
||||||
# Get the associated car
|
|
||||||
car = instance.car
|
|
||||||
|
|
||||||
# Get the entity associated with the dealer
|
|
||||||
entity = EntityModel.objects.get(name=car.dealer.get_root_dealer.name) # Assuming the dealer's name matches the entity name
|
|
||||||
|
|
||||||
# Get the product in Django Ledger associated with the car
|
|
||||||
items_products = entity.get_items_products()
|
|
||||||
|
|
||||||
try:
|
|
||||||
product_model = items_products.get(
|
|
||||||
name=f"{car.year} {car.id_car_make} {car.id_car_model} {car.id_car_trim}"
|
|
||||||
)
|
|
||||||
except ItemModel.DoesNotExist:
|
|
||||||
print(f"Product for car {car} does not exist in Django Ledger.")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Update the default value per unit of measure for the product
|
|
||||||
product_model.default_amount = instance.selling_price
|
|
||||||
product_model.save()
|
|
||||||
|
|
||||||
print(f"Updated product {product_model.name} with default value: {product_model.default_amount}")
|
|
||||||
|
|
||||||
@receiver(post_save, sender=models.Car)
|
@receiver(post_save, sender=models.Car)
|
||||||
def create_car_location(sender, instance, created, **kwargs):
|
def create_car_location(sender, instance, created, **kwargs):
|
||||||
"""
|
"""
|
||||||
Signal to create or update the car's location when a car instance is saved.
|
Signal to create or update the car's location when a car instance is saved.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if created:
|
if created:
|
||||||
if instance.dealer is None:
|
if instance.dealer is None:
|
||||||
raise ValueError(
|
raise ValueError(f"Cannot create CarLocation for car {instance.vin}: dealer is missing.")
|
||||||
f"Cannot create CarLocation for car {instance.vin}: dealer is missing."
|
|
||||||
)
|
|
||||||
|
|
||||||
models.CarLocation.objects.create(
|
models.CarLocation.objects.create(
|
||||||
car=instance,
|
car=instance,
|
||||||
owner=instance.dealer,
|
owner=instance.dealer,
|
||||||
showroom=instance.dealer,
|
showroom=instance.dealer,
|
||||||
description=f"Initial location set for car {instance.vin}.",
|
description=f"Initial location set for car {instance.vin}."
|
||||||
)
|
)
|
||||||
print("Car Location created")
|
print("Car Location created")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -143,65 +93,65 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
)
|
)
|
||||||
print(f"Ledger entity created for Dealer: {instance.name}")
|
print(f"Ledger entity created for Dealer: {instance.name}")
|
||||||
|
|
||||||
entity.create_account(
|
# entity.create_account(
|
||||||
coa_model=default_coa,
|
# coa_model=coa,
|
||||||
code="10100",
|
# code=1010,
|
||||||
role='asset_ca_cash',
|
# role='asset_ca_cash',
|
||||||
name=_('Cash'),
|
# name=_('Cash'),
|
||||||
balance_type="debit",
|
# balance_type="debit",
|
||||||
)
|
# )
|
||||||
entity.create_account(
|
# entity.create_account(
|
||||||
coa_model=default_coa,
|
# coa_model=coa,
|
||||||
code="11000",
|
# code=1100,
|
||||||
role='asset_ca_recv',
|
# role='asset_ca_recv',
|
||||||
name=_('Accounts Receivable'),
|
# name=_('Accounts Receivable'),
|
||||||
balance_type="debit",
|
# balance_type="debit",
|
||||||
)
|
# )
|
||||||
entity.create_account(
|
# entity.create_account(
|
||||||
coa_model=default_coa,
|
# coa_model=coa,
|
||||||
code="12000",
|
# code=1200,
|
||||||
role='asset_ca_inv',
|
# role='asset_ca_inv',
|
||||||
name=_('Inventory'),
|
# name=_('Inventory'),
|
||||||
balance_type="debit",
|
# balance_type="debit",
|
||||||
active=True)
|
# active=True)
|
||||||
|
|
||||||
entity.create_account(
|
|
||||||
coa_model=default_coa,
|
|
||||||
code="20100",
|
|
||||||
role='lia_cl_acc_payable',
|
|
||||||
name=_('Accounts Payable'),
|
|
||||||
balance_type="credit",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
entity.create_account(
|
|
||||||
coa_model=default_coa,
|
|
||||||
code="40100",
|
|
||||||
role='in_operational',
|
|
||||||
name=_('Sales Income'),
|
|
||||||
balance_type="credit",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
entity.create_account(
|
|
||||||
coa_model=default_coa,
|
|
||||||
code="50100",
|
|
||||||
role='cogs_regular',
|
|
||||||
name=_('Cost of Goods Sold'),
|
|
||||||
balance_type="debit",
|
|
||||||
active=True)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Failed to create Ledger entity for Dealer: {instance.name}. Error: {e}")
|
|
||||||
|
|
||||||
# entity = EntityModel.objects.filter(name=instance.dealer.name).first()
|
|
||||||
#
|
#
|
||||||
|
# entity.create_account(
|
||||||
|
# coa_model=coa,
|
||||||
|
# code=2010,
|
||||||
|
# role='lia_cl_acc_payable',
|
||||||
|
# name=_('Accounts Payable'),
|
||||||
|
# balance_type="credit",
|
||||||
|
# active=True)
|
||||||
|
#
|
||||||
|
# entity.create_account(
|
||||||
|
# coa_model=coa,
|
||||||
|
# code=4010,
|
||||||
|
# role='in_operational',
|
||||||
|
# name=_('Sales Income'),
|
||||||
|
# balance_type="credit",
|
||||||
|
# active=True)
|
||||||
|
#
|
||||||
|
# entity.create_account(
|
||||||
|
# coa_model=coa,
|
||||||
|
# code=5010,
|
||||||
|
# role='cogs_regular',
|
||||||
|
# name=_('Cost of Goods Sold'),
|
||||||
|
# balance_type="debit",
|
||||||
|
# active=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# uom_name = _("Unit")
|
# uom_name = _("Unit")
|
||||||
# unit_abbr = _("U")
|
# unit_abbr = _("U")
|
||||||
#
|
#
|
||||||
# entity.create_uom(uom_name, unit_abbr)
|
# entity.create_uom(uom_name, unit_abbr)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Create Vendor
|
# Create Vendor
|
||||||
@receiver(post_save, sender=models.Vendor)
|
@receiver(post_save, sender=models.Vendor)
|
||||||
def create_ledger_vendor(sender, instance, created, **kwargs):
|
def create_ledger_vendor(sender, instance, created, **kwargs):
|
||||||
|
|
||||||
if created:
|
if created:
|
||||||
entity = EntityModel.objects.filter(name=instance.dealer.name).first()
|
entity = EntityModel.objects.filter(name=instance.dealer.name).first()
|
||||||
|
|
||||||
@ -216,8 +166,8 @@ def create_ledger_vendor(sender, instance, created, **kwargs):
|
|||||||
additional_info={
|
additional_info={
|
||||||
"arabic_name": instance.arabic_name,
|
"arabic_name": instance.arabic_name,
|
||||||
"contact_person": instance.contact_person,
|
"contact_person": instance.contact_person,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
|
|
||||||
print(f"VendorModel created for Vendor: {instance.name}")
|
print(f"VendorModel created for Vendor: {instance.name}")
|
||||||
|
|
||||||
@ -225,9 +175,7 @@ def create_ledger_vendor(sender, instance, created, **kwargs):
|
|||||||
@receiver(post_save, sender=models.Customer)
|
@receiver(post_save, sender=models.Customer)
|
||||||
def create_customer(sender, instance, created, **kwargs):
|
def create_customer(sender, instance, created, **kwargs):
|
||||||
if created:
|
if created:
|
||||||
entity = EntityModel.objects.filter(
|
entity = EntityModel.objects.filter(name=instance.dealer.get_root_dealer.name).first()
|
||||||
name=instance.dealer.get_root_dealer.name
|
|
||||||
).first()
|
|
||||||
name = f"{instance.first_name} {instance.middle_name} {instance.last_name}"
|
name = f"{instance.first_name} {instance.middle_name} {instance.last_name}"
|
||||||
|
|
||||||
entity.create_customer(
|
entity.create_customer(
|
||||||
@ -239,7 +187,7 @@ def create_customer(sender, instance, created, **kwargs):
|
|||||||
"sales_tax_rate": 0.15,
|
"sales_tax_rate": 0.15,
|
||||||
"active": True,
|
"active": True,
|
||||||
"hidden": False,
|
"hidden": False,
|
||||||
"additional_info": {},
|
"additional_info": {}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from django_ledger.models import EntityModel, InvoiceModel,EntityUnitModel,LedgerModel
|
from django_ledger.models import EntityModel, InvoiceModel
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
@ -786,6 +786,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)
|
||||||
@ -1069,6 +1071,7 @@ def mark_quotation(request, pk):
|
|||||||
# messages.success(request, _("Quotation Paid"))
|
# messages.success(request, _("Quotation Paid"))
|
||||||
return redirect("quotation_detail", pk=pk)
|
return redirect("quotation_detail", pk=pk)
|
||||||
|
|
||||||
|
|
||||||
@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)
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -74,7 +74,7 @@
|
|||||||
<th>{% trans "Year" %}</th>
|
<th>{% trans "Year" %}</th>
|
||||||
<th>{% trans "Quantity" %}</th>
|
<th>{% trans "Quantity" %}</th>
|
||||||
<th>{% trans "Price" %}</th>
|
<th>{% trans "Price" %}</th>
|
||||||
<th>{% trans "VAT %" %}</th>
|
<th>{% trans "VAT" %}</th>
|
||||||
<th>{% trans "Total" %}</th>
|
<th>{% trans "Total" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user