Compare commits
No commits in common. "e5d09b6e0d92be6809ed59ce9ade18d7983a3077" and "62813388d76447b3be1aeb3790f0f699562af13f" have entirely different histories.
e5d09b6e0d
...
62813388d7
@ -1,4 +1,4 @@
|
||||
# Generated by Django 4.2.20 on 2025-03-20 17:15
|
||||
# Generated by Django 5.1.6 on 2025-03-06 01:43
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# Generated by Django 4.2.20 on 2025-03-20 17:15
|
||||
# Generated by Django 5.1.6 on 2025-03-06 01:43
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -9,8 +9,8 @@ class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0001_initial'),
|
||||
('haikalbot', '0001_initial'),
|
||||
('inventory', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
||||
@ -6,7 +6,7 @@ class InventoryConfig(AppConfig):
|
||||
|
||||
def ready(self):
|
||||
import inventory.signals
|
||||
from decimal import Decimal
|
||||
from inventory.models import VatRate
|
||||
VatRate.objects.get_or_create(rate=Decimal('0.15'), is_active=True)
|
||||
# from decimal import Decimal
|
||||
# from inventory.models import VatRate
|
||||
# VatRate.objects.get_or_create(rate=Decimal('0.15'), is_active=True)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
18
inventory/migrations/0002_alter_saleorder_payment_method.py
Normal file
18
inventory/migrations/0002_alter_saleorder_payment_method.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.7 on 2025-03-16 19:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='saleorder',
|
||||
name='payment_method',
|
||||
field=models.CharField(choices=[('cash', 'Cash'), ('finance', 'Finance'), ('lease', 'Lease'), ('credit_card', 'Credit Card'), ('bank_transfer', 'Bank Transfer'), ('SADAD', 'SADAD')], max_length=20),
|
||||
),
|
||||
]
|
||||
@ -358,6 +358,8 @@ class Car(models.Model):
|
||||
vendor = models.ForeignKey(
|
||||
VendorModel,
|
||||
models.DO_NOTHING,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="cars",
|
||||
verbose_name=_("Vendor"),
|
||||
)
|
||||
@ -592,10 +594,6 @@ class CarFinance(models.Model):
|
||||
def total(self):
|
||||
return self.selling_price
|
||||
|
||||
@property
|
||||
def total_additionals_no_vat(self):
|
||||
return sum(x.price for x in self.additional_services.all())
|
||||
|
||||
@property
|
||||
def total_additionals(self):
|
||||
return sum(x.price_ for x in self.additional_services.all())
|
||||
|
||||
@ -19,9 +19,7 @@ from django_ledger.models import (
|
||||
CustomerModel,
|
||||
JournalEntryModel,
|
||||
TransactionModel,
|
||||
LedgerModel,
|
||||
BillModel,
|
||||
ItemTransactionModel
|
||||
LedgerModel
|
||||
)
|
||||
from . import models
|
||||
from django.utils.timezone import now
|
||||
@ -644,18 +642,20 @@ def create_dealer_groups(sender, instance, created, **kwargs):
|
||||
def create_ledger_vendor(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
entity = EntityModel.objects.filter(name=instance.dealer.name).first()
|
||||
additionals = to_dict(instance)
|
||||
|
||||
entity.create_vendor(
|
||||
vendor_model_kwargs={
|
||||
"vendor_name": instance.name,
|
||||
"vendor_number": instance.crn,
|
||||
"address_1": instance.address,
|
||||
"phone": instance.phone_number,
|
||||
"email": instance.email,
|
||||
"tax_id_number": instance.vrn,
|
||||
"active": True,
|
||||
"hidden": False,
|
||||
"additional_info": additionals,
|
||||
"additional_info": {
|
||||
"arabic_name": instance.arabic_name,
|
||||
"contact_person": instance.contact_person,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@ -676,37 +676,25 @@ def create_ledger_vendor(sender, instance, created, **kwargs):
|
||||
active=True
|
||||
)
|
||||
print(f"VendorModel created for Vendor: {instance.name}")
|
||||
else:
|
||||
additionals = to_dict(instance)
|
||||
entity.get_vendors().filter(email=instance.email).first().update(
|
||||
vendor_name= instance.name,
|
||||
vendor_number= instance.crn,
|
||||
address_1= instance.address,
|
||||
phone= instance.phone_number,
|
||||
email= instance.email,
|
||||
tax_id_number= instance.vrn,
|
||||
additional_info= additionals,
|
||||
)
|
||||
|
||||
|
||||
@receiver(post_save, sender=models.CustomerModel)
|
||||
def create_customer_user(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
try:
|
||||
first_name = instance.additional_info.get("customer_info").get("first_name")
|
||||
last_name = instance.additional_info.get("customer_info").get("last_name")
|
||||
user = User.objects.create(
|
||||
username=instance.email,
|
||||
email=instance.email,
|
||||
first_name=first_name if first_name else '',
|
||||
last_name=last_name if last_name else '',
|
||||
)
|
||||
instance.additional_info.update({"user_info": to_dict(user)})
|
||||
user.set_unusable_password()
|
||||
user.save()
|
||||
instance.user = user
|
||||
instance.save()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
first_name = instance.additional_info.get("customer_info").get("first_name")
|
||||
last_name = instance.additional_info.get("customer_info").get("last_name")
|
||||
user = User.objects.create(
|
||||
username=instance.email,
|
||||
email=instance.email,
|
||||
first_name=first_name if first_name else '',
|
||||
last_name=last_name if last_name else '',
|
||||
)
|
||||
instance.additional_info.update({"user_info": to_dict(user)})
|
||||
user.set_unusable_password()
|
||||
user.save()
|
||||
instance.user = user
|
||||
instance.save()
|
||||
|
||||
|
||||
# Create Item
|
||||
@receiver(post_save, sender=models.Car)
|
||||
@ -911,6 +899,11 @@ def create_dealer_settings(sender, instance, created, **kwargs):
|
||||
bill_unearned_account=instance.entity.get_all_accounts().filter(role=roles.LIABILITY_CL_ACC_PAYABLE).first()
|
||||
)
|
||||
|
||||
@receiver(post_save, sender=models.Dealer)
|
||||
def check_if_vat_exists(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
models.VatRate.objects.get_create(is_active=True)
|
||||
|
||||
# @receiver(post_save, sender=EstimateModel)
|
||||
# def update_estimate_status(sender, instance,created, **kwargs):
|
||||
|
||||
@ -941,106 +934,98 @@ def create_dealer_settings(sender, instance, created, **kwargs):
|
||||
@receiver(post_save, sender=models.Dealer)
|
||||
def create_make_ledger_accounts(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
entity = instance.entity
|
||||
coa = entity.get_default_coa()
|
||||
entity_name = instance.user.dealer.name
|
||||
entity = EntityModel.objects.get(name=entity_name)
|
||||
|
||||
last_account = entity.get_all_accounts().filter(role=roles.ASSET_CA_RECEIVABLES).order_by('-created').first()
|
||||
if len(last_account.code) == 4:
|
||||
code = f"{int(last_account.code)}{1:03d}"
|
||||
elif len(last_account.code) > 4:
|
||||
code = f"{int(last_account.code)+1}"
|
||||
|
||||
for make in models.CarMake.objects.all():
|
||||
entity.create_account(
|
||||
name=make.name,
|
||||
code=code,
|
||||
role=roles.ASSET_CA_RECEIVABLES,
|
||||
coa_model=coa,
|
||||
balance_type="credit",
|
||||
active=True
|
||||
)
|
||||
|
||||
# @receiver(post_save, sender=VendorModel)
|
||||
# def create_vendor_accounts(sender, instance, created, **kwargs):
|
||||
# if created:
|
||||
# entity = instance.entity_model
|
||||
# coa = entity.get_default_coa()
|
||||
|
||||
# last_account = entity.get_all_accounts().filter(role=roles.LIABILITY_CL_ACC_PAYABLE).order_by('-created').first()
|
||||
# if len(last_account.code) == 4:
|
||||
# code = f"{int(last_account.path)}{1:03d}"
|
||||
# elif len(last_account.code) > 4:
|
||||
# code = f"{int(last_account.path)+1}"
|
||||
# entity.create_account(
|
||||
# code = str(int(last_account.code) + 1)
|
||||
# account = entity.create_account(
|
||||
# name=instance.vendor_name,
|
||||
# code=code,
|
||||
# role=roles.LIABILITY_CL_ACC_PAYABLE,
|
||||
# coa_model=coa,
|
||||
# coa_model=entity.get_default_coa(),
|
||||
# balance_type="credit",
|
||||
# active=True
|
||||
# )
|
||||
|
||||
def save_journal(car_finance,ledger,vendor):
|
||||
entity = ledger.entity
|
||||
|
||||
journal = JournalEntryModel.objects.create(
|
||||
posted=False,
|
||||
description=f"Finances of Car:{car_finance.car.vin} for Vendor:{car_finance.car.vendor.vendor_name}",
|
||||
ledger=ledger,
|
||||
locked=False,
|
||||
origin="Payment",
|
||||
)
|
||||
ledger.additional_info["je_number"] = journal.je_number
|
||||
ledger.save()
|
||||
|
||||
inventory_account = entity.get_default_coa_accounts().filter(role=roles.ASSET_CA_INVENTORY).first()
|
||||
vendor_account = entity.get_default_coa_accounts().get(name=vendor.vendor_name)
|
||||
additional_services_account = entity.get_default_coa_accounts().filter(name="Additional Services",role=roles.COGS).first()
|
||||
|
||||
# Debit Inventory Account
|
||||
TransactionModel.objects.create(
|
||||
journal_entry=journal,
|
||||
account=inventory_account,
|
||||
amount=car_finance.cost_price,
|
||||
tx_type='debit'
|
||||
)
|
||||
|
||||
# Credit Vendor Account
|
||||
TransactionModel.objects.create(
|
||||
journal_entry=journal,
|
||||
account=vendor_account,
|
||||
amount=car_finance.cost_price,
|
||||
tx_type='credit',
|
||||
|
||||
)
|
||||
|
||||
@receiver(post_save, sender=models.CarFinance)
|
||||
def update_finance_cost(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
entity = instance.car.dealer.entity
|
||||
vendor = instance.car.vendor
|
||||
name = f"{instance.car.vin}-{instance.car.id_car_make.name}-{instance.car.id_car_model.name}-{instance.car.year}-{vendor.vendor_name}"
|
||||
ledger,_ = LedgerModel.objects.get_or_create(name=name, entity=entity)
|
||||
save_journal(instance,ledger,vendor)
|
||||
entity = instance.car.dealer.entity
|
||||
ledger,created = LedgerModel.objects.get_or_create(name=instance.car.vin, entity=entity)
|
||||
vendor = instance.car.vendor
|
||||
|
||||
# if not created:
|
||||
# if ledger.additional_info.get("je_number"):
|
||||
# journal = JournalEntryModel.objects.filter(je_number=ledger.additional_info.get("je_number")).first()
|
||||
# journal.description = f"Finances of Car:{instance.car.vin} for Vendor:{instance.car.vendor.vendor_name}"
|
||||
# journal.save()
|
||||
# debit = journal.get_transaction_queryset().filter(tx_type='debit').first()
|
||||
# credit = journal.get_transaction_queryset().filter(tx_type='credit').first()
|
||||
# if debit and credit:
|
||||
# if journal.is_locked():
|
||||
# journal.mark_as_unlocked()
|
||||
# journal.save()
|
||||
# debit.amount = instance.cost_price
|
||||
# credit.amount = instance.cost_price
|
||||
# debit.save()
|
||||
# credit.save()
|
||||
# else:
|
||||
# save_journal(instance,ledger,vendor,journal=journal)
|
||||
# else:
|
||||
# save_journal(instance,ledger,vendor)
|
||||
# else:
|
||||
# save_journal(instance,ledger,vendor)
|
||||
if created:
|
||||
journal = JournalEntryModel.objects.create(
|
||||
posted=False,
|
||||
description=f"Finances of Car:{instance.car.vin} for Vendor:{instance.car.vendor.vendor_name}",
|
||||
ledger=ledger,
|
||||
locked=False,
|
||||
origin="Payment",
|
||||
)
|
||||
ledger.additional_info["je_number"] = journal.je_number
|
||||
ledger.save()
|
||||
|
||||
inventory_account = entity.get_default_coa_accounts().filter(role=roles.ASSET_CA_INVENTORY).first()
|
||||
vendor_account = entity.get_default_coa_accounts().get(name=vendor.vendor_name)
|
||||
|
||||
# Debit Inventory Account
|
||||
TransactionModel.objects.create(
|
||||
journal_entry=journal,
|
||||
account=inventory_account,
|
||||
amount=instance.total + instance.total_additionals,
|
||||
tx_type='debit'
|
||||
)
|
||||
|
||||
# Credit Vendor Account
|
||||
TransactionModel.objects.create(
|
||||
journal_entry=journal,
|
||||
account=vendor_account,
|
||||
amount=instance.cost_price,
|
||||
tx_type='credit'
|
||||
)
|
||||
else:
|
||||
if not ledger.additional_info.get("je_number"):
|
||||
journal = JournalEntryModel.objects.create(
|
||||
posted=False,
|
||||
description=f"Finances of Car:{instance.car.vin} for Vendor:{instance.car.vendor.vendor_name}",
|
||||
ledger=ledger,
|
||||
locked=False,
|
||||
origin="Payment",
|
||||
)
|
||||
ledger.additional_info["je_number"] = journal.je_number
|
||||
ledger.save()
|
||||
|
||||
inventory_account = entity.get_default_coa_accounts().filter(role=roles.ASSET_CA_INVENTORY).first()
|
||||
vendor_account = entity.get_default_coa_accounts().get(name=vendor.vendor_name, active=True)
|
||||
|
||||
# Debit Inventory Account
|
||||
TransactionModel.objects.create(
|
||||
journal_entry=journal,
|
||||
account=inventory_account,
|
||||
amount=instance.cost_price,
|
||||
tx_type='debit'
|
||||
)
|
||||
|
||||
# Credit Vendor Account
|
||||
TransactionModel.objects.create(
|
||||
journal_entry=journal,
|
||||
account=vendor_account,
|
||||
amount=instance.cost_price,
|
||||
tx_type='credit'
|
||||
)
|
||||
|
||||
else:
|
||||
journal = JournalEntryModel.objects.filter(je_number=ledger.additional_info.get("je_number")).first()
|
||||
debit = journal.get_transaction_queryset().filter(tx_type='debit').first()
|
||||
credit = journal.get_transaction_queryset().filter(tx_type='credit').first()
|
||||
|
||||
debit.amount = instance.cost_price
|
||||
credit.amount = instance.cost_price
|
||||
|
||||
debit.save()
|
||||
credit.save()
|
||||
@ -935,29 +935,3 @@ def handle_account_process(invoice,amount,finance_data):
|
||||
tx_type="credit",
|
||||
description="VAT Payable on Invoice",
|
||||
)
|
||||
|
||||
def create_make_accounts(dealer):
|
||||
entity = dealer.entity
|
||||
coa = entity.get_default_coa()
|
||||
|
||||
# Create a unique account name for the dealer and car make combination
|
||||
makes = models.DealersMake.objects.filter(dealer=dealer).all()
|
||||
for make in makes:
|
||||
account_name = f"{make.car_make.name} Inventory Account"
|
||||
|
||||
account = entity.get_all_accounts().filter(coa_model=coa,name=account_name).first()
|
||||
if not account:
|
||||
last_account = entity.get_all_accounts().filter(role=roles.ASSET_CA_INVENTORY).order_by('-created').first()
|
||||
if len(last_account.code) == 4:
|
||||
code = f"{int(last_account.code)}{1:03d}"
|
||||
elif len(last_account.code) > 4:
|
||||
code = f"{int(last_account.code)+1}"
|
||||
|
||||
account = entity.create_account(
|
||||
name=account_name,
|
||||
code=code,
|
||||
role=roles.ASSET_CA_INVENTORY,
|
||||
coa_model=coa,
|
||||
balance_type="credit",
|
||||
active=True
|
||||
)
|
||||
@ -127,7 +127,6 @@ from .services import (
|
||||
)
|
||||
from .utils import (
|
||||
CarFinanceCalculator,
|
||||
create_make_accounts,
|
||||
get_car_finance_data,
|
||||
get_financial_values,
|
||||
get_item_transactions,
|
||||
@ -137,7 +136,6 @@ from .utils import (
|
||||
set_bill_payment,
|
||||
set_invoice_payment,
|
||||
CarTransfer,
|
||||
to_dict,
|
||||
)
|
||||
|
||||
#####################################################################
|
||||
@ -1506,31 +1504,13 @@ class VendorUpdateView(
|
||||
SuccessMessageMixin,
|
||||
UpdateView,
|
||||
):
|
||||
model = VendorModel
|
||||
model = models.Vendor
|
||||
form_class = forms.VendorForm
|
||||
template_name = "vendors/vendor_form.html"
|
||||
success_url = reverse_lazy("vendor_list")
|
||||
success_message = _("Vendor updated successfully.")
|
||||
|
||||
def get_initial(self):
|
||||
initial = super().get_initial()
|
||||
initial = self.object.additional_info
|
||||
return initial
|
||||
|
||||
def form_valid(self, form):
|
||||
instance = form.save(commit=False)
|
||||
|
||||
instance.vendor_name = self.request.POST["name"]
|
||||
instance.vendor_number = self.request.POST["crn"]
|
||||
instance.address_1 = self.request.POST["address"]
|
||||
instance.phone = self.request.POST["phone_number"]
|
||||
instance.email = self.request.POST["email"]
|
||||
instance.tax_id_number = self.request.POST["vrn"]
|
||||
additionals = form.cleaned_data
|
||||
additionals['phone_number'] = str(additionals['phone_number'])
|
||||
instance.additional_info = additionals
|
||||
instance.save()
|
||||
return super().form_valid(form)
|
||||
@login_required
|
||||
def delete_vendor(request, pk):
|
||||
vendor = get_object_or_404(models.Vendor, pk=pk)
|
||||
@ -4072,7 +4052,6 @@ def assign_car_makes(request):
|
||||
form = forms.DealersMakeForm(request.POST, dealer=dealer)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
create_make_accounts(dealer)
|
||||
return redirect("dealer_detail", pk=dealer.pk)
|
||||
else:
|
||||
# Pre-fill the form with existing selections
|
||||
@ -4091,7 +4070,6 @@ class LedgerModelListView(LoginRequiredMixin, ListView,ArchiveIndexView):
|
||||
show_all = False
|
||||
show_current = False
|
||||
show_visible = False
|
||||
allow_empty = True
|
||||
|
||||
|
||||
def get_queryset(self):
|
||||
|
||||
@ -29,6 +29,8 @@ commonmark
|
||||
contourpy
|
||||
crispy-bootstrap5
|
||||
cryptography
|
||||
cssselect2
|
||||
ctranslate2
|
||||
cycler
|
||||
Cython
|
||||
decorator
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
from inventory.models import *
|
||||
from django_ledger.models import VendorModel
|
||||
from rich import print
|
||||
import random
|
||||
import datetime
|
||||
@ -9,9 +8,6 @@ from inventory.services import decodevin
|
||||
|
||||
def run():
|
||||
# car = Car.objects.filter(vin='2C3HD46R4WH170267')
|
||||
dealer = Dealer.objects.first()
|
||||
vendors = [VendorModel.objects.create(vendor_name=f'vendor{i}',entity_model=dealer.entity) for i in range(1, 5)]
|
||||
|
||||
vin_list = [
|
||||
"1B3ES56C13D120225",
|
||||
"1GB4KYC86FF131536",
|
||||
@ -28,8 +24,8 @@ def run():
|
||||
]
|
||||
for vin in vin_list:
|
||||
try:
|
||||
for _ in range(5):
|
||||
|
||||
for _ in range(15):
|
||||
dealer = Dealer.objects.get(user__email="ismail.mosa.ibrahim@gmail.com")
|
||||
vin = f"{vin[:-4]}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}{random.randint(0, 9)}"
|
||||
result = decodevin(vin)
|
||||
make = CarMake.objects.get(name=result["maker"])
|
||||
@ -39,14 +35,13 @@ def run():
|
||||
year = result["modelYear"]
|
||||
serie = random.choice(model.carserie_set.all())
|
||||
trim = random.choice(serie.cartrim_set.all())
|
||||
vendor = random.choice(vendors)
|
||||
|
||||
car = Car.objects.create(
|
||||
vin=vin,
|
||||
id_car_make=make,
|
||||
id_car_model=model,
|
||||
id_car_serie=serie,
|
||||
id_car_trim=trim,
|
||||
vendor=vendor,
|
||||
year=(int(year) or 2025),
|
||||
receiving_date=datetime.datetime.now(),
|
||||
dealer=dealer,
|
||||
|
||||
3
templates/vendors/vendors_list.html
vendored
3
templates/vendors/vendors_list.html
vendored
@ -130,8 +130,7 @@
|
||||
<td class="align-middle white-space-nowrap text-end pe-0 ps-4">
|
||||
<div class="btn-reveal-trigger position-static">
|
||||
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button>
|
||||
<div class="dropdown-menu dropdown-menu-end py-2">
|
||||
<a href="{% url 'vendor_update' vendor.pk %}" class="dropdown-item text-success-dark">
|
||||
<div class="dropdown-menu dropdown-menu-end py-2"><a href="" class="dropdown-item text-success-dark">
|
||||
{% trans "Edit" %}
|
||||
</a>
|
||||
<div class="dropdown-divider"></div><button class="dropdown-item text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">{% trans "Delete" %}</button>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user