haikal/inventory/signals.py
2024-12-25 17:28:03 +00:00

285 lines
9.8 KiB
Python

from random import randint
from django.db.models.signals import post_save, post_delete, pre_delete, pre_save
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 . import models
# @receiver(post_save, sender=models.SaleQuotation)
# def link_quotation_to_entity(sender, instance, created, **kwargs):
# if created:
# # Get the corresponding Django Ledger entity for the dealer
# entity = EntityModel.objects.get(name=instance.dealer.get_root_dealer.name)
# instance.entity = entity
# instance.save()
# @receiver(pre_delete, sender=models.Dealer)
# def remove_user_account(sender, instance, **kwargs):
# user = instance.user
# if user:
# user.delete()
@receiver(post_save, sender=models.Car)
def create_car_location(sender, instance, created, **kwargs):
"""
Signal to create or update the car's location when a car instance is saved.
"""
try:
if created:
if instance.dealer is None:
raise ValueError(
f"Cannot create CarLocation for car {instance.vin}: dealer is missing."
)
models.CarLocation.objects.create(
car=instance,
owner=instance.dealer,
showroom=instance.dealer,
description=f"Initial location set for car {instance.vin}.",
)
print("Car Location created")
except Exception as e:
print(f"Failed to create CarLocation for car {instance.vin}: {e}")
@receiver(post_save, sender=models.CarReservation)
def update_car_status_on_reservation(sender, instance, created, **kwargs):
if created:
car = instance.car
car.status = models.CarStatusChoices.RESERVED
car.save()
@receiver(post_delete, sender=models.CarReservation)
def update_car_status_on_reservation_delete(sender, instance, **kwargs):
car = instance.car
if not car.is_reserved():
car.status = models.CarStatusChoices.AVAILABLE
car.save()
# Create Entity
@receiver(post_save, sender=models.Dealer)
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 = EntityModel.create_entity(
name=entity_name,
admin=root_dealer.user,
use_accrual_method=True,
fy_start_month=1,
)
if entity:
instance.entity = entity
instance.save()
coa = entity.create_chart_of_accounts(
assign_as_default=True, commit=True, coa_name=_(f"{entity_name}-COA")
)
if 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,
)
entity.create_account(
coa_model=coa,
code="20100",
role="lia_cl_acc_payable",
name=_("Accounts Payable"),
balance_type="credit",
active=True,
)
entity.create_account(
coa_model=coa,
code="40100",
role="in_operational",
name=_("Sales Income"),
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,
)
# uom_name = _("Unit")
# unit_abbr = _("U")
#
# entity.create_uom(uom_name, unit_abbr)
# Create Vendor
@receiver(post_save, sender=models.Vendor)
def create_ledger_vendor(sender, instance, created, **kwargs):
if created:
entity = EntityModel.objects.filter(name=instance.dealer.name).first()
entity.create_vendor(
name=instance.name,
vendor_number=instance.crn,
address_1=instance.address,
phone=instance.phone_number,
tax_id_number=instance.vrn,
active=True,
hidden=False,
additional_info={
"arabic_name": instance.arabic_name,
"contact_person": instance.contact_person,
},
)
print(f"VendorModel created for Vendor: {instance.name}")
@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()
name = f"{instance.first_name} {instance.middle_name} {instance.last_name}"
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}")
# 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}")
#
#
# # update price - CarFinance
# @receiver(post_save, sender=CarFinance)
# def update_item_model_cost(sender, instance, created, **kwargs):
#
# ItemModel.objects.filter(item_id=instance.car.vin).update(
# inventory_received_value=instance.cost_price,
# default_amount=instance.cost_price,
# )
# print(f"Inventory item updated with CarFinance data for Car: {instance.car}")
# @receiver(pre_save, sender=models.SaleQuotation)
# def update_quotation_status(sender, instance, **kwargs):
# if instance.valid_until and timezone.now() > instance.valid_until:
# instance.status = 'expired'
# # instance.total_price = instance.calculate_total_price()
#
#
# @receiver(post_save, sender=models.Payment)
# def update_status_on_payment(sender, instance, created, **kwargs):
# if created:
# quotation = instance.sale_quotation
# total_payments = sum(payment.amount for payment in quotation.payments.all())
# if total_payments >= quotation.amount:
# quotation.status = 'completed'
# # SalesInvoice.objects.create(sales_order=order)
# elif total_payments > 0:
# quotation.status = 'partially_paid'
# else:
# quotation.status = 'pending'
# quotation.save()