clean base V1-update
This commit is contained in:
parent
8556078b59
commit
18dd7829d9
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,6 +15,7 @@ car*.json
|
||||
car_inventory/settings.py
|
||||
car_inventory/__pycache__
|
||||
scripts/dsrpipe.py
|
||||
def_venv
|
||||
# Backup files #
|
||||
*.bak
|
||||
|
||||
|
||||
28
Dockerfile
28
Dockerfile
@ -4,18 +4,23 @@ FROM python:3.11.11-slim-bullseye
|
||||
# Set the working directory to /app
|
||||
WORKDIR /app
|
||||
|
||||
# Install the dependencies
|
||||
RUN apt-get update && apt-get install -y libgl1
|
||||
RUN apt-get update && apt-get install -y libglib2.0-dev
|
||||
RUN apt-get update && apt-get install -y libzbar0
|
||||
RUN apt-get update && apt-get install -y cmake build-essential xmlsec1 libxmlsec1-dev
|
||||
RUN apt-get install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl
|
||||
|
||||
COPY requirements_dev.txt .
|
||||
|
||||
RUN pip install --upgrade pip
|
||||
|
||||
RUN pip install -r requirements_dev.txt
|
||||
# Create a new user and group
|
||||
RUN groupadd -r appgroup
|
||||
RUN useradd -r -g appgroup -G appgroup -m -d /app -s /bin/false appuser
|
||||
|
||||
# Copy the requirements file
|
||||
COPY requirements.txt .
|
||||
|
||||
# Install the dependencies
|
||||
RUN pip install -r requirements.txt
|
||||
RUN apt-get update && apt-get install -y libgl1
|
||||
RUN apt-get update && apt-get install -y libglib2.0-dev
|
||||
RUN apt-get update && apt-get install -y libzbar0
|
||||
|
||||
# Copy the application code
|
||||
COPY . .
|
||||
@ -23,17 +28,12 @@ COPY . .
|
||||
# Expose the port
|
||||
EXPOSE 8000
|
||||
|
||||
# Copy the entrypoint script
|
||||
COPY entrypoint.sh /app/entrypoint.sh
|
||||
|
||||
# Make the script executable
|
||||
RUN chmod +x /app/entrypoint.sh
|
||||
RUN chmod +x *.sh
|
||||
|
||||
# Change ownership of the app directory to the new user
|
||||
RUN chown -R appuser:appgroup /app
|
||||
|
||||
RUN find /app -path "*/migrations/*.py" -not -name "__init__.py" -delete
|
||||
RUN find /app -path "*/migrations/*.pyc" -delete
|
||||
|
||||
# Set the entrypoint to execute the script as the new user
|
||||
ENTRYPOINT ["sh", "-c", "python3 manage.py makemigrations && python3 manage.py migrate && python3 manage.py collectstatic --no-input && python3 manage.py runserver 0.0.0.0:8000"]
|
||||
ENTRYPOINT ["sh", "-c", "python3 manage.py runserver 0.0.0.0:8000"]
|
||||
22
api/views.py
22
api/views.py
@ -11,7 +11,7 @@ from django.shortcuts import render
|
||||
from inventory.utils import get_user_type
|
||||
from . import models, serializers
|
||||
from .services import get_car_data, get_from_cardatabase
|
||||
from rest_framework.authtoken.models import Token
|
||||
# from rest_framework.authtoken.models import Token
|
||||
from django.utils.decorators import method_decorator
|
||||
from inventory import models as inventory_models
|
||||
|
||||
@ -20,20 +20,20 @@ from inventory import models as inventory_models
|
||||
class LoginView(APIView):
|
||||
permission_classes = [permissions.AllowAny,]
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
username = request.data.get('username')
|
||||
password = request.data.get('password')
|
||||
# def post(self, request, *args, **kwargs):
|
||||
# username = request.data.get('username')
|
||||
# password = request.data.get('password')
|
||||
|
||||
if username is None or password is None:
|
||||
return Response({'error': 'Please provide both username and password.'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
# if username is None or password is None:
|
||||
# return Response({'error': 'Please provide both username and password.'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
user = authenticate(username=username, password=password)
|
||||
# user = authenticate(username=username, password=password)
|
||||
|
||||
if not user:
|
||||
return Response({'error': 'Invalid credentials.'}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
# if not user:
|
||||
# return Response({'error': 'Invalid credentials.'}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
token, created = Token.objects.get_or_create(user=user)
|
||||
return Response({'token': token.key, 'user_id': user.id, 'username': user.username}, status=status.HTTP_200_OK)
|
||||
# token, created = Token.objects.get_or_create(user=user)
|
||||
# return Response({'token': token.key, 'user_id': user.id, 'username': user.username}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class CarVINViewSet(APIView):
|
||||
|
||||
21
apply_initial_migrations.sh
Executable file
21
apply_initial_migrations.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
echo "Delete Old Migrations"
|
||||
find ./inventory -type f -iname "000*.py" -delete
|
||||
|
||||
echo "Delete Old Cache"
|
||||
find ./car_inventory -type d -iname "__pycache__"|xargs rm -rf
|
||||
find ./inventory -type d -iname "__pycache__"|xargs rm -rf
|
||||
|
||||
echo "Apply Base Migrate"
|
||||
python3 manage.py migrate
|
||||
|
||||
echo "Apply Make Migratinos"
|
||||
python3 manage.py makemigrations
|
||||
|
||||
echo "Apply Final Migrate"
|
||||
python3 manage.py migrate
|
||||
|
||||
echo "Collect Static"
|
||||
python3 manage.py collectstatic --no-input
|
||||
|
||||
echo "Done"
|
||||
@ -4,16 +4,16 @@ from django.conf.urls.static import static
|
||||
from django.conf import settings
|
||||
from django.conf.urls.i18n import i18n_patterns
|
||||
from inventory import views
|
||||
import debug_toolbar
|
||||
from schema_graph.views import Schema
|
||||
# import debug_toolbar
|
||||
# from schema_graph.views import Schema
|
||||
# from two_factor.urls import urlpatterns as tf_urls
|
||||
|
||||
urlpatterns = [
|
||||
path('__debug__/', include(debug_toolbar.urls)),
|
||||
path('silk/', include('silk.urls', namespace='silk')),
|
||||
# path('__debug__/', include(debug_toolbar.urls)),
|
||||
# path('silk/', include('silk.urls', namespace='silk')),
|
||||
path('api-auth/', include('rest_framework.urls')),
|
||||
path('api/', include('api.urls')),
|
||||
path('dj-rest-auth/', include('dj_rest_auth.urls')),
|
||||
# path('api/', include('api.urls')),
|
||||
# path('dj-rest-auth/', include('dj_rest_auth.urls')),
|
||||
|
||||
|
||||
]
|
||||
@ -21,13 +21,13 @@ urlpatterns += i18n_patterns(
|
||||
path('admin/', admin.site.urls),
|
||||
path('switch_language/', views.switch_language, name='switch_language'),
|
||||
path('accounts/', include('allauth.urls')),
|
||||
path('prometheus/', include('django_prometheus.urls')),
|
||||
# path('prometheus/', include('django_prometheus.urls')),
|
||||
path('', include('inventory.urls')),
|
||||
path('ledger/', include('django_ledger.urls', namespace='django_ledger')),
|
||||
path("haikalbot/", include("haikalbot.urls")),
|
||||
# path("haikalbot/", include("haikalbot.urls")),
|
||||
path('appointment/', include('appointment.urls')),
|
||||
path('plans/', include('plans.urls')),
|
||||
path("schema/", Schema.as_view()),
|
||||
# path("schema/", Schema.as_view()),
|
||||
# path('', include(tf_urls)),
|
||||
)
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "car_inventory.settings")
|
||||
django.setup()
|
||||
|
||||
from inventory.models import *
|
||||
from rich import print
|
||||
# from rich import print
|
||||
import random
|
||||
import datetime
|
||||
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.20 on 2025-03-20 17:15
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ChatLog',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('user_message', models.TextField()),
|
||||
('chatbot_response', models.TextField()),
|
||||
('timestamp', models.DateTimeField(auto_now_add=True)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@ -1,22 +0,0 @@
|
||||
# Generated by Django 4.2.20 on 2025-03-20 17:15
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0001_initial'),
|
||||
('haikalbot', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='chatlog',
|
||||
name='dealer',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='chatlogs', to='inventory.dealer'),
|
||||
),
|
||||
]
|
||||
@ -1,9 +1,9 @@
|
||||
from appointment.models import Appointment
|
||||
# from appointment.models import Appointment
|
||||
from django.contrib import admin
|
||||
from . import models
|
||||
from django_ledger import models as ledger_models
|
||||
from django_pdf_actions.actions import export_to_pdf_landscape, export_to_pdf_portrait
|
||||
from appointment import models as appointment_models
|
||||
# from django_pdf_actions.actions import export_to_pdf_landscape, export_to_pdf_portrait
|
||||
# from appointment import models as appointment_models
|
||||
from import_export.admin import ExportMixin
|
||||
from import_export.resources import ModelResource
|
||||
|
||||
@ -72,14 +72,14 @@ admin.site.register(models.UserActivityLog)
|
||||
@admin.register(models.Car)
|
||||
class CarAdmin(admin.ModelAdmin):
|
||||
search_fields = ('vin',)
|
||||
actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
||||
# actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
||||
|
||||
@admin.register(models.CarMake)
|
||||
class CarMakeAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'arabic_name', 'is_sa_import')
|
||||
search_fields = ('name', 'arabic_name')
|
||||
list_filter = ('is_sa_import', 'name',)
|
||||
actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
||||
# actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Car Make"
|
||||
@ -152,9 +152,9 @@ class CarOptionAdmin(admin.ModelAdmin):
|
||||
# search_fields = ('user__username', 'action')
|
||||
# list_filter = ('timestamp',)
|
||||
|
||||
@admin.register(ledger_models.ItemTransactionModel)
|
||||
class ItemTransactionModelAdmin(admin.ModelAdmin):
|
||||
# @admin.register(ledger_models.ItemTransactionModel)
|
||||
# class ItemTransactionModelAdmin(admin.ModelAdmin):
|
||||
|
||||
actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
||||
# actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
||||
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -1,19 +1,12 @@
|
||||
from django.core.cache import cache
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import Group
|
||||
from appointment.models import Appointment, Service, StaffMember
|
||||
from django.urls import reverse
|
||||
from django_countries.widgets import CountrySelectWidget
|
||||
from django_ledger.models import CustomerModel
|
||||
from appointment.models import Service
|
||||
from phonenumber_field.formfields import PhoneNumberField
|
||||
from django.core.validators import MinLengthValidator
|
||||
from django.core.validators import RegexValidator
|
||||
from django import forms
|
||||
from django.contrib.auth import get_user_model
|
||||
from phonenumber_field.phonenumber import PhoneNumber
|
||||
from .models import CustomGroup, Status, Stage
|
||||
from .mixins import AddClassMixin
|
||||
from django.forms.models import inlineformset_factory
|
||||
from django_ledger.forms.invoice import (
|
||||
InvoiceModelCreateForm as InvoiceModelCreateFormBase,
|
||||
)
|
||||
@ -21,17 +14,14 @@ from django_ledger.forms.estimate import (
|
||||
EstimateModelCreateForm as EstimateModelCreateFormBase,
|
||||
)
|
||||
|
||||
# from django_ledger.forms.ledger import LedgerModelCreateForm as LedgerModelCreateFormBase
|
||||
from django_ledger.forms.bill import BillModelCreateForm as BillModelCreateFormBase
|
||||
from django_ledger.forms.journal_entry import JournalEntryModelCreateForm as JournalEntryModelCreateFormBase
|
||||
|
||||
from .models import (
|
||||
Dealer,
|
||||
DealersMake,
|
||||
# Branch,
|
||||
Vendor,
|
||||
Schedule,
|
||||
Customer,
|
||||
Car,
|
||||
CarTransfer,
|
||||
CarFinance,
|
||||
@ -40,16 +30,11 @@ from .models import (
|
||||
CarColors,
|
||||
ExteriorColors,
|
||||
InteriorColors,
|
||||
# SaleQuotation,
|
||||
CarLocation,
|
||||
|
||||
Representative,
|
||||
|
||||
# SaleQuotationCar,
|
||||
AdditionalServices,
|
||||
Staff,
|
||||
Opportunity,
|
||||
|
||||
Lead,
|
||||
Activity,
|
||||
Notes,
|
||||
@ -65,7 +50,6 @@ from django.forms import (
|
||||
)
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
import django_tables2 as tables
|
||||
from django.forms import formset_factory
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
@ -90,14 +74,6 @@ class AdditionalServiceForm(forms.ModelForm):
|
||||
model = AdditionalServices
|
||||
fields = ["name", "price", "description", "taxable", "uom"]
|
||||
|
||||
|
||||
# class PaymentForm(forms.ModelForm):
|
||||
# invoice = forms.ModelChoiceField(queryset=InvoiceModel.objects.all(),label="Invoice", required=True)
|
||||
# class Meta:
|
||||
# model = Payment
|
||||
# fields = ['amount','payment_method', 'reference_number']
|
||||
|
||||
|
||||
class StaffForm(forms.ModelForm):
|
||||
"""
|
||||
Represents a form for managing Staff entities, including associated user email updates
|
||||
@ -128,22 +104,6 @@ class StaffForm(forms.ModelForm):
|
||||
model = Staff
|
||||
fields = ["name", "arabic_name", "phone_number", "staff_type"]
|
||||
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# user_instance = kwargs.get("instance")
|
||||
# if user_instance and user_instance.user:
|
||||
# initial = kwargs.setdefault("initial", {})
|
||||
# initial["email"] = user_instance.user.email
|
||||
# super().__init__(*args, **kwargs)
|
||||
#
|
||||
# def save(self, commit=True):
|
||||
# user_instance = super().save(commit=False)
|
||||
# user = user_instance.user
|
||||
# user.email = self.cleaned_data["email"]
|
||||
# if commit:
|
||||
# user.save()
|
||||
# user_instance.save()
|
||||
# return user_instance
|
||||
|
||||
|
||||
# Dealer Form
|
||||
class DealerForm(forms.ModelForm):
|
||||
@ -258,28 +218,6 @@ class OrganizationForm(CustomerForm):
|
||||
logo = forms.ImageField(required=False)
|
||||
|
||||
|
||||
# class CustomerForm(forms.ModelForm, AddClassMixin):
|
||||
# class Meta:
|
||||
# model = Customer
|
||||
# fields = [
|
||||
# "title",
|
||||
# "first_name",
|
||||
# "middle_name",
|
||||
# "last_name",
|
||||
# "gender",
|
||||
# "dob",
|
||||
# "email",
|
||||
# "national_id",
|
||||
|
||||
# "phone_number",
|
||||
# "address",
|
||||
# ]
|
||||
# widgets = {
|
||||
# "phone_number": forms.TextInput(attrs={"class": "phone"}),
|
||||
# "dob": forms.DateInput(attrs={"type": "date"}),
|
||||
# }
|
||||
|
||||
|
||||
class CarForm(
|
||||
forms.ModelForm,
|
||||
AddClassMixin,
|
||||
@ -338,10 +276,6 @@ class CarForm(
|
||||
self.fields["vendor"].queryset = ledger_models.VendorModel.objects.filter(
|
||||
active=True
|
||||
)
|
||||
# queryset = self.fields["vendor"].queryset
|
||||
# self.fields["vendor"].choices = [
|
||||
# (obj.pk, obj.get_local_name()) for obj in queryset
|
||||
# ]
|
||||
|
||||
|
||||
class CarUpdateForm(forms.ModelForm, AddClassMixin):
|
||||
@ -382,19 +316,6 @@ class CarUpdateForm(forms.ModelForm, AddClassMixin):
|
||||
dealer = kwargs.pop("dealer", None)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# if dealer and 'branch' in self.fields:
|
||||
# self.fields['branch'].queryset = Branch.objects.filter(dealer=dealer)
|
||||
# self.fields['branch'].choices = [
|
||||
# (branch.id, branch.get_local_name()) for branch in self.fields['branch'].queryset
|
||||
# ]
|
||||
|
||||
# if "vendor" in self.fields:
|
||||
# queryset = self.fields["vendor"].queryset
|
||||
# if queryset:
|
||||
# self.fields["vendor"].choices = [
|
||||
# (vendor.id, vendor.get_local_name()) for vendor in queryset
|
||||
# ]
|
||||
|
||||
|
||||
class CarFinanceForm(forms.ModelForm):
|
||||
"""
|
||||
@ -424,13 +345,6 @@ class CarFinanceForm(forms.ModelForm):
|
||||
"additional_services",
|
||||
]
|
||||
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# super().__init__(*args, **kwargs)
|
||||
# if self.instance.pk:
|
||||
# self.fields[
|
||||
# "additional_finances"
|
||||
# ].initial = self.instance.additional_services.all()
|
||||
|
||||
def save(self, commit=True):
|
||||
instance = super().save()
|
||||
instance.additional_services.set(self.cleaned_data["additional_finances"])
|
||||
@ -617,43 +531,6 @@ class CarColorsForm(forms.ModelForm):
|
||||
return cleaned_data
|
||||
|
||||
|
||||
# class QuotationForm(forms.ModelForm):
|
||||
# cars = ModelMultipleChoiceField(
|
||||
# queryset=Car.objects.none(), # Default empty queryset
|
||||
# widget=forms.CheckboxSelectMultiple,
|
||||
# label="Select Cars",
|
||||
# )
|
||||
#
|
||||
# class Meta:
|
||||
# model = SaleQuotation
|
||||
# fields = ["customer", "cars", "remarks"]
|
||||
#
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# super().__init__(*args, **kwargs)
|
||||
#
|
||||
# self.fields["cars"].queryset = Car.objects.filter(
|
||||
# finances__isnull=False
|
||||
# ).distinct()
|
||||
|
||||
|
||||
# class OrganizationForm(forms.ModelForm):
|
||||
# class Meta:
|
||||
# model = Organization
|
||||
# fields = [
|
||||
# "name",
|
||||
# "arabic_name",
|
||||
# "crn",
|
||||
# "vrn",
|
||||
# "phone_number",
|
||||
# "address",
|
||||
# "logo",
|
||||
# ]
|
||||
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# dealer = kwargs.pop("dealer", None)
|
||||
# super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class RepresentativeForm(forms.ModelForm):
|
||||
"""
|
||||
A form for creating or updating instances of the Representative model.
|
||||
@ -958,17 +835,6 @@ class WizardForm3(forms.Form):
|
||||
},
|
||||
)
|
||||
|
||||
# def clean(self):
|
||||
# cleaned_data = super().clean()
|
||||
# password = cleaned_data.get("password")
|
||||
# confirm_password = cleaned_data.get("confirm_password")
|
||||
|
||||
# if password != confirm_password:
|
||||
# raise forms.ValidationError("Passwords do not match.")
|
||||
# else:
|
||||
# return cleaned_data
|
||||
|
||||
|
||||
class ItemForm(forms.Form):
|
||||
"""
|
||||
A form for handling item-related inputs in the application.
|
||||
@ -991,9 +857,6 @@ class ItemForm(forms.Form):
|
||||
validators=[MinLengthValidator(5)],
|
||||
)
|
||||
quantity = forms.DecimalField(label="Quantity", required=True)
|
||||
# unit = forms.DecimalField(label="Unit", required=True)
|
||||
# unit_cost = forms.DecimalField(label="Unit Cost", required=True)
|
||||
# unit_sales_price = forms.DecimalField(label="Unit Sales Price", required=True)
|
||||
|
||||
|
||||
class PaymentForm(forms.Form):
|
||||
@ -1278,10 +1141,6 @@ class BillModelCreateForm(BillModelCreateFormBase):
|
||||
self.fields["cash_account"].widget = forms.HiddenInput()
|
||||
self.fields["prepaid_account"].widget = forms.HiddenInput()
|
||||
self.fields["unearned_account"].widget = forms.HiddenInput()
|
||||
# self.fields["date_draft"] = forms.DateField(
|
||||
# widget=DateInput(attrs={"type": "date"})
|
||||
# )
|
||||
|
||||
|
||||
class SaleOrderForm(forms.ModelForm):
|
||||
"""
|
||||
@ -1568,6 +1427,3 @@ class JournalEntryModelCreateForm(JournalEntryModelCreateFormBase):
|
||||
:type bar: int
|
||||
"""
|
||||
pass
|
||||
|
||||
# class LedgerModelCreateForm(LedgerModelCreateFormBase):
|
||||
# pass
|
||||
Binary file not shown.
BIN
inventory/management/commands/__pycache__/.DS_Store
vendored
BIN
inventory/management/commands/__pycache__/.DS_Store
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -72,6 +72,7 @@ def normalize_name(name):
|
||||
|
||||
|
||||
def decodevin(vin):
|
||||
|
||||
"""
|
||||
Decodes a Vehicle Identification Number (VIN) using multiple decoding functions
|
||||
and returns the decoded result. This function attempts to decode the VIN using
|
||||
@ -159,4 +160,5 @@ def elm(vin):
|
||||
"model": response["data"]["model"],
|
||||
"modelYear": response["data"]["modelYear"],
|
||||
}
|
||||
print(data)
|
||||
return data if all([x for x in data.values()]) else None
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
from inventory.tasks import create_coa_accounts,create_accounts_for_make,create_settings
|
||||
from django.contrib.auth.models import Group
|
||||
from decimal import Decimal
|
||||
from django.db.models.signals import post_save, post_delete, pre_delete, pre_save
|
||||
@ -142,519 +143,10 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
||||
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 COA accounts, background task
|
||||
create_coa_accounts(instance.pk)
|
||||
create_settings(instance.pk)
|
||||
# create_accounts_for_make(instance.pk)
|
||||
|
||||
@receiver(post_save, sender=models.Dealer)
|
||||
def create_dealer_groups(sender, instance, created, **kwargs):
|
||||
@ -679,7 +171,6 @@ def create_dealer_groups(sender, instance, created, **kwargs):
|
||||
group_manager,created = models.CustomGroup.objects.get_or_create(name=group_name, dealer=instance, group=group)
|
||||
group_manager.set_default_permissions()
|
||||
instance.user.groups.add(group)
|
||||
|
||||
transaction.on_commit(create_groups)
|
||||
# Create Vendor
|
||||
@receiver(post_save, sender=models.Vendor)
|
||||
@ -1137,8 +628,6 @@ def create_dealer_settings(sender, instance, created, **kwargs):
|
||||
# current_staff_count = instance.dealer.staff.count()
|
||||
# if current_staff_count > allowed_users:
|
||||
# raise ValidationError(_("You have reached the maximum number of staff users allowed for your plan."))
|
||||
|
||||
|
||||
@receiver(post_save, sender=models.Dealer)
|
||||
def create_vat(sender, instance, created, **kwargs):
|
||||
"""
|
||||
@ -1176,21 +665,21 @@ def create_make_ledger_accounts(sender, instance, created, **kwargs):
|
||||
entity = instance.entity
|
||||
coa = entity.get_default_coa()
|
||||
|
||||
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():
|
||||
# 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}"
|
||||
# entity.create_account(
|
||||
# name=make.name,
|
||||
# code=code,
|
||||
# role=roles.ASSET_CA_RECEIVABLES,
|
||||
# coa_model=coa,
|
||||
# balance_type="credit",
|
||||
# active=True
|
||||
# )
|
||||
|
||||
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)
|
||||
|
||||
580
inventory/tasks.py
Normal file
580
inventory/tasks.py
Normal file
@ -0,0 +1,580 @@
|
||||
from django_ledger.io import roles
|
||||
from django.core.mail import send_mail
|
||||
from background_task import background
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from inventory.models import DealerSettings,CarMake,Dealer
|
||||
|
||||
@background
|
||||
def create_coa_accounts(pk):
|
||||
instance = Dealer.objects.get(pk=pk)
|
||||
entity = instance.entity
|
||||
coa = entity.get_default_coa()
|
||||
|
||||
# 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)
|
||||
|
||||
|
||||
# @background
|
||||
# def create_groups(instance):
|
||||
# group_names = ["Inventory", "Accountant", "Sales"]
|
||||
# for group_name in group_names:
|
||||
# group, _ = Group.objects.get_or_create(name=f"{instance.pk}_{group_name}")
|
||||
# group_manager,_ = CustomGroup.objects.get_or_create(name=group_name, dealer=instance, group=group)
|
||||
# group_manager.set_default_permissions()
|
||||
# instance.user.groups.add(group)
|
||||
|
||||
@background
|
||||
def create_settings(pk):
|
||||
instance = Dealer.objects.get(pk=pk)
|
||||
|
||||
DealerSettings.objects.create(
|
||||
dealer=instance,
|
||||
invoice_cash_account=instance.entity.get_all_accounts().filter(role=roles.ASSET_CA_CASH).first(),
|
||||
invoice_prepaid_account=instance.entity.get_all_accounts().filter(role=roles.ASSET_CA_RECEIVABLES).first(),
|
||||
invoice_unearned_account=instance.entity.get_all_accounts().filter(role=roles.LIABILITY_CL_DEFERRED_REVENUE).first(),
|
||||
bill_cash_account=instance.entity.get_all_accounts().filter(role=roles.ASSET_CA_CASH).first(),
|
||||
bill_prepaid_account=instance.entity.get_all_accounts().filter(role=roles.ASSET_CA_PREPAID).first(),
|
||||
bill_unearned_account=instance.entity.get_all_accounts().filter(role=roles.LIABILITY_CL_ACC_PAYABLE).first()
|
||||
)
|
||||
|
||||
@background
|
||||
def create_accounts_for_make(pk):
|
||||
instance = Dealer.objects.get(pk=pk)
|
||||
entity = instance.entity
|
||||
coa = entity.get_default_coa()
|
||||
|
||||
for make in CarMake.objects.all():
|
||||
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}"
|
||||
entity.create_account(
|
||||
name=make.name,
|
||||
code=code,
|
||||
role=roles.ASSET_CA_RECEIVABLES,
|
||||
coa_model=coa,
|
||||
balance_type="credit",
|
||||
active=True
|
||||
)
|
||||
|
||||
|
||||
|
||||
@background
|
||||
def send_email(from_, to_, subject, message):
|
||||
subject = subject
|
||||
message = message
|
||||
from_email = from_
|
||||
recipient_list = [to_]
|
||||
send_mail(subject, message, from_email, recipient_list)
|
||||
Binary file not shown.
@ -4,13 +4,15 @@ import json
|
||||
import logging
|
||||
import datetime
|
||||
import numpy as np
|
||||
from rich import print
|
||||
# from rich import print
|
||||
from random import randint
|
||||
from decimal import Decimal
|
||||
from calendar import month_name
|
||||
from pyzbar.pyzbar import decode
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
|
||||
#####################################################################
|
||||
|
||||
from django.db.models.deletion import RestrictedError
|
||||
|
||||
# Django
|
||||
@ -66,12 +68,27 @@ from django_ledger.views import (
|
||||
LedgerModelDeleteView as LedgerModelDeleteViewBase,
|
||||
LedgerModelCreateView as LedgerModelCreateViewBase
|
||||
)
|
||||
from django_ledger.views.invoice import (
|
||||
InvoiceModelDetailView as InvoiceModelDetailViewBase,
|
||||
)
|
||||
from django_ledger.views import (
|
||||
LedgerModelListView as LedgerModelListViewBase,
|
||||
JournalEntryModelTXSDetailView as JournalEntryModelTXSDetailViewBase,
|
||||
LedgerModelModelActionView as LedgerModelModelActionViewBase,
|
||||
LedgerModelDeleteView as LedgerModelDeleteViewBase,
|
||||
LedgerModelCreateView as LedgerModelCreateViewBase
|
||||
)
|
||||
from django_ledger.forms.account import AccountModelCreateForm, AccountModelUpdateForm
|
||||
from django_ledger.views.entity import (
|
||||
EntityModelDetailBaseView,
|
||||
EntityModelDetailHandlerView,
|
||||
)
|
||||
from django_ledger.forms.ledger import LedgerModelCreateForm
|
||||
from django_ledger.views.entity import (
|
||||
EntityModelDetailBaseView,
|
||||
EntityModelDetailHandlerView,
|
||||
)
|
||||
from django_ledger.forms.ledger import LedgerModelCreateForm
|
||||
from django_ledger.forms.item import (
|
||||
ExpenseItemCreateForm,
|
||||
ExpenseItemUpdateForm,
|
||||
@ -142,18 +159,20 @@ from .utils import (
|
||||
get_financial_values,
|
||||
get_item_transactions,
|
||||
reserve_car,
|
||||
send_email,
|
||||
# send_email,
|
||||
get_user_type,
|
||||
set_bill_payment,
|
||||
set_invoice_payment,
|
||||
CarTransfer,
|
||||
)
|
||||
from .tasks import send_email
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
|
||||
class Hash(Func):
|
||||
"""
|
||||
Represents a function used to compute a hash value.
|
||||
@ -570,7 +589,6 @@ class CarCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
|
||||
template_name = "inventory/car_form.html"
|
||||
permission_required = ["inventory.add_car"]
|
||||
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super().get_form(form_class)
|
||||
dealer = get_user_type(self.request)
|
||||
@ -1012,6 +1030,7 @@ class CarListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||
)
|
||||
return context
|
||||
|
||||
|
||||
def get_queryset(self):
|
||||
dealer = get_user_type(self.request)
|
||||
qs = super().get_queryset()
|
||||
@ -1048,6 +1067,7 @@ class CarListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||
return qs
|
||||
|
||||
|
||||
|
||||
@login_required
|
||||
def inventory_stats_view(request):
|
||||
"""
|
||||
@ -1463,6 +1483,7 @@ class CarTransferCreateView(LoginRequiredMixin, CreateView):
|
||||
return reverse_lazy("car_detail", kwargs={"pk": self.object.car.pk})
|
||||
|
||||
|
||||
|
||||
class CarTransferDetailView(LoginRequiredMixin, SuccessMessageMixin, DetailView):
|
||||
"""
|
||||
Provides a detailed view of a specific car transfer record.
|
||||
@ -1493,6 +1514,7 @@ class CarTransferDetailView(LoginRequiredMixin, SuccessMessageMixin, DetailView)
|
||||
return context
|
||||
|
||||
|
||||
|
||||
@login_required
|
||||
def car_transfer_approve(request, car_pk, transfer_pk):
|
||||
"""
|
||||
@ -1786,7 +1808,7 @@ class DealerDetailView(LoginRequiredMixin, DetailView):
|
||||
return models.Dealer.objects.annotate(
|
||||
staff_count=Coalesce(
|
||||
Count("staff"), Value(0)
|
||||
)
|
||||
) # Get the number of staff members
|
||||
)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
25
load_initial_data.sh
Executable file
25
load_initial_data.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
echo "Loading initial data"
|
||||
|
||||
echo "Loading carmake"
|
||||
python3 manage.py loaddata --app carmake carmake_backup.json
|
||||
|
||||
echo "Loading carmodel"
|
||||
python3 manage.py loaddata --app carmodel carmodel_backup.json
|
||||
|
||||
echo "Loading carserie"
|
||||
python3 manage.py loaddata --app carserie carserie_backup.json
|
||||
|
||||
echo "Loading cartrim"
|
||||
python3 manage.py loaddata --app cartrim cartrim_backup.json
|
||||
|
||||
echo "Loading caroption"
|
||||
python3 manage.py loaddata --app caroption caroption_backup.json
|
||||
|
||||
echo "Loading carequipment"
|
||||
python3 manage.py loaddata --app carequipment carequipment_backup.json
|
||||
|
||||
echo "Populating colors"
|
||||
python3 manage.py populate_colors
|
||||
|
||||
echo "Done"
|
||||
@ -4,7 +4,6 @@ aiohttp-retry
|
||||
aiosignal
|
||||
alabaster
|
||||
albucore
|
||||
albumentations
|
||||
annotated-types
|
||||
anyio
|
||||
arabic-reshaper
|
||||
@ -32,7 +31,6 @@ cryptography
|
||||
cycler
|
||||
Cython
|
||||
decorator
|
||||
defusedxml
|
||||
desert
|
||||
diff-match-patch
|
||||
dill
|
||||
@ -83,7 +81,6 @@ docopt
|
||||
docutils
|
||||
easy-thumbnails
|
||||
emoji
|
||||
et_xmlfile
|
||||
Faker
|
||||
filelock
|
||||
fire
|
||||
@ -117,8 +114,6 @@ kiwisolver
|
||||
lazy_loader
|
||||
ledger
|
||||
libretranslatepy
|
||||
lmdb
|
||||
lxml
|
||||
Markdown
|
||||
markdown-it-py
|
||||
MarkupSafe
|
||||
@ -195,9 +190,6 @@ rfc3986
|
||||
rich
|
||||
rubicon-objc
|
||||
sacremoses
|
||||
scikit-image
|
||||
scikit-learn
|
||||
scipy
|
||||
selenium
|
||||
sentencepiece
|
||||
shapely
|
||||
@ -211,7 +203,6 @@ sqlparse
|
||||
stanza
|
||||
stringzilla
|
||||
suds
|
||||
sympy
|
||||
tablib
|
||||
termcolor
|
||||
threadpoolctl
|
||||
|
||||
68
requirements_dev.txt
Normal file
68
requirements_dev.txt
Normal file
@ -0,0 +1,68 @@
|
||||
annotated-types==0.7.0
|
||||
anyio==4.9.0
|
||||
asgiref==3.8.1
|
||||
Babel==2.15.0
|
||||
certifi==2025.1.31
|
||||
cffi==1.17.1
|
||||
charset-normalizer==3.4.1
|
||||
colorama==0.4.6
|
||||
crispy-bootstrap5==2024.10
|
||||
cryptography==44.0.2
|
||||
diff-match-patch==20241021
|
||||
distro==1.9.0
|
||||
Django==5.1.7
|
||||
django-allauth==65.6.0
|
||||
django-appointment==3.8.0
|
||||
django-background-tasks==1.2.8
|
||||
django-bootstrap5==25.1
|
||||
django-countries==7.6.1
|
||||
django-crispy-forms==2.3
|
||||
django-extensions==3.2.3
|
||||
django-filter==25.1
|
||||
django-import-export==4.3.7
|
||||
django-ledger==0.7.6.1
|
||||
django-next-url-mixin==0.4.0
|
||||
django-ordered-model==3.7.4
|
||||
django-phonenumber-field==8.0.0
|
||||
django-plans==2.0.0
|
||||
django-sequences==3.0
|
||||
django-tables2==2.7.5
|
||||
django-treebeard==4.7.1
|
||||
djangorestframework==3.15.2
|
||||
docopt==0.6.2
|
||||
Faker==37.1.0
|
||||
fpdf==1.7.2
|
||||
h11==0.14.0
|
||||
httpcore==1.0.7
|
||||
httpx==0.28.1
|
||||
icalendar==6.1.2
|
||||
idna==3.10
|
||||
jiter==0.9.0
|
||||
jwt==1.3.1
|
||||
Markdown==3.7
|
||||
num2words==0.5.14
|
||||
numpy==2.2.4
|
||||
ofxtools==0.9.5
|
||||
openai==1.68.2
|
||||
opencv-python==4.11.0.86
|
||||
phonenumbers==8.13.42
|
||||
pillow==10.4.0
|
||||
pycparser==2.22
|
||||
pydantic==2.10.6
|
||||
pydantic_core==2.27.2
|
||||
python-dateutil==2.9.0.post0
|
||||
python-stdnum==1.20
|
||||
pytz==2025.2
|
||||
pyvin==0.0.2
|
||||
pyzbar==0.1.9
|
||||
requests==2.32.3
|
||||
six==1.17.0
|
||||
sniffio==1.3.1
|
||||
sqlparse==0.5.3
|
||||
suds==1.2.0
|
||||
swapper==1.3.0
|
||||
tablib==3.8.0
|
||||
tqdm==4.67.1
|
||||
typing_extensions==4.13.0
|
||||
tzdata==2025.2
|
||||
urllib3==2.3.0
|
||||
@ -1,6 +1,6 @@
|
||||
from inventory.models import *
|
||||
from django_ledger.models import VendorModel
|
||||
from rich import print
|
||||
# from rich import print
|
||||
import random
|
||||
import datetime
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ from django_ledger.models import (
|
||||
CustomerModel,
|
||||
EntityManagementModel,
|
||||
)
|
||||
from rich import print
|
||||
# from rich import print
|
||||
from datetime import date
|
||||
from inventory.models import (
|
||||
Car,
|
||||
@ -30,6 +30,7 @@ from inventory.models import (
|
||||
)
|
||||
from inventory.utils import CarFinanceCalculator
|
||||
from appointment.models import Appointment, AppointmentRequest, Service, StaffMember
|
||||
from appointment.models import Appointment, AppointmentRequest, Service, StaffMember
|
||||
from django.contrib.auth import get_user_model
|
||||
from django_ledger.io.io_core import get_localdate
|
||||
from datetime import datetime, timedelta
|
||||
@ -42,6 +43,8 @@ User = get_user_model()
|
||||
load_dotenv(".env")
|
||||
|
||||
|
||||
|
||||
|
||||
def run():
|
||||
# print(Service.objects.first().pk)
|
||||
# print(Appointment.objects.first().client)
|
||||
@ -142,6 +145,9 @@ def run():
|
||||
# info = item.additional_info["car_info"]
|
||||
# finance = item.additional_info["car_finance"]
|
||||
# print({"vin":info["make"],"mode":info["model"],"year":info["year"],"trim":info["trim"],"mileage":info["mileage"],"cost_price":finance["cost_price"],"selling_price":finance["selling_price"]})
|
||||
# info = item.additional_info["car_info"]
|
||||
# finance = item.additional_info["car_finance"]
|
||||
# print({"vin":info["make"],"mode":info["model"],"year":info["year"],"trim":info["trim"],"mileage":info["mileage"],"cost_price":finance["cost_price"],"selling_price":finance["selling_price"]})
|
||||
# for account in AccountModel.objects.all():
|
||||
# print(account.path)
|
||||
|
||||
@ -175,6 +181,7 @@ def run():
|
||||
# print(Permission.objects.filter(codename__icontains='customermodel').first().codename)
|
||||
# print(os.getenv("DJANGO_ALLOWED_HOSTS"))
|
||||
|
||||
|
||||
car_makes = CarMake.objects.all()[:10]
|
||||
|
||||
# Fetch the entity and COGS account
|
||||
@ -186,6 +193,8 @@ def run():
|
||||
for make in range(len(car_makes)): # Start from 0 to include all items
|
||||
# Generate a unique code
|
||||
|
||||
# Generate a unique code
|
||||
|
||||
# Create the account
|
||||
# account = AccountModel.objects.create(
|
||||
# name=car_makes[make].name,
|
||||
@ -211,10 +220,17 @@ def run():
|
||||
.order_by("-created")
|
||||
.first()
|
||||
)
|
||||
last_account = (
|
||||
entity.get_all_accounts()
|
||||
.filter(role=roles.COGS)
|
||||
.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}"
|
||||
code = f"{int(last_account.code) + 1}"
|
||||
|
||||
# account = entity.create_account(
|
||||
# name=car_makes[make].name,
|
||||
@ -240,12 +256,24 @@ def run():
|
||||
.order_by("-created")
|
||||
.first()
|
||||
)
|
||||
path = ""
|
||||
depth=3,
|
||||
)
|
||||
# 00060004001S
|
||||
last_account = (
|
||||
entity.get_all_accounts()
|
||||
.filter(role=roles.COGS)
|
||||
.order_by("-created")
|
||||
.first()
|
||||
)
|
||||
path = ""
|
||||
if len(last_account.code) == 12:
|
||||
path = f"{int(last_account.path)}{1:03d}"
|
||||
elif len(last_account.code) > 12:
|
||||
path = f"{int(last_account.path) + 1}"
|
||||
path = f"{int(last_account.path) + 1}"
|
||||
# account.path = path
|
||||
try:
|
||||
try:
|
||||
account = cogs.add_child(instance=account)
|
||||
account.move(cogs, pos="sorted-sibling")
|
||||
@ -254,6 +282,7 @@ def run():
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
|
||||
# form_data = {
|
||||
# 'name': car_makes[make].name,
|
||||
# 'code': code,
|
||||
@ -263,6 +292,7 @@ def run():
|
||||
# 'coa_model': coa # Ensure the COA model is included
|
||||
# }
|
||||
|
||||
|
||||
# Create the form instance with the data
|
||||
# create_form = AccountModelCreateForm(data=form_data, coa_model=coa)
|
||||
# # Validate and save the form
|
||||
@ -286,3 +316,26 @@ def run():
|
||||
# print(f"Account {account.name} created successfully.")
|
||||
# else:
|
||||
# print(f"Failed to create account {account.name}. Errors: {form.errors}")
|
||||
|
||||
# create_form = AccountModelCreateForm(data=form_data, coa_model=coa)
|
||||
# # Validate and save the form
|
||||
# if create_form.is_valid():
|
||||
# account = create_form.save(commit=False)
|
||||
# account.coa_model = coa # Set the entity for the account
|
||||
|
||||
# Add the account as a child of the COGS account
|
||||
# cogs.add_child(instance=account)
|
||||
|
||||
# print(f"Account '{account.name}' created successfully.")
|
||||
# else:
|
||||
# print(f"Failed to create account. Errors: {create_form.errors}")
|
||||
# form = AccountModelUpdateForm(instance=account)
|
||||
|
||||
# if form.is_valid():
|
||||
# instance = form.save(commit=False)
|
||||
# instance._position = "sorted-sibling"
|
||||
# instance._ref_node_id = cogs.pk
|
||||
# instance.save()
|
||||
# print(f"Account {account.name} created successfully.")
|
||||
# else:
|
||||
# print(f"Failed to create account {account.name}. Errors: {form.errors}")
|
||||
|
||||
@ -8,7 +8,7 @@ from django_ledger.models.invoice import InvoiceModel
|
||||
from django_ledger.utils import accruable_net_summary
|
||||
from decimal import Decimal
|
||||
from django_ledger.models import EstimateModel,EntityModel,ItemModel,ItemTransactionModel,AccountModel,CustomerModel,EntityManagementModel
|
||||
from rich import print
|
||||
# from rich import print
|
||||
from datetime import date
|
||||
from inventory.models import Car, Dealer, VatRate,Lead,CarMake,CarModel,Schedule,CustomGroup
|
||||
from inventory.utils import CarFinanceCalculator
|
||||
@ -68,4 +68,3 @@ def run():
|
||||
# 'coa_model': coa # Ensure the COA model is included
|
||||
# }
|
||||
|
||||
|
||||
20
staticfiles/account/js/account.js
Normal file
20
staticfiles/account/js/account.js
Normal file
@ -0,0 +1,20 @@
|
||||
(function () {
|
||||
const allauth = window.allauth = window.allauth || {}
|
||||
|
||||
function manageEmailForm (o) {
|
||||
const actions = document.getElementsByName('action_remove')
|
||||
if (actions.length) {
|
||||
actions[0].addEventListener('click', function (e) {
|
||||
if (!window.confirm(o.i18n.confirmDelete)) {
|
||||
e.preventDefault()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
allauth.account = {
|
||||
forms: {
|
||||
manageEmailForm
|
||||
}
|
||||
}
|
||||
})()
|
||||
12
staticfiles/account/js/onload.js
Normal file
12
staticfiles/account/js/onload.js
Normal file
@ -0,0 +1,12 @@
|
||||
(function () {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
Array.from(document.querySelectorAll('script[data-allauth-onload]')).forEach(scriptElt => {
|
||||
const funcRef = scriptElt.dataset.allauthOnload
|
||||
if (typeof funcRef === 'string' && funcRef.startsWith('allauth.')) {
|
||||
const funcArg = JSON.parse(scriptElt.textContent)
|
||||
const func = funcRef.split('.').reduce((acc, part) => acc && acc[part], window)
|
||||
func(funcArg)
|
||||
}
|
||||
})
|
||||
})
|
||||
})()
|
||||
43
staticfiles/admin/js/collapse.js
Normal file
43
staticfiles/admin/js/collapse.js
Normal file
@ -0,0 +1,43 @@
|
||||
/*global gettext*/
|
||||
'use strict';
|
||||
{
|
||||
window.addEventListener('load', function() {
|
||||
// Add anchor tag for Show/Hide link
|
||||
const fieldsets = document.querySelectorAll('fieldset.collapse');
|
||||
for (const [i, elem] of fieldsets.entries()) {
|
||||
// Don't hide if fields in this fieldset have errors
|
||||
if (elem.querySelectorAll('div.errors, ul.errorlist').length === 0) {
|
||||
elem.classList.add('collapsed');
|
||||
const h2 = elem.querySelector('h2');
|
||||
const link = document.createElement('a');
|
||||
link.id = 'fieldsetcollapser' + i;
|
||||
link.className = 'collapse-toggle';
|
||||
link.href = '#';
|
||||
link.textContent = gettext('Show');
|
||||
h2.appendChild(document.createTextNode(' ('));
|
||||
h2.appendChild(link);
|
||||
h2.appendChild(document.createTextNode(')'));
|
||||
}
|
||||
}
|
||||
// Add toggle to hide/show anchor tag
|
||||
const toggleFunc = function(ev) {
|
||||
if (ev.target.matches('.collapse-toggle')) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
const fieldset = ev.target.closest('fieldset');
|
||||
if (fieldset.classList.contains('collapsed')) {
|
||||
// Show
|
||||
ev.target.textContent = gettext('Hide');
|
||||
fieldset.classList.remove('collapsed');
|
||||
} else {
|
||||
// Hide
|
||||
ev.target.textContent = gettext('Show');
|
||||
fieldset.classList.add('collapsed');
|
||||
}
|
||||
}
|
||||
};
|
||||
document.querySelectorAll('fieldset.module').forEach(function(el) {
|
||||
el.addEventListener('click', toggleFunc);
|
||||
});
|
||||
});
|
||||
}
|
||||
BIN
staticfiles/css/SaudiRiyalFont.ttf
Normal file
BIN
staticfiles/css/SaudiRiyalFont.ttf
Normal file
Binary file not shown.
BIN
staticfiles/css/SaudiRiyalFont.woff
Normal file
BIN
staticfiles/css/SaudiRiyalFont.woff
Normal file
Binary file not shown.
BIN
staticfiles/css/SaudiRiyalFont.woff2
Normal file
BIN
staticfiles/css/SaudiRiyalFont.woff2
Normal file
Binary file not shown.
@ -267,6 +267,20 @@
|
||||
titleText: msg
|
||||
});
|
||||
}
|
||||
function getCookie(name) {
|
||||
let cookieValue = null;
|
||||
if (document.cookie && document.cookie !== "") {
|
||||
const cookies = document.cookie.split(";");
|
||||
for (let cookie of cookies) {
|
||||
cookie = cookie.trim();
|
||||
if (cookie.substring(0, name.length + 1) === name + "=") {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
</script>
|
||||
|
||||
{% endblock customJS %}
|
||||
@ -82,14 +82,10 @@
|
||||
<div class="my-3"></div>
|
||||
{% include 'footer.html' %}
|
||||
</div>
|
||||
|
||||
</main>
|
||||
{% block customJS %}
|
||||
<script src="{% static 'js/djetler.bundle.js' %}"></script>
|
||||
|
||||
<script src="{% static 'js/js-utils.js' %}"></script>
|
||||
<script src="{% static 'js/modal/show_modal.js' %}"></script>
|
||||
{% endblock %}
|
||||
<script src="{% static 'js/js-utils.js' %}"></script>
|
||||
<script src="{% static 'js/modal/show_modal.js' %}"></script>
|
||||
|
||||
<!-- ===============================================-->
|
||||
<!-- JavaScripts-->
|
||||
@ -133,5 +129,7 @@
|
||||
datePickers.forEach(dp => djLedger.getCalendar(dp.attributes.id.value, dateNavigationUrl))
|
||||
{% endif %}
|
||||
</script>
|
||||
{% block customJS %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
@ -70,6 +70,8 @@
|
||||
<script src="{% static 'vendors/swiper/swiper-bundle.min.js' %}"></script>
|
||||
<script src="{% static 'vendors/typed.js/typed.umd.js' %}"></script>
|
||||
|
||||
{% block customJS %}
|
||||
{% endblock customJS %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user