newudpate

This commit is contained in:
gitea 2024-12-26 09:31:31 +00:00
parent 71ad0bc9e6
commit 313eed6415
9 changed files with 212 additions and 158 deletions

2
.gitignore vendored
View File

@ -18,7 +18,7 @@ car_inventory/settings.py
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
Makefile
# AWS User-specific
.idea/**/aws.xml

View File

@ -34,7 +34,7 @@ from django_ledger.io import roles, DEBIT, CREDIT
class AdditionalServiceForm(forms.ModelForm):
class Meta:
model = AdditionalServices
fields = ['name', 'price','description','vatable', 'uom']
fields = ['name', 'price','description','taxable', 'uom']
class PaymentForm(forms.ModelForm):
class Meta:

View File

@ -0,0 +1,17 @@
# Generated by Django 4.2.17 on 2024-12-26 07:58
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('inventory', '0030_account'),
]
operations = [
migrations.RemoveField(
model_name='salequotation',
name='entity',
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 4.2.17 on 2024-12-26 08:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0031_remove_salequotation_entity'),
]
operations = [
migrations.RemoveField(
model_name='additionalservices',
name='vatable',
),
migrations.AddField(
model_name='additionalservices',
name='taxable',
field=models.BooleanField(default=False, verbose_name='taxable'),
),
]

View File

@ -237,7 +237,7 @@ class AdditionalServices(models.Model, LocalizedNameMixin):
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
description = models.TextField(verbose_name=_("Description"))
price = models.DecimalField(max_digits=14, decimal_places=2, verbose_name=_("Price"))
vatable = models.BooleanField(default=False, verbose_name=_("Vatable"))
taxable = models.BooleanField(default=False, verbose_name=_("taxable"))
uom = models.CharField(max_length=10, choices=UNIT_CHOICES, verbose_name=_("Unit of Measurement"))
dealer = models.ForeignKey("Dealer", on_delete=models.CASCADE, verbose_name=_("Dealer"))
@ -767,8 +767,7 @@ class SaleQuotation(models.Model):
]
dealer = models.ForeignKey(
Dealer, on_delete=models.CASCADE, related_name="sales", null=True
)
entity = models.ForeignKey(EntityModel, on_delete=models.CASCADE)
)
customer = models.ForeignKey(
Customer,
on_delete=models.CASCADE,

View File

@ -5,10 +5,12 @@ from django.dispatch import receiver
from django.utils import timezone
from django_ledger.models import EntityModel
from django.utils.translation import gettext_lazy as _
from django.contrib.auth import get_user_model
from django_ledger.io import roles
from django_ledger.models import EntityModel,AccountModel,ItemModel,ItemModelAbstract,UnitOfMeasureModel
from . import models
User = get_user_model()
# @receiver(post_save, sender=models.SaleQuotation)
# def link_quotation_to_entity(sender, instance, created, **kwargs):
@ -22,6 +24,25 @@ from . import models
# user = instance.user
# if user:
# user.delete()
@receiver(post_save, sender=User)
def create_dealer(instance, created, *args, **kwargs):
if created:
models.Dealer.objects.create(user=instance,name=instance.username,email=instance.email)
@receiver(post_save, sender=models.Dealer)
def create_user_account(sender, instance, created, **kwargs):
if created:
if instance.dealer_type != "Owner":
user = User.objects.create_user(
username=instance.name,
email=instance.email,
)
user.set_password("Tenhal@123")
user.save()
instance.user = user
instance.save()
@receiver(post_save, sender=models.Car)
def create_car_location(sender, instance, created, **kwargs):
"""
@ -67,11 +88,11 @@ def create_ledger_entity(sender, instance, created, **kwargs):
if created:
root_dealer = instance.get_root_dealer
if not root_dealer.entity:
entity_name = f"{root_dealer.name}-{root_dealer.pk}-{root_dealer.joined_at.date()}"
entity_name = f"{root_dealer.name}-{root_dealer.joined_at.date()}"
entity = EntityModel.create_entity(
name=entity_name,
admin=root_dealer.user,
use_accrual_method=True,
use_accrual_method=False,
fy_start_month=1,
)
@ -82,60 +103,88 @@ def create_ledger_entity(sender, instance, created, **kwargs):
assign_as_default=True, commit=True, coa_name=_(f"{entity_name}-COA")
)
if coa:
entity.populate_default_coa(activate_accounts=True, coa_model=coa)
# entity.populate_default_coa(activate_accounts=True, coa_model=coa)
print(f"Ledger entity created for Dealer: {instance.name}")
entity.create_account(
coa_model=coa,
code="10100",
role="asset_ca_cash",
name=_("Cash"),
balance_type="debit",
active=True,
)
entity.create_account(
coa_model=coa,
code="11000",
role="asset_ca_recv",
name=_("Accounts Receivable"),
balance_type="debit",
active=True,
)
entity.create_account(
coa_model=coa,
code="12000",
role="asset_ca_inv",
name=_("Inventory"),
balance_type="debit",
active=True,
)
# Create Cash Account
entity.create_account(
coa_model=coa,
code="1010",
role=roles.ASSET_CA_CASH,
name=_("Cash"),
balance_type="debit",
active=True,
)
entity.create_account(
coa_model=coa,
code="20100",
role="lia_cl_acc_payable",
name=_("Accounts Payable"),
balance_type="credit",
active=True,
)
# Create Accounts Receivable Account
entity.create_account(
coa_model=coa,
code="1020",
role=roles.ASSET_CA_RECEIVABLES,
name=_("Accounts Receivable"),
balance_type="debit",
active=True,
)
# Create Inventory Account
entity.create_account(
coa_model=coa,
code="1030",
role=roles.ASSET_CA_INVENTORY,
name=_("Inventory"),
balance_type="debit",
active=True,
)
entity.create_account(
coa_model=coa,
code="40100",
role="in_operational",
name=_("Sales Income"),
balance_type="credit",
active=True,
)
# Create Accounts Payable Account
entity.create_account(
coa_model=coa,
code="2010",
role=roles.LIABILITY_CL_ACC_PAYABLE,
name=_("Accounts Payable"),
balance_type="credit",
active=True,
)
entity.create_account(
coa_model=coa,
code="50100",
role="cogs_regular",
name=_("Cost of Goods Sold"),
balance_type="debit",
active=True,
)
# Create Sales Revenue Account
entity.create_account(
coa_model=coa,
code="4010",
role=roles.INCOME_OPERATIONAL,
name=_("Sales Revenue"),
balance_type="credit",
active=True,
)
# Create Cost of Goods Sold Account
entity.create_account(
coa_model=coa,
code="5010",
role=roles.COGS,
name=_("Cost of Goods Sold"),
balance_type="debit",
active=True,
)
# Create Rent Expense Account
entity.create_account(
coa_model=coa,
code="6010",
role=roles.EXPENSE_OPERATIONAL,
name=_("Rent Expense"),
balance_type="debit",
active=True,
)
# Create Utilities Expense Account
entity.create_account(
coa_model=coa,
code="6020",
role=roles.EXPENSE_OPERATIONAL,
name=_("Utilities Expense"),
balance_type="debit",
active=True,
)
# uom_name = _("Unit")
# unit_abbr = _("U")
@ -169,87 +218,52 @@ def create_ledger_vendor(sender, instance, created, **kwargs):
@receiver(post_save, sender=models.Customer)
def create_customer(sender, instance, created, **kwargs):
if created:
entity = EntityModel.objects.filter(
name=instance.dealer.get_root_dealer.name
).first()
dealer = instance.dealer.get_root_dealer
entity = dealer.entity
name = f"{instance.first_name} {instance.middle_name} {instance.last_name}"
if entity:
entity.create_customer(
customer_model_kwargs={
"customer_name": name,
"address_1": instance.address,
"phone": instance.phone_number,
"email": instance.email,
"sales_tax_rate": 0.15,
"active": True,
"hidden": False,
"additional_info": {},
}
)
entity.create_customer(
customer_model_kwargs={
"customer_name": name,
"address_1": instance.address,
"phone": instance.phone_number,
"email": instance.email,
"sales_tax_rate": 0.15,
"active": True,
"hidden": False,
"additional_info": {},
}
)
print(f"Customer created: {name}")
print(f"Customer created: {name}")
# Create Item
# @receiver(post_save, sender=models.Car)
# def create_item_model(sender, instance, created, **kwargs):
# item_name = f"{instance.year} - {instance.id_car_make} - {instance.id_car_model} - {instance.id_car_trim}"
# uom_name = _("Car")
# unit_abbr = _("C")
#
# uom, uom_created = UnitOfMeasureModel.objects.get_or_create(
# name=uom_name,
# unit_abbr=unit_abbr
# )
#
# if uom_created:
# print(f"UOM created: {uom_name}")
# else:
# print(f"Using existing UOM: {uom_name}")
#
# entity = EntityModel.objects.filter(name=instance.dealer.name).first()
#
# inventory_account = AccountModel.objects.first()
# cogs_account = AccountModel.objects.first()
# earnings_account = AccountModel.objects.first()
#
# entity.create_item_product(
# item_name=item_name,
# item_role=ItemModelAbstract.ITEM_ROLE_PRODUCT,
# item_type=ItemModelAbstract.ITEM_TYPE_MATERIAL,
# item_id=instance.vin,
# sold_as_unit=True,
# inventory_received=1.00,
# inventory_received_value=0.00,
# inventory_account=inventory_account,
# for_inventory=True,)
#
# item = ItemModel.objects.create(
# entity=entity,
# uom=uom,
# name=item_name,
# item_role=ItemModelAbstract.ITEM_ROLE_INVENTORY,
# item_type=ItemModelAbstract.ITEM_TYPE_MATERIAL,
# item_id=instance.vin,
# sold_as_unit=True,
# inventory_received=1.00,
# inventory_received_value=0.00,
# inventory_account=inventory_account,
# for_inventory=True,
# is_product_or_service=True,
# cogs_account=cogs_account,
# earnings_account=earnings_account,
# is_active=True,
# additional_info={
# "remarks": instance.remarks,
# "status": instance.status,
# "stock_type": instance.stock_type,
# "mileage": instance.mileage,
# },
# )
#
# print(f"ItemModel {'created' if created else 'updated'} for Car: {item.name}")
#
@receiver(post_save, sender=models.Car)
def create_item_model(sender, instance, created, **kwargs):
item_name = f"{instance.year} - {instance.id_car_make} - {instance.id_car_model} - {instance.id_car_trim}"
dealer = instance.dealer
entity = dealer.entity
if not entity:
return
uom_name = _("Car")
unit_abbr = _("C")
uom = entity.get_uom_all().filter(name=uom_name, unit_abbr=unit_abbr).first()
if not uom:
uom = entity.create_uom(
name=uom_name,
unit_abbr=unit_abbr
)
entity.create_item_product(
name=item_name,
uom_model=uom,
item_type=ItemModel.ITEM_TYPE_MATERIAL)
print(f"ItemModel for Car:")
#
# # update price - CarFinance
# @receiver(post_save, sender=CarFinance)

View File

@ -22,17 +22,13 @@ def get_financial_value(name,vat=False):
def get_total_financials(instance,vat=False):
# price_after_discount = get_financial_value(instance,"selling_price",vat) - get_financial_value(instance,"discount_amount",vat)
# subtotal = (
# price_after_discount +
# get_financial_value("registration_fee") +
# get_financial_value("administration_fee",vat) +
# get_financial_value("transportation_fee",vat) +
# get_financial_value("custom_card_fee",vat))
return 1000
total = 0
if instance.additional_services.count() != 0:
total = sum(x.price for x in instance.additional_services) + instance.selling_price
if vat:
total = (total * settings.VAT_RATE).quantize(Decimal('0.01')) + total
return total
def get_total(instance):
total = get_total_financials(instance)
total_vat = get_total_financials(instance,vat=True)
return total + total_vat
total = get_total_financials(instance,vat=True)
return total

View File

@ -761,10 +761,8 @@ class QuotationCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateVie
permission_required = ("inventory.add_salequotation",)
def form_valid(self, form):
dealer = self.request.user.dealer.get_root_dealer
entity = EntityModel.objects.get(name=dealer.get_root_dealer.name)
form.instance.dealer = dealer
form.instance.entity = entity
dealer = self.request.user.dealer.get_root_dealer
form.instance.dealer = dealer
quotation = form.save()
selected_cars = form.cleaned_data.get("cars")
for car in selected_cars:
@ -815,12 +813,13 @@ class QuotationDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailVie
@login_required
def generate_invoice(request, pk):
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
dealer = request.user.dealer.get_root_dealer
entity = dealer.entity
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")
recivable_account = coa_qs.first().get_coa_accounts().filter(name="Accounts Receivable")
@ -961,10 +960,11 @@ def generate_invoice(request, pk):
@login_required
def post_quotation(request, pk):
qoutation = get_object_or_404(models.SaleQuotation, pk=pk)
dealer = request.user.dealer.get_root_dealer
entity = dealer.entity
if qoutation.posted:
messages.error(request, "Quotation is already posted")
return redirect("quotation_detail", pk=pk)
entity = qoutation.entity
return redirect("quotation_detail", pk=pk)
coa_qs, coa_map = entity.get_all_coa_accounts()
cash_account = coa_qs.first().get_coa_accounts().filter(name="Cash")
recivable_account = coa_qs.first().get_coa_accounts().filter(name="Accounts Receivable")
@ -1016,7 +1016,8 @@ def post_quotation(request, pk):
def mark_quotation(request, pk):
qoutation = get_object_or_404(models.SaleQuotation, pk=pk)
status = request.GET.get("status")
entity = qoutation.entity
dealer = request.user.dealer.get_root_dealer
entity = dealer.entity
date = datetime.datetime.now()
customer = entity.get_customers().filter(customer_name=qoutation.customer.get_full_name).first()
invoice_model = entity.get_invoices().filter(customer=customer)
@ -1361,7 +1362,8 @@ def download_quotation_pdf(request, quotation_id):
@login_required
def invoice_detail(request,pk):
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
entity = quotation.entity
dealer = request.user.dealer.get_root_dealer
entity = dealer.entity
customer = entity.get_customers().filter(customer_name=quotation.customer.get_full_name).first()
invoice_model = entity.get_invoices()
@ -1371,7 +1373,8 @@ def invoice_detail(request,pk):
@login_required
def payment_invoice(request,pk):
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
entity = quotation.entity
dealer = request.user.dealer.get_root_dealer
entity = dealer.entity
customer = entity.get_customers().filter(customer_name=quotation.customer.get_full_name).first()
invoice_model = entity.get_invoices()
invoice = invoice_model.filter(customer=customer,date_draft=quotation.date_draft).first()
@ -1406,7 +1409,8 @@ def payment_create(request, pk):
form.instance.quotation = quotation
insatnce = form.save()
entity = quotation.entity
dealer = request.user.dealer.get_root_dealer
entity = dealer.entity
customer = entity.get_customers().filter(customer_name=quotation.customer.get_full_name).first()
coa_qs, coa_map = entity.get_all_coa_accounts()
cash_account = coa_qs.first().get_coa_accounts().filter(name="Cash")

View File

@ -41,6 +41,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<link href="https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@300;400;600;700;800;900&amp;display=swap" rel="stylesheet">
<link href="{% static 'vendors/simplebar/simplebar.min.css' %}" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/sweetalert2@11.15.3/dist/sweetalert2.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.8/css/line.css">
{% if LANGUAGE_CODE == 'ar' %}
<link href="{% static 'css/theme-rtl.min.css' %}" type="text/css" rel="stylesheet" id="style-rtl">
@ -724,6 +725,7 @@
<script src="{% static 'vendors/feather-icons/feather.min.js' %}"></script>
<script src="{% static 'vendors/dayjs/dayjs.min.js' %}"></script>
<script src="{% static 'js/phoenix.js' %}"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11.15.3/dist/sweetalert2.all.min.js"></script>
</body>