Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend
This commit is contained in:
commit
cf378f1a1e
@ -146,6 +146,7 @@ class StaffForm(forms.ModelForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
model = Staff
|
model = Staff
|
||||||
fields = ["first_name","last_name", "arabic_name", "phone_number", "address", "logo", "group"]
|
fields = ["first_name","last_name", "arabic_name", "phone_number", "address", "logo", "group"]
|
||||||
|
|
||||||
|
|||||||
22
inventory/hooks.py
Normal file
22
inventory/hooks.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import logging
|
||||||
|
from inventory.models import Dealer
|
||||||
|
from .utils import get_accounts_data,create_account
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def check_create_coa_accounts(task):
|
||||||
|
logger.info("Checking if all accounts are created")
|
||||||
|
instance_id = task.args[0]
|
||||||
|
instance = Dealer.objects.get(pk=instance_id)
|
||||||
|
entity = instance.entity
|
||||||
|
coa = entity.get_default_coa()
|
||||||
|
|
||||||
|
for account_data in get_accounts_data():
|
||||||
|
if entity.get_all_accounts().filter(code=account_data["code"]).exists():
|
||||||
|
logger.info(f"Default account already exists: {account_data['code']}")
|
||||||
|
continue
|
||||||
|
logger.info(f"Default account does not exist: {account_data['code']}")
|
||||||
|
create_account(entity, coa, account_data)
|
||||||
|
|
||||||
|
def print_results(task):
|
||||||
|
print(task.kwargs.get("dealer"))
|
||||||
9
inventory/management/commands/run1.py
Normal file
9
inventory/management/commands/run1.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django_q.tasks import async_task, result
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
def handle(self, *args, **kwargs):
|
||||||
|
from inventory.models import Dealer
|
||||||
|
instance = Dealer.objects.first()
|
||||||
|
async_task(name="test_task_test",func="inventory.tasks.test_task",dealer=instance,hook="inventory.hooks.print_results")
|
||||||
@ -2,6 +2,7 @@ import uuid
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
|
from inventory.validators import SaudiPhoneNumberValidator
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
@ -1305,7 +1306,7 @@ class Dealer(models.Model, LocalizedNameMixin):
|
|||||||
)
|
)
|
||||||
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
||||||
name = models.CharField(max_length=255, verbose_name=_("English Name"))
|
name = models.CharField(max_length=255, verbose_name=_("English Name"))
|
||||||
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
||||||
address = models.CharField(
|
address = models.CharField(
|
||||||
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
||||||
)
|
)
|
||||||
@ -1431,7 +1432,7 @@ class Staff(models.Model):
|
|||||||
last_name = models.CharField(max_length=255, verbose_name=_("Last Name"))
|
last_name = models.CharField(max_length=255, verbose_name=_("Last Name"))
|
||||||
|
|
||||||
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
||||||
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
||||||
staff_type = models.CharField(
|
staff_type = models.CharField(
|
||||||
choices=StaffTypes.choices, max_length=255, verbose_name=_("Staff Type")
|
choices=StaffTypes.choices, max_length=255, verbose_name=_("Staff Type")
|
||||||
)
|
)
|
||||||
@ -1825,7 +1826,7 @@ class Organization(models.Model, LocalizedNameMixin):
|
|||||||
)
|
)
|
||||||
vrn = models.CharField(max_length=15, verbose_name=_("VAT Registration Number"))
|
vrn = models.CharField(max_length=15, verbose_name=_("VAT Registration Number"))
|
||||||
email = models.EmailField(verbose_name=_("Email"))
|
email = models.EmailField(verbose_name=_("Email"))
|
||||||
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
||||||
address = models.CharField(
|
address = models.CharField(
|
||||||
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
||||||
)
|
)
|
||||||
@ -1959,7 +1960,7 @@ class Representative(models.Model, LocalizedNameMixin):
|
|||||||
id_number = models.CharField(
|
id_number = models.CharField(
|
||||||
max_length=10, unique=True, verbose_name=_("ID Number")
|
max_length=10, unique=True, verbose_name=_("ID Number")
|
||||||
)
|
)
|
||||||
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
||||||
email = models.EmailField(max_length=255, verbose_name=_("Email Address"))
|
email = models.EmailField(max_length=255, verbose_name=_("Email Address"))
|
||||||
address = models.CharField(
|
address = models.CharField(
|
||||||
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
||||||
@ -1979,7 +1980,7 @@ class Lead(models.Model):
|
|||||||
first_name = models.CharField(max_length=50, verbose_name=_("First Name"))
|
first_name = models.CharField(max_length=50, verbose_name=_("First Name"))
|
||||||
last_name = models.CharField(max_length=50, verbose_name=_("Last Name"))
|
last_name = models.CharField(max_length=50, verbose_name=_("Last Name"))
|
||||||
email = models.EmailField(verbose_name=_("Email"))
|
email = models.EmailField(verbose_name=_("Email"))
|
||||||
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
||||||
address = models.CharField(
|
address = models.CharField(
|
||||||
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
||||||
)
|
)
|
||||||
@ -2667,7 +2668,7 @@ class Vendor(models.Model, LocalizedNameMixin):
|
|||||||
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
||||||
name = models.CharField(max_length=255, verbose_name=_("English Name"))
|
name = models.CharField(max_length=255, verbose_name=_("English Name"))
|
||||||
contact_person = models.CharField(max_length=100, verbose_name=_("Contact Person"))
|
contact_person = models.CharField(max_length=100, verbose_name=_("Contact Person"))
|
||||||
phone_number = PhoneNumberField(region="SA", verbose_name=_("Phone Number"))
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
||||||
email = models.EmailField(max_length=255, verbose_name=_("Email Address"))
|
email = models.EmailField(max_length=255, verbose_name=_("Email Address"))
|
||||||
address = models.CharField(max_length=200, verbose_name=_("Address"))
|
address = models.CharField(max_length=200, verbose_name=_("Address"))
|
||||||
logo = models.ImageField(
|
logo = models.ImageField(
|
||||||
|
|||||||
@ -178,7 +178,8 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
|||||||
entity.create_uom(name=u[1], unit_abbr=u[0])
|
entity.create_uom(name=u[1], unit_abbr=u[0])
|
||||||
|
|
||||||
# Create COA accounts, background task
|
# Create COA accounts, background task
|
||||||
async_task(create_coa_accounts, instance)
|
async_task(name="create_coa_accounts",func=create_coa_accounts,dealer_pk=instance.pk,hook="inventory.hooks.check_create_coa_accounts")
|
||||||
|
# async_task('inventory.tasks.check_create_coa_accounts', instance, schedule_type='O', schedule_time=timedelta(seconds=20))
|
||||||
|
|
||||||
# create_settings(instance.pk)
|
# create_settings(instance.pk)
|
||||||
# create_accounts_for_make(instance.pk)
|
# create_accounts_for_make(instance.pk)
|
||||||
|
|||||||
1585
inventory/tasks.py
1585
inventory/tasks.py
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import secrets
|
import secrets
|
||||||
|
import logging
|
||||||
import datetime
|
import datetime
|
||||||
import requests
|
import requests
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
@ -27,7 +28,7 @@ from django.contrib.contenttypes.models import ContentType
|
|||||||
from django_ledger.models.transactions import TransactionModel
|
from django_ledger.models.transactions import TransactionModel
|
||||||
from django_ledger.models.journal_entry import JournalEntryModel
|
from django_ledger.models.journal_entry import JournalEntryModel
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
import logging
|
from django_q.models import Schedule as DjangoQSchedule
|
||||||
from django_ledger.io import roles
|
from django_ledger.io import roles
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -223,13 +224,21 @@ def reserve_car(car, request):
|
|||||||
:return: Redirection to the car's detail page.
|
:return: Redirection to the car's detail page.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
reserved_until = timezone.now() + timezone.timedelta(hours=24)
|
# reserved_until = timezone.now() + timezone.timedelta(hours=24)
|
||||||
models.CarReservation.objects.create(
|
reserved_until = timezone.now() + timezone.timedelta(minutes=1)
|
||||||
|
reservation = models.CarReservation.objects.create(
|
||||||
car=car, reserved_by=request.user, reserved_until=reserved_until
|
car=car, reserved_by=request.user, reserved_until=reserved_until
|
||||||
)
|
)
|
||||||
car.status = models.CarStatusChoices.RESERVED
|
car.status = models.CarStatusChoices.RESERVED
|
||||||
car.save()
|
car.save()
|
||||||
# --- Logging for Success ---
|
# --- Logging for Success ---
|
||||||
|
DjangoQSchedule.objects.create(
|
||||||
|
name=f"remove_reservation_for_car_with_vin_{car.vin}",
|
||||||
|
func='inventory.tasks.remove_reservation_by_id',
|
||||||
|
args=reservation.pk,
|
||||||
|
schedule_type=DjangoQSchedule.ONCE,
|
||||||
|
next_run=reserved_until,
|
||||||
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Car {car.pk} ('{car.id_car_make} {car.id_car_model}') reserved successfully "
|
f"Car {car.pk} ('{car.id_car_make} {car.id_car_model}') reserved successfully "
|
||||||
f"by user {request.user}. "
|
f"by user {request.user}. "
|
||||||
@ -1288,7 +1297,7 @@ def get_finance_data(estimate,dealer):
|
|||||||
)
|
)
|
||||||
discount = extra_info.data.get("discount", 0)
|
discount = extra_info.data.get("discount", 0)
|
||||||
discount = Decimal(discount)
|
discount = Decimal(discount)
|
||||||
|
|
||||||
additional_services = car.get_additional_services()
|
additional_services = car.get_additional_services()
|
||||||
discounted_price=(Decimal(car.marked_price) - discount)
|
discounted_price=(Decimal(car.marked_price) - discount)
|
||||||
vat_amount = discounted_price * vat.rate
|
vat_amount = discounted_price * vat.rate
|
||||||
@ -1915,3 +1924,416 @@ def handle_payment(request, order):
|
|||||||
|
|
||||||
# def get_user_quota(user):
|
# def get_user_quota(user):
|
||||||
# return user.dealer.quota
|
# return user.dealer.quota
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_accounts_data():
|
||||||
|
return [
|
||||||
|
# Current Assets (must start with 1)
|
||||||
|
{
|
||||||
|
"code": "1010",
|
||||||
|
"name": "Cash on Hand",
|
||||||
|
"role": roles.ASSET_CA_CASH,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for ASSET_CA_CASH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1020",
|
||||||
|
"name": "Bank",
|
||||||
|
"role": roles.ASSET_CA_CASH,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1030",
|
||||||
|
"name": "Accounts Receivable",
|
||||||
|
"role": roles.ASSET_CA_RECEIVABLES,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for ASSET_CA_RECEIVABLES
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1040",
|
||||||
|
"name": "Inventory (Cars)",
|
||||||
|
"role": roles.ASSET_CA_INVENTORY,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for ASSET_CA_INVENTORY
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1045",
|
||||||
|
"name": "Spare Parts Inventory",
|
||||||
|
"role": roles.ASSET_CA_INVENTORY,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1050",
|
||||||
|
"name": "Employee Advances",
|
||||||
|
"role": roles.ASSET_CA_RECEIVABLES,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1060",
|
||||||
|
"name": "Prepaid Expenses",
|
||||||
|
"role": roles.ASSET_CA_PREPAID,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for ASSET_CA_PREPAID
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1070",
|
||||||
|
"name": "Notes Receivable",
|
||||||
|
"role": roles.ASSET_LTI_NOTES_RECEIVABLE,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for ASSET_LTI_NOTES_RECEIVABLE
|
||||||
|
},
|
||||||
|
# Fixed Assets (must also start with 1)
|
||||||
|
{
|
||||||
|
"code": "1110",
|
||||||
|
"name": "Lands",
|
||||||
|
"role": roles.ASSET_LTI_LAND,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for ASSET_LTI_LAND
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1111",
|
||||||
|
"name": "Buildings",
|
||||||
|
"role": roles.ASSET_PPE_BUILDINGS,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for ASSET_PPE_BUILDINGS
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1112",
|
||||||
|
"name": "Company Vehicles",
|
||||||
|
"role": roles.ASSET_PPE_EQUIPMENT,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for ASSET_PPE_EQUIPMENT
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1113",
|
||||||
|
"name": "Equipment & Tools",
|
||||||
|
"role": roles.ASSET_PPE_EQUIPMENT,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1114",
|
||||||
|
"name": "Furniture & Fixtures",
|
||||||
|
"role": roles.ASSET_PPE_EQUIPMENT,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1115",
|
||||||
|
"name": "Other Fixed Assets",
|
||||||
|
"role": roles.ASSET_PPE_EQUIPMENT,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1120",
|
||||||
|
"name": "Long-term Investments",
|
||||||
|
"role": roles.ASSET_LTI_SECURITIES,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for ASSET_LTI_SECURITIES
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "1130",
|
||||||
|
"name": "Intangible Assets",
|
||||||
|
"role": roles.ASSET_INTANGIBLE_ASSETS,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for ASSET_INTANGIBLE_ASSETS
|
||||||
|
},
|
||||||
|
# Current Liabilities (must start with 2)
|
||||||
|
{
|
||||||
|
"code": "2010",
|
||||||
|
"name": "Accounts Payable",
|
||||||
|
"role": roles.LIABILITY_CL_ACC_PAYABLE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": True,
|
||||||
|
"default": True, # Default for LIABILITY_CL_ACC_PAYABLE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "2020",
|
||||||
|
"name": "Notes Payable",
|
||||||
|
"role": roles.LIABILITY_CL_ST_NOTES_PAYABLE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for LIABILITY_CL_ST_NOTES_PAYABLE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "2030",
|
||||||
|
"name": "Short-term Loans",
|
||||||
|
"role": roles.LIABILITY_CL_ST_NOTES_PAYABLE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "2040",
|
||||||
|
"name": "Employee Payables",
|
||||||
|
"role": roles.LIABILITY_CL_WAGES_PAYABLE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for LIABILITY_CL_WAGES_PAYABLE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "2050",
|
||||||
|
"name": "Accrued Expenses",
|
||||||
|
"role": roles.LIABILITY_CL_OTHER,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for LIABILITY_CL_OTHER
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "2060",
|
||||||
|
"name": "Accrued Taxes",
|
||||||
|
"role": roles.LIABILITY_CL_TAXES_PAYABLE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False, # Default for LIABILITY_CL_TAXES_PAYABLE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "2070",
|
||||||
|
"name": "Provisions",
|
||||||
|
"role": roles.LIABILITY_CL_OTHER,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
# Long-term Liabilities (must also start with 2)
|
||||||
|
{
|
||||||
|
"code": "2103",
|
||||||
|
"name": "Deferred Revenue",
|
||||||
|
"role": roles.LIABILITY_CL_DEFERRED_REVENUE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for LIABILITY_CL_DEFERRED_REVENUE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "2200",
|
||||||
|
"name": "Tax Payable",
|
||||||
|
"role": roles.LIABILITY_CL_TAXES_PAYABLE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "2210",
|
||||||
|
"name": "Long-term Bank Loans",
|
||||||
|
"role": roles.LIABILITY_LTL_NOTES_PAYABLE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for LIABILITY_LTL_NOTES_PAYABLE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "2220",
|
||||||
|
"name": "Lease Liabilities",
|
||||||
|
"role": roles.LIABILITY_LTL_NOTES_PAYABLE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "2230",
|
||||||
|
"name": "Other Long-term Liabilities",
|
||||||
|
"role": roles.LIABILITY_LTL_NOTES_PAYABLE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
# Equity (must start with 3)
|
||||||
|
{
|
||||||
|
"code": "3010",
|
||||||
|
"name": "Capital",
|
||||||
|
"role": roles.EQUITY_CAPITAL,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": True,
|
||||||
|
"default": True, # Default for EQUITY_CAPITAL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "3020",
|
||||||
|
"name": "Statutory Reserve",
|
||||||
|
"role": roles.EQUITY_ADJUSTMENT,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for EQUITY_ADJUSTMENT
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "3030",
|
||||||
|
"name": "Retained Earnings",
|
||||||
|
"role": roles.EQUITY_ADJUSTMENT,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "3040",
|
||||||
|
"name": "Profit & Loss for the Period",
|
||||||
|
"role": roles.EQUITY_ADJUSTMENT,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
# Revenue (must start with 4)
|
||||||
|
{
|
||||||
|
"code": "4010",
|
||||||
|
"name": "Car Sales",
|
||||||
|
"role": roles.INCOME_OPERATIONAL,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": True,
|
||||||
|
"default": True, # Default for INCOME_OPERATIONAL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "4020",
|
||||||
|
"name": "After-Sales Services",
|
||||||
|
"role": roles.INCOME_OPERATIONAL,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "4030",
|
||||||
|
"name": "Car Rental Income",
|
||||||
|
"role": roles.INCOME_PASSIVE,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for INCOME_PASSIVE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "4040",
|
||||||
|
"name": "Other Income",
|
||||||
|
"role": roles.INCOME_OTHER,
|
||||||
|
"balance_type": roles.CREDIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for INCOME_OTHER
|
||||||
|
},
|
||||||
|
# Expenses (must start with 5 for COGS, 6 for others)
|
||||||
|
{
|
||||||
|
"code": "5010",
|
||||||
|
"name": "Cost of Goods Sold",
|
||||||
|
"role": roles.COGS,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": True,
|
||||||
|
"default": True, # Default for COGS
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "5015",
|
||||||
|
"name": "Spare Parts Cost Consumed",
|
||||||
|
"role": roles.COGS,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "6010",
|
||||||
|
"name": "Salaries & Wages",
|
||||||
|
"role": roles.EXPENSE_OPERATIONAL,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for EXPENSE_OPERATIONAL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "6020",
|
||||||
|
"name": "Rent",
|
||||||
|
"role": roles.EXPENSE_OPERATIONAL,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "6030",
|
||||||
|
"name": "Utilities",
|
||||||
|
"role": roles.EXPENSE_OPERATIONAL,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "6040",
|
||||||
|
"name": "Advertising & Marketing",
|
||||||
|
"role": roles.EXPENSE_OPERATIONAL,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "6050",
|
||||||
|
"name": "Maintenance",
|
||||||
|
"role": roles.EXPENSE_OPERATIONAL,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "6060",
|
||||||
|
"name": "Operating Expenses",
|
||||||
|
"role": roles.EXPENSE_OPERATIONAL,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "6070",
|
||||||
|
"name": "Depreciation",
|
||||||
|
"role": roles.EXPENSE_DEPRECIATION,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for EXPENSE_DEPRECIATION
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "6080",
|
||||||
|
"name": "Fees & Taxes",
|
||||||
|
"role": roles.EXPENSE_OPERATIONAL,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "6090",
|
||||||
|
"name": "Bank Charges",
|
||||||
|
"role": roles.EXPENSE_OPERATIONAL,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "6100",
|
||||||
|
"name": "Other Expenses",
|
||||||
|
"role": roles.EXPENSE_OTHER,
|
||||||
|
"balance_type": roles.DEBIT,
|
||||||
|
"locked": False,
|
||||||
|
"default": True, # Default for EXPENSE_OTHER
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
def create_account(entity, coa, account_data):
|
||||||
|
try:
|
||||||
|
account = entity.create_account(
|
||||||
|
coa_model=coa,
|
||||||
|
code=account_data["code"],
|
||||||
|
name=account_data["name"],
|
||||||
|
role=account_data["role"],
|
||||||
|
balance_type=_(account_data["balance_type"]),
|
||||||
|
active=True,
|
||||||
|
)
|
||||||
|
account.role_default = account_data["default"]
|
||||||
|
account.save()
|
||||||
|
logger.info(f"Created default account: {account}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error creating default account: {account_data['code']}, {e}")
|
||||||
Loading…
x
Reference in New Issue
Block a user