866 lines
32 KiB
Python
866 lines
32 KiB
Python
from decimal import Decimal
|
|
from django.db.models.signals import post_save, post_delete, pre_delete, pre_save
|
|
from .utils import to_dict
|
|
from django.dispatch import receiver
|
|
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,
|
|
VendorModel,
|
|
EstimateModel, CustomerModel
|
|
)
|
|
from . import models
|
|
from django.utils.timezone import now
|
|
|
|
User = get_user_model()
|
|
|
|
# @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=User)
|
|
# def create_dealer(instance, created, *args, **kwargs):
|
|
# if created:
|
|
# if not instance.dealer:
|
|
#
|
|
# 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()
|
|
|
|
|
|
# check with marwan
|
|
@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}")
|
|
|
|
# Create Entity
|
|
@receiver(post_save, sender=models.Dealer)
|
|
def create_ledger_entity(sender, instance, created, **kwargs):
|
|
if created:
|
|
entity_name = instance.user.dealer.name
|
|
entity = EntityModel.create_entity(
|
|
name=entity_name,
|
|
admin=instance.user,
|
|
use_accrual_method=False,
|
|
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:
|
|
# Create unit of measures
|
|
entity.create_uom(name="Unit", unit_abbr="unit")
|
|
for u in models.UnitOfMeasure.choices:
|
|
entity.create_uom(name=u[1], unit_abbr=u[0])
|
|
|
|
# Cash Account
|
|
asset_ca_cash = entity.create_account(
|
|
coa_model=coa,
|
|
code="1101",
|
|
role=roles.ASSET_CA_CASH,
|
|
name=_("Cash"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
asset_ca_cash.role_default = True
|
|
asset_ca_cash.save()
|
|
|
|
# Accounts Receivable Account
|
|
asset_ca_receivables = entity.create_account(
|
|
coa_model=coa,
|
|
code="1102",
|
|
role=roles.ASSET_CA_RECEIVABLES,
|
|
name=_("Accounts Receivable"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
asset_ca_receivables.role_default = True
|
|
asset_ca_receivables.save()
|
|
|
|
# Inventory Account
|
|
asset_ca_inventory = entity.create_account(
|
|
coa_model=coa,
|
|
code="1103",
|
|
role=roles.ASSET_CA_INVENTORY,
|
|
name=_("Inventory"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
asset_ca_inventory.role_default = True
|
|
asset_ca_inventory.save()
|
|
|
|
|
|
# Prepaid Expenses Account
|
|
asset_ca_prepaid = entity.create_account(
|
|
coa_model=coa,
|
|
code="1104",
|
|
role=roles.ASSET_CA_PREPAID,
|
|
name=_("Prepaid Expenses"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
asset_ca_prepaid.role_default = True
|
|
asset_ca_prepaid.save()
|
|
|
|
# Employee Expenses Account
|
|
asset_ca_prepaid_employee = entity.create_account(
|
|
coa_model=coa,
|
|
code="1105",
|
|
role=roles.ASSET_CA_PREPAID,
|
|
name=_("Employee Advance"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
|
|
# VAT Payable Account
|
|
liability_ltl_vat_receivable = entity.create_account(
|
|
coa_model=coa,
|
|
code="1106",
|
|
role=roles.ASSET_CA_RECEIVABLES,
|
|
name=_("VAT Receivable"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Buildings Accumulated Depreciation Account
|
|
asset_ppe_buildings_accum_depreciation = entity.create_account(
|
|
coa_model=coa,
|
|
code="1201",
|
|
role=roles.ASSET_PPE_BUILDINGS_ACCUM_DEPRECIATION,
|
|
name=_("Buildings - Accum. Depreciation"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
asset_ppe_buildings_accum_depreciation.role_default = True
|
|
asset_ppe_buildings_accum_depreciation.save()
|
|
|
|
# intangible Account
|
|
asset_lti_land_intangable = entity.create_account(
|
|
coa_model=coa,
|
|
code="1202",
|
|
role=roles.ASSET_INTANGIBLE_ASSETS,
|
|
name=_("Intangible Assets"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
asset_lti_land_intangable.role_default = True
|
|
asset_lti_land_intangable.save()
|
|
|
|
# investment property Account
|
|
asset_lti_land_investment = entity.create_account(
|
|
coa_model=coa,
|
|
code="1204",
|
|
role=roles.ASSET_LTI_SECURITIES,
|
|
name=_("Investments"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
asset_lti_land_investment.role_default = True
|
|
asset_lti_land_investment.save()
|
|
|
|
# # Notes Receivable Account
|
|
# asset_lti_notes_receivable = entity.create_account(
|
|
# coa_model=coa,
|
|
# code="1201",
|
|
# role=roles.ASSET_LTI_NOTES_RECEIVABLE,
|
|
# name=_("Notes Receivable"),
|
|
# balance_type="debit",
|
|
# active=True,
|
|
# )
|
|
# asset_lti_notes_receivable.role_default = True
|
|
# asset_lti_notes_receivable.save()
|
|
|
|
# # Land Account
|
|
# asset_lti_land = entity.create_account(
|
|
# coa_model=coa,
|
|
# code="1202",
|
|
# role=roles.ASSET_LTI_LAND,
|
|
# name=_("Land"),
|
|
# balance_type="debit",
|
|
# active=True,
|
|
# )
|
|
# asset_lti_land.role_default = True
|
|
# asset_lti_land.save()
|
|
|
|
|
|
# Buildings Account
|
|
asset_ppe_buildings = entity.create_account(
|
|
coa_model=coa,
|
|
code="1301",
|
|
role=roles.ASSET_PPE_BUILDINGS,
|
|
name=_("Buildings"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
asset_ppe_buildings.role_default = True
|
|
asset_ppe_buildings.save()
|
|
|
|
|
|
|
|
# Accounts Payable Account
|
|
liability_cl_acc_payable = entity.create_account(
|
|
coa_model=coa,
|
|
code="2101",
|
|
role=roles.LIABILITY_CL_ACC_PAYABLE,
|
|
name=_("Accounts Payable"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
liability_cl_acc_payable.role_default = True
|
|
liability_cl_acc_payable.save()
|
|
|
|
# Deferred Revenue Account
|
|
liability_cl_def_rev = entity.create_account(
|
|
coa_model=coa,
|
|
code="2103",
|
|
role=roles.LIABILITY_CL_DEFERRED_REVENUE,
|
|
name=_("Deferred Revenue"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
liability_cl_def_rev.role_default = True
|
|
liability_cl_def_rev.save()
|
|
|
|
# Wages Payable Account
|
|
liability_cl_wages_payable = entity.create_account(
|
|
coa_model=coa,
|
|
code="2102",
|
|
role=roles.LIABILITY_CL_WAGES_PAYABLE,
|
|
name=_("Wages Payable"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
liability_cl_wages_payable.role_default = True
|
|
liability_cl_wages_payable.save()
|
|
|
|
# Long-Term Notes Payable Account
|
|
liability_ltl_notes_payable = entity.create_account(
|
|
coa_model=coa,
|
|
code="2201",
|
|
role=roles.LIABILITY_LTL_NOTES_PAYABLE,
|
|
name=_("Long-Term Notes Payable"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
liability_ltl_notes_payable.role_default = True
|
|
liability_ltl_notes_payable.save()
|
|
|
|
# VAT Payable Account
|
|
liability_ltl_vat_payable = entity.create_account(
|
|
coa_model=coa,
|
|
code="2106",
|
|
role=roles.LIABILITY_CL_OTHER,
|
|
name=_("VAT Payable"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
|
|
# taxes Payable Account
|
|
liability_ltl_taxes_payable = entity.create_account(
|
|
coa_model=coa,
|
|
code="2107",
|
|
role=roles.LIABILITY_CL_OTHER,
|
|
name=_("Taxes Payable"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
|
|
# social insurance Payable Account
|
|
liability_ltl_social_insurance_payable = entity.create_account(
|
|
coa_model=coa,
|
|
code="2108",
|
|
role=roles.LIABILITY_LTL_NOTES_PAYABLE,
|
|
name=_("Social Insurance Payable"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
|
|
# End of Service Benefits
|
|
entity.create_account(coa_model=coa, code="2202", role=roles.LIABILITY_LTL_NOTES_PAYABLE, name=_("End of Service Benefits"), balance_type="credit", active=True)
|
|
|
|
# Mortgage Payable Account
|
|
liability_ltl_mortgage_payable = entity.create_account(
|
|
coa_model=coa,
|
|
code="2203",
|
|
role=roles.LIABILITY_LTL_MORTGAGE_PAYABLE,
|
|
name=_("Mortgage Payable"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
liability_ltl_mortgage_payable.role_default = True
|
|
liability_ltl_mortgage_payable.save()
|
|
|
|
# Capital
|
|
equity_capital = entity.create_account(coa_model=coa, code="3101", role=roles.EQUITY_CAPITAL, name=_("Registered Capital"), balance_type="credit", active=True)
|
|
equity_capital.role_default = True
|
|
equity_capital.save()
|
|
entity.create_account(coa_model=coa, code="3102", role=roles.EQUITY_CAPITAL, name=_("Additional Paid-In Capital"), balance_type="credit", active=True)
|
|
|
|
# Other Equity
|
|
other_equity = entity.create_account(coa_model=coa, code="3201", role=roles.EQUITY_COMMON_STOCK, name=_("Opening Balances"), balance_type="credit", active=True)
|
|
other_equity.role_default = True
|
|
other_equity.save()
|
|
|
|
# Reserves
|
|
reserve = entity.create_account(coa_model=coa, code="3301", role=roles.EQUITY_ADJUSTMENT, name=_("Statutory Reserve"), balance_type="credit", active=True)
|
|
reserve.role_default = True
|
|
reserve.save()
|
|
entity.create_account(coa_model=coa, code="3302", role=roles.EQUITY_ADJUSTMENT, name=_("Foreign Currency Translation Reserve"), balance_type="credit", active=True)
|
|
|
|
# Retained Earnings Account
|
|
equity_retained_earnings = entity.create_account(
|
|
coa_model=coa,
|
|
code="3401",
|
|
role=roles.EQUITY_PREFERRED_STOCK,
|
|
name=_("Operating Profits and Losses"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
equity_retained_earnings.role_default = True
|
|
equity_retained_earnings.save()
|
|
|
|
equity_retained_earnings_losses = entity.create_account(
|
|
coa_model=coa,
|
|
code="3402",
|
|
role=roles.EQUITY_PREFERRED_STOCK,
|
|
name=_("Retained Earnings (or Losses)"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
|
|
# Sales Revenue Account
|
|
income_operational = entity.create_account(
|
|
coa_model=coa,
|
|
code="4101",
|
|
role=roles.INCOME_OPERATIONAL,
|
|
name=_("Sales Revenue"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
income_operational.role_default = True
|
|
income_operational.save()
|
|
|
|
# Interest Income Account
|
|
income_interest = entity.create_account(
|
|
coa_model=coa,
|
|
code="4102",
|
|
role=roles.INCOME_INTEREST,
|
|
name=_("Interest Income"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
income_interest.role_default = True
|
|
income_interest.save()
|
|
|
|
# Uneared Income Account
|
|
income_unearned = entity.create_account(
|
|
coa_model=coa,
|
|
code="4103",
|
|
role=roles.INCOME_OTHER,
|
|
name=_("Unearned Income"),
|
|
balance_type="credit",
|
|
active=True,
|
|
)
|
|
|
|
# Operating Revenues
|
|
entity.create_account(coa_model=coa, code="4104", role=roles.INCOME_OPERATIONAL, name=_("Sales/Service Revenue"), balance_type="credit", active=True)
|
|
|
|
#Non-Operating Revenues
|
|
entity.create_account(coa_model=coa, code="4201", role=roles.INCOME_OTHER, name=_("Non-Operating Revenues"), balance_type="credit", active=True)
|
|
|
|
|
|
# Cost of Goods Sold (COGS) Account
|
|
expense_cogs = entity.create_account(
|
|
coa_model=coa,
|
|
code="5101",
|
|
role=roles.COGS,
|
|
name=_("Cost of Goods Sold"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
expense_cogs.role_default = True
|
|
expense_cogs.save()
|
|
|
|
|
|
# accrued Expenses Account
|
|
expense_cogs = entity.create_account(
|
|
coa_model=coa,
|
|
code="6117",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Accrued Expenses"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# accrued salaries Account
|
|
expense_cogs = entity.create_account(
|
|
coa_model=coa,
|
|
code="6118",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Accrued Salaries"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Rent Expense Account
|
|
expense_rent = entity.create_account(
|
|
coa_model=coa,
|
|
code="6102",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Rent Expense"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
# expense_rent.role_default = True
|
|
# expense_rent.save()
|
|
|
|
# Salaries and Administrative Fees
|
|
expense_salaries = entity.create_account(
|
|
coa_model=coa,
|
|
code="6103",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Salaries and Administrative Fees"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Medical Insurance
|
|
expense_medical_insurance = entity.create_account(
|
|
coa_model=coa,
|
|
code="6104",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Medical Insurance"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Marketing and Advertising Expenses
|
|
expense_marketing = entity.create_account(
|
|
coa_model=coa,
|
|
code="6105",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Marketing and Advertising Expenses"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Commissions and Incentives
|
|
expense_commissions = entity.create_account(
|
|
coa_model=coa,
|
|
code="6106",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Commissions and Incentives"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Travel Tickets
|
|
expense_travel = entity.create_account(
|
|
coa_model=coa,
|
|
code="6107",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Travel Tickets"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Social Insurance
|
|
expense_other = entity.create_account(
|
|
coa_model=coa,
|
|
code="6108",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Social Insurance"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Government Fees
|
|
expense_other = entity.create_account(
|
|
coa_model=coa,
|
|
code="6109",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Government Fees"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Fees and Subscriptions
|
|
expense_other = entity.create_account(
|
|
coa_model=coa,
|
|
code="6110",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Fees and Subscriptions"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Office Services Expenses
|
|
expense_other = entity.create_account(
|
|
coa_model=coa,
|
|
code="6111",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Office Services Expenses"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Office Supplies and Printing
|
|
expense_other = entity.create_account(
|
|
coa_model=coa,
|
|
code="6112",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Office Supplies and Printing"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Hospitality Expenses
|
|
expense_other = entity.create_account(
|
|
coa_model=coa,
|
|
code="6113",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Hospitality Expenses"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Bank Commissions
|
|
expense_other = entity.create_account(
|
|
coa_model=coa,
|
|
code="6114",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Bank Commissions"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Other Expenses
|
|
expense_other = entity.create_account(
|
|
coa_model=coa,
|
|
code="6115",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Other Expenses"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# Transportation Expenses
|
|
expense_other = entity.create_account(
|
|
coa_model=coa,
|
|
code="6116",
|
|
role=roles.EXPENSE_OPERATIONAL,
|
|
name=_("Transportation Expenses"),
|
|
balance_type="debit",
|
|
active=True,
|
|
)
|
|
|
|
# 5.1 Direct Costs
|
|
entity.create_account(coa_model=coa, code="6201", role=roles.EXPENSE_OPERATIONAL, name=_("Cost of Goods Sold"), balance_type="debit", active=True)
|
|
entity.create_account(coa_model=coa, code="6202", role=roles.EXPENSE_OPERATIONAL, name=_("Salaries and Wages"), balance_type="debit", active=True)
|
|
entity.create_account(coa_model=coa, code="6203", role=roles.EXPENSE_OPERATIONAL, name=_("Sales Commissions"), balance_type="debit", active=True)
|
|
entity.create_account(coa_model=coa, code="6204", role=roles.EXPENSE_OPERATIONAL, name=_("Shipping and Customs Clearance"), balance_type="debit", active=True)
|
|
|
|
# 5.3 Non-Operating Expenses
|
|
entity.create_account(coa_model=coa, code="6301", role=roles.EXPENSE_OTHER, name=_("Zakat"), balance_type="debit", active=True)
|
|
entity.create_account(coa_model=coa, code="6302", role=roles.EXPENSE_OTHER, name=_("Taxes"), balance_type="debit", active=True)
|
|
entity.create_account(coa_model=coa, code="6303", role=roles.EXPENSE_OTHER, name=_("Foreign Currency Translation"), balance_type="debit", active=True)
|
|
entity.create_account(coa_model=coa, code="6304", role=roles.EXPENSE_OTHER, name=_("Interest Expenses"), balance_type="debit", active=True)
|
|
|
|
|
|
|
|
# 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(
|
|
vendor_model_kwargs={
|
|
"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.CustomerModel)
|
|
def create_customer_user(sender, instance, created, **kwargs):
|
|
if created:
|
|
user = User.objects.create(
|
|
username=instance.email,
|
|
email=instance.email,
|
|
first_name=instance.additional_info["customer_info"].get("first_name", ""),
|
|
last_name=instance.additional_info["customer_info"].get("last_name", ""),
|
|
)
|
|
user.set_unusable_password()
|
|
user.save()
|
|
instance.user = user
|
|
instance.save()
|
|
|
|
|
|
# Create Item
|
|
@receiver(post_save, sender=models.Car)
|
|
def create_item_model(sender, instance, created, **kwargs):
|
|
entity = instance.dealer.entity
|
|
if created:
|
|
coa = entity.get_default_coa()
|
|
uom = entity.get_uom_all().get(name="Unit")
|
|
|
|
if not entity.get_items_all().filter(name=instance.vin).exists():
|
|
product = entity.create_item_product(
|
|
name=instance.vin,
|
|
item_type=ItemModel.ITEM_TYPE_MATERIAL,
|
|
uom_model=uom,
|
|
coa_model=coa,
|
|
)
|
|
product.additional_info = {}
|
|
product.save()
|
|
|
|
product = entity.get_items_all().filter(name=instance.vin).first()
|
|
product.additional_info.update({'car_info': instance.to_dict()})
|
|
product.save()
|
|
|
|
# # update price - CarFinance
|
|
@receiver(post_save, sender=models.CarFinance)
|
|
def update_item_model_cost(sender, instance, created, **kwargs):
|
|
entity = instance.car.dealer.entity
|
|
|
|
product = entity.get_items_all().filter(name=instance.car.vin).first()
|
|
|
|
product.default_amount = instance.selling_price
|
|
if not isinstance(product.additional_info, dict):
|
|
product.additional_info = {}
|
|
product.additional_info.update({"car_finance":instance.to_dict()})
|
|
product.additional_info.update({"additional_services": [service.to_dict() for service in instance.additional_services.all()]})
|
|
product.save()
|
|
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()
|
|
|
|
@receiver(post_save, sender=models.CarColors)
|
|
def update_car_when_color_changed(sender, instance, **kwargs):
|
|
car = instance.car
|
|
car.save()
|
|
|
|
@receiver(post_save, sender=models.Opportunity)
|
|
def notify_staff_on_deal_stage_change(sender, instance, **kwargs):
|
|
if instance.pk:
|
|
previous = models.Opportunity.objects.get(pk=instance.pk)
|
|
if previous.stage != instance.stage:
|
|
message = f"Opportunity '{instance.pk}' status changed from {previous.stage} to {instance.stage}."
|
|
models.Notification.objects.create(
|
|
staff=instance.created_by, message=message
|
|
)
|
|
|
|
|
|
# @receiver(post_save, sender=models.Opportunity)
|
|
# def log_opportunity_creation(sender, instance, created, **kwargs):
|
|
# if created:
|
|
# models.OpportunityLog.objects.create(
|
|
# opportunity=instance,
|
|
# action="create",
|
|
# user=instance.created_by,
|
|
# details=f"Opportunity '{instance.deal_name}' was created.",
|
|
# )
|
|
|
|
|
|
# @receiver(pre_save, sender=models.Opportunity)
|
|
# def log_opportunity_update(sender, instance, **kwargs):
|
|
# if instance.pk:
|
|
# previous = models.Opportunity.objects.get(pk=instance.pk)
|
|
# if previous.stage != instance.deal_status:
|
|
# models.OpportunityLog.objects.create(
|
|
# opportunity=instance,
|
|
# action="status_change",
|
|
# user=instance.created_by,
|
|
# old_status=previous.deal_status,
|
|
# new_status=instance.deal_status,
|
|
# details=f"Status changed from {previous.deal_status} to {instance.deal_status}.",
|
|
# )
|
|
# else:
|
|
# models.OpportunityLog.objects.create(
|
|
# opportunity=instance,
|
|
# action="update",
|
|
# user=instance.created_by,
|
|
# details=f"Opportunity '{instance.deal_name}' was updated.",
|
|
# )
|
|
|
|
|
|
@receiver(post_save, sender=models.AdditionalServices)
|
|
def create_item_service(sender, instance, created, **kwargs):
|
|
if created:
|
|
entity = instance.dealer.entity
|
|
uom = entity.get_uom_all().get(unit_abbr=instance.uom)
|
|
cogs = entity.get_all_accounts().get(role=roles.COGS)
|
|
|
|
service_model = ItemModel.objects.create(
|
|
name=instance.name,
|
|
uom=uom,
|
|
default_amount=instance.price,
|
|
entity=entity,
|
|
is_product_or_service=True,
|
|
sold_as_unit=True,
|
|
is_active=True,
|
|
item_role="service",
|
|
for_inventory=False,
|
|
cogs_account=cogs,
|
|
)
|
|
instance.item = service_model
|
|
instance.save()
|
|
|
|
|
|
@receiver(post_save, sender=models.Lead)
|
|
def track_lead_status_change(sender, instance, **kwargs):
|
|
if instance.pk: # Ensure the instance is being updated, not created
|
|
try:
|
|
old_lead = models.Lead.objects.get(pk=instance.pk)
|
|
if old_lead.status != instance.status: # Check if status has changed
|
|
models.LeadStatusHistory.objects.create(
|
|
lead=instance,
|
|
old_status=old_lead.status,
|
|
new_status=instance.status,
|
|
changed_by=instance.staff # Assuming the assigned staff made the change
|
|
)
|
|
except models.Lead.DoesNotExist:
|
|
pass # Ignore if the lead doesn't exist (e.g., during initial creation)
|
|
|
|
|
|
@receiver(post_save, sender=models.Lead)
|
|
def notify_assigned_staff(sender, instance, created, **kwargs):
|
|
if instance.staff: # Check if the lead is assigned
|
|
models.Notification.objects.create(
|
|
user=instance.staff.user,
|
|
message=f"You have been assigned a new lead: {instance.full_name}."
|
|
)
|
|
|
|
|
|
@receiver(post_save, sender=models.CarReservation)
|
|
def update_car_status_on_reservation_create(sender, instance, created, **kwargs):
|
|
"""
|
|
Signal to update the car status to 'reserved' when a reservation is created.
|
|
"""
|
|
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):
|
|
"""
|
|
Signal to update the car status to 'available' when a reservation is deleted.
|
|
"""
|
|
car = instance.car
|
|
# Check if there are no active reservations for the car
|
|
if not car.reservations.filter(reserved_until__gt=now()).exists():
|
|
car.status = models.CarStatusChoices.AVAILABLE
|
|
car.save()
|
|
|
|
@receiver(post_save, sender=models.CarReservation)
|
|
def update_car_status_on_reservation_update(sender, instance, **kwargs):
|
|
"""
|
|
Signal to update the car status based on the reservation's active status.
|
|
"""
|
|
car = instance.car
|
|
if instance.is_active:
|
|
car.status = models.CarStatusChoices.RESERVED
|
|
else:
|
|
if not car.reservations.filter(reserved_until__gt=now()).exists():
|
|
car.status = models.CarStatusChoices.AVAILABLE
|
|
car.save()
|
|
|
|
# @receiver(post_save, sender=EstimateModel)
|
|
# def update_estimate_status(sender, instance,created, **kwargs):
|
|
|
|
# items = instance.get_itemtxs_data()[0].all()
|
|
# total = sum([Decimal(item.item_model.additional_info['car_finance']["selling_price"]) * Decimal(item.ce_quantity) for item in items])
|
|
|
|
@receiver(post_save, sender=models.Schedule)
|
|
def create_activity_on_schedule_creation(sender, instance, created, **kwargs):
|
|
if created:
|
|
models.Activity.objects.create(
|
|
content_object=instance,
|
|
activity_type='Schedule Created',
|
|
created_by=instance.scheduled_by.user,
|
|
notes=f"New schedule created for {instance.purpose} with {instance.lead.full_name} on {instance.scheduled_at}."
|
|
)
|
|
|
|
|