This commit is contained in:
gitea 2024-12-26 07:51:23 +00:00
parent d15cb61a12
commit be055f2de7
9 changed files with 129 additions and 73 deletions

View File

@ -104,14 +104,21 @@ WSGI_APPLICATION = 'car_inventory.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
# DATABASES = {
# "default": {
# "ENGINE": "django_prometheus.db.backends.postgresql",
# "NAME": "murad_haikal",
# "USER": "f95166",
# "PASSWORD": "Kfsh&rc9788",
# "HOST": "localhost",
# "PORT": 5432,
# }
# }
DATABASES = {
"default": {
"ENGINE": "django_prometheus.db.backends.postgresql",
"NAME": "murad_haikal",
"USER": "f95166",
"PASSWORD": "Kfsh&rc9788",
"HOST": "localhost",
"PORT": 5432,
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3',
}
}

View File

@ -0,0 +1,21 @@
# Generated by Django 4.2.17 on 2024-12-26 07:13
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('inventory', '0018_additionalservices_taxable'),
]
operations = [
migrations.RemoveField(
model_name='additionalservices',
name='taxable',
),
migrations.RemoveField(
model_name='salequotation',
name='entity',
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 4.2.17 on 2024-12-26 07:22
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('django_ledger', '0017_alter_accountmodel_unique_together_and_more'),
('inventory', '0019_remove_additionalservices_taxable_and_more'),
]
operations = [
migrations.AddField(
model_name='dealer',
name='entity',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='django_ledger.entitymodel'),
),
]

View File

@ -498,6 +498,7 @@ class Dealer(models.Model, LocalizedNameMixin):
logo = models.ImageField(
upload_to="logos/users", blank=True, null=True, verbose_name=_("Logo")
)
entity = models.ForeignKey(EntityModel, on_delete=models.SET_NULL, null=True, blank=True)
joined_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Joined At"))
email = models.EmailField(unique=True, verbose_name=_("Email"))
parent_dealer = models.ForeignKey(
@ -676,8 +677,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

@ -10,7 +10,6 @@ from django.utils.translation import gettext_lazy as _
from . import models
# @receiver(post_save, sender=models.SaleQuotation)
# def link_quotation_to_entity(sender, instance, created, **kwargs):
# if created:
@ -163,23 +162,24 @@ 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

View File

@ -5,7 +5,6 @@ from django.conf.urls import (
handler400, handler403, handler404, handler500
)
urlpatterns = [
# main URLs
path('', views.HomeView.as_view(), name='landing_page'),
@ -46,7 +45,6 @@ urlpatterns = [
path('vendors/<int:pk>/update/', views.VendorUpdateView.as_view(), name='vendor_update'),
path('vendors/<int:pk>/delete/', views.VendorDetailView.as_view(), name='vendor_delete'),
# Car URLs
path('cars/inventory/',
views.CarInventory.as_view(),

View File

@ -22,6 +22,12 @@ def get_financial_value(name,vat=False):
def get_total_financials(instance,vat=False):
total = 0
if instance.additional_services.exists():
total = sum(x.price for x in instance.additional_services.all()) + instance.selling_price
if vat:
total = (total * settings.VAT_RATE).quantize(Decimal('0.01')) + total
# price_after_discount = get_financial_value(instance,"selling_price",vat) - get_financial_value(instance,"discount_amount",vat)
# subtotal = (
# price_after_discount +
@ -30,9 +36,9 @@ def get_total_financials(instance,vat=False):
# get_financial_value("transportation_fee",vat) +
# get_financial_value("custom_card_fee",vat))
return 1000
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)
# total_vat = get_total_financials(instance,vat=True)
return total

View File

@ -759,10 +759,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)
dealer = self.request.user.dealer.get_root_dealer
form.instance.dealer = dealer
form.instance.entity = entity
quotation = form.save()
selected_cars = form.cleaned_data.get("cars")
for car in selected_cars:
@ -785,9 +783,7 @@ class QuotationListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
permission_required = ("inventory.view_salequotation",)
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())
status = self.request.GET.get("status")
queryset = self.request.user.dealer.get_root_dealer.sales.all()
if status:
queryset = queryset.filter(status=status)
@ -813,12 +809,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
if not quotation.is_approved:
messages.error(
request, "Quotation must be approved before converting to an invoice."
)
else:
entity = quotation.entity
entity = dealer.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")
@ -979,36 +976,36 @@ def post_quotation(request, pk):
# 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",
)
# journal_entry = JournalEntryModel.objects.create(
# entity_unit=entity_unit,
# posted=False,
# description=f"Payment for Invoice {invoice_model}",
# ledger=ledger,
# locked=False,
# origin="Payment",
# )
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=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=recivable_account.first(), # Credit Accounts Receivable
amount=invoice_model.amount_due, # Payment amount
tx_type='credit',
description="Payment Received",
)
journal_entry.posted = True
qoutation.posted = True
qoutation.save()
journal_entry.save()
messages.success(request, "Invoice posted")
return redirect("quotation_detail", pk=pk)
# TransactionModel.objects.create(
# journal_entry=journal_entry,
# account=recivable_account.first(), # Credit Accounts Receivable
# amount=invoice_model.amount_due, # Payment amount
# tx_type='credit',
# description="Payment Received",
# )
# journal_entry.posted = True
# qoutation.posted = True
# qoutation.save()
# journal_entry.save()
# messages.success(request, "Invoice posted")
# return redirect("quotation_detail", pk=pk)
@login_required
def mark_quotation(request, pk):
@ -1358,8 +1355,9 @@ 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
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
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()
@ -1368,8 +1366,9 @@ def invoice_detail(request,pk):
return redirect('quotation_detail', pk=pk)
@login_required
def payment_invoice(request,pk):
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
entity = quotation.entity
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
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()
@ -1398,13 +1397,13 @@ def payment_invoice(request,pk):
def payment_create(request, pk):
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
dealer = request.user.dealer.get_root_dealer
if request.method == "POST":
form = forms.PaymentForm(request.POST)
if form.is_valid():
form.instance.quotation = quotation
insatnce = form.save()
entity = quotation.entity
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

@ -42,6 +42,7 @@
<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 rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.8/css/line.css">
<link href="https://cdn.jsdelivr.net/npm/sweetalert2@11.15.3/dist/sweetalert2.min.css" rel="stylesheet">
{% if LANGUAGE_CODE == 'ar' %}
<link href="{% static 'css/theme-rtl.min.css' %}" type="text/css" rel="stylesheet" id="style-rtl">
<link href="{% static 'css/user-rtl.min.css' %}" type="text/css" rel="stylesheet" id="user-style-rtl">
@ -418,7 +419,9 @@
{% if user.is_authenticated and user.dealer or user.subdealer%}
<li class="nav-item dropdown"><a class="nav-link lh-1 pe-0" id="navbarDropdownUser" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
<div class="avatar avatar-l ">
{% if user.dealer.logo %}
<img class="rounded-circle " src="{{ user.dealer.logo.url }}" alt="" />
{% endif %}
</div>
</a>
@ -427,8 +430,9 @@
<div class="card-body p-0">
<div class="text-center pt-4 pb-3">
<div class="avatar avatar-xl ">
{% if user.dealer.logo %}
<img class="rounded-circle " src="{{ user.dealer.logo.url }}" alt="" />
{% endif %}
</div>
<h6 class="mt-2 text-body-emphasis">{{ user.dealer.get_local_name }}</h6>
</div>
@ -710,6 +714,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>