This commit is contained in:
gitea 2024-12-25 14:52:36 +00:00
parent ab657348e6
commit ab097f333c
13 changed files with 386 additions and 44 deletions

3
.gitignore vendored
View File

@ -9,7 +9,8 @@ media
./car_inventory/settings.py
# Backup files #
*.bak
.gitignore
car_inventory/settings.py
# If you are using PyCharm #
# User-specific stuff
.idea/**/workspace.xml

View File

@ -104,14 +104,21 @@ WSGI_APPLICATION = 'car_inventory.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
# DATABASES = {
# "default": {
# "ENGINE": "django_prometheus.db.backends.postgresql",
# "NAME": "haikal",
# "USER": "haikal",
# "PASSWORD": "haikal",
# "HOST": "10.10.1.120",
# "PORT": 5432,
# }
# }
DATABASES = {
"default": {
"ENGINE": "django_prometheus.db.backends.postgresql",
"NAME": "haikal",
"USER": "haikal",
"PASSWORD": "haikal",
"HOST": "10.10.1.120",
"PORT": 5432,
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3',
}
}

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.17 on 2024-12-25 08:18
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0015_alter_salequotation_payment_id'),
]
operations = [
migrations.AddField(
model_name='additionalservices',
name='vatable',
field=models.BooleanField(default=True, verbose_name='Vatable'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.17 on 2024-12-25 08:18
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0016_additionalservices_vatable'),
]
operations = [
migrations.AlterField(
model_name='additionalservices',
name='vatable',
field=models.BooleanField(default=False, verbose_name='Vatable'),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 4.2.17 on 2024-12-25 10:35
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('django_ledger', '0017_alter_accountmodel_unique_together_and_more'),
('inventory', '0017_alter_additionalservices_vatable'),
]
operations = [
migrations.AddField(
model_name='dealer',
name='entity',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dealers', to='django_ledger.entitymodel'),
),
]

View File

@ -0,0 +1,40 @@
# Generated by Django 4.2.17 on 2024-12-25 11:21
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import inventory.mixins
import phonenumber_field.modelfields
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('inventory', '0018_dealer_entity'),
]
operations = [
migrations.RemoveField(
model_name='dealer',
name='dealer_type',
),
migrations.RemoveField(
model_name='dealer',
name='parent_dealer',
),
migrations.CreateModel(
name='Users',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='Name')),
('arabic_name', models.CharField(max_length=255, verbose_name='Arabic Name')),
('phone', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region='SA', verbose_name='Phone Number')),
('address', models.CharField(blank=True, max_length=200, null=True, verbose_name='Address')),
('user_type', models.CharField(max_length=255, verbose_name='User Type')),
('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='users', to='inventory.dealer')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='user', to=settings.AUTH_USER_MODEL)),
],
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 4.2.17 on 2024-12-25 11:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0019_remove_dealer_dealer_type_and_more'),
]
operations = [
migrations.RenameField(
model_name='users',
old_name='phone',
new_name='phone_number',
),
migrations.AlterField(
model_name='users',
name='user_type',
field=models.CharField(choices=[('Inventory', 'Inventory'), ('Accountent', 'Accountent'), ('sales', 'Sales')], max_length=255, verbose_name='User Type'),
),
]

View File

@ -0,0 +1,35 @@
# Generated by Django 4.2.17 on 2024-12-25 12:51
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('inventory', '0020_rename_phone_users_phone_number_and_more'),
]
operations = [
migrations.RemoveField(
model_name='additionalservices',
name='vatable',
),
migrations.RemoveField(
model_name='dealer',
name='entity',
),
migrations.AddField(
model_name='dealer',
name='dealer_type',
field=models.CharField(choices=[('Owner', 'Owner'), ('Inventory', 'Inventory'), ('Accountent', 'Accountent'), ('sales', 'Sales')], default='Owner', max_length=255, verbose_name='Dealer Type'),
),
migrations.AddField(
model_name='dealer',
name='parent_dealer',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sub_dealers', to='inventory.dealer', verbose_name='Parent Dealer'),
),
migrations.DeleteModel(
name='Users',
),
]

View File

@ -100,14 +100,14 @@ def switch_language(request):
class HomeView(LoginRequiredMixin, TemplateView):
template_name = "index.html"
def dispatch(self, request, *args, **kwargs):
if (
not any(hasattr(request.user, attr) for attr in ["dealer", "subdealer"])
or not request.user.is_authenticated
):
messages.error(request, _("You are not associated with any dealer."))
return redirect("welcome")
return super().dispatch(request, *args, **kwargs)
# def dispatch(self, request, *args, **kwargs):
# if (
# not any(hasattr(request.user, attr) for attr in ["dealer", "subdealer"])
# or not request.user.is_authenticated
# ):
# messages.error(request, _("You are not associated with any dealer."))
# return redirect("welcome")
# return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@ -979,36 +979,36 @@ def post_quotation(request, pk):
# document_prefix="SD"
# )
journal_entry = JournalEntryModel.objects.create(
entity_unit=entity_unit,
posted=False,
description=f"Payment for Invoice {invoice_model}",
ledger=ledger,
locked=False,
origin="Payment",
)
# journal_entry = JournalEntryModel.objects.create(
# entity_unit=entity_unit,
# posted=False,
# description=f"Payment for Invoice {invoice_model}",
# ledger=ledger,
# locked=False,
# origin="Payment",
# )
TransactionModel.objects.create(
journal_entry=journal_entry,
account=cash_account.first(), # Debit Cash
amount=invoice_model.amount_due, # Payment amount
tx_type='debit',
description="Payment Received",
)
# TransactionModel.objects.create(
# journal_entry=journal_entry,
# account=cash_account.first(), # Debit Cash
# amount=invoice_model.amount_due, # Payment amount
# tx_type='debit',
# description="Payment Received",
# )
TransactionModel.objects.create(
journal_entry=journal_entry,
account=recivable_account.first(), # Credit Accounts Receivable
amount=invoice_model.amount_due, # Payment amount
tx_type='credit',
description="Payment Received",
)
journal_entry.posted = True
qoutation.posted = True
qoutation.save()
journal_entry.save()
messages.success(request, "Invoice posted")
return redirect("quotation_detail", pk=pk)
# TransactionModel.objects.create(
# journal_entry=journal_entry,
# account=recivable_account.first(), # Credit Accounts Receivable
# amount=invoice_model.amount_due, # Payment amount
# tx_type='credit',
# description="Payment Received",
# )
# journal_entry.posted = True
# qoutation.posted = True
# qoutation.save()
# journal_entry.save()
# messages.success(request, "Invoice posted")
# return redirect("quotation_detail", pk=pk)
@login_required
def mark_quotation(request, pk):

113
scripts/l.py Normal file
View File

@ -0,0 +1,113 @@
from django_ledger import models as led
from inventory import models as inv_model
import os
from datetime import date, datetime
from decimal import Decimal
from random import randint, choices, random
from zoneinfo import ZoneInfo
# import django
# for easier visualization it is recommended to use pandas to render data...
# if pandas is not installed, you may install it with this command: pip install -U pandas
# pandas is not a dependecy of django_ledger...
# from django.core.exceptions import ObjectDoesNotExist
# # Set your django settings module if needed...
# os.environ['DJANGO_SETTINGS_MODULE'] = 'dev_env.settings'
# # if using jupyter notebook need to set DJANGO_ALLOW_ASYNC_UNSAFE as "true"
# os.environ['DJANGO_ALLOW_ASYNC_UNSAFE'] = 'true'
# # change your working directory as needed...
# os.chdir('../')
# django.setup()
from django_ledger.models.entity import EntityModel
from django_ledger.models.items import ItemModel
from django_ledger.models.invoice import InvoiceModel
from django_ledger.models.bill import BillModel
from django_ledger.models.estimate import EstimateModel
from django.contrib.auth import get_user_model
from django_ledger.io import roles, DEBIT, CREDIT
from django_ledger.io.io_library import IOBluePrint, IOLibrary
from rich import print
def run():
user = inv_model.Dealer.objects.first().user
entity_name = f"{user}-{user.pk}-{user.date_joined.date()}"
entity = EntityModel.create_entity(
name=f"4-{entity_name}",
admin=user,
use_accrual_method=True,
fy_start_month=1
)
coa = entity.create_chart_of_accounts(assign_as_default=True,
commit=True,
coa_name=f"4-{entity_name}-COA")
# if coa:
# entity.populate_default_coa(activate_accounts=True, coa_model=coa)
entity.create_account(
coa_model=coa,
code="10100",
role=roles.ASSET_CA_CASH,
name='Cash',
balance_type="debit",
active=True,
)
entity.create_account(
coa_model=coa,
code="11000",
role=roles.ASSET_CA_RECEIVABLES,
name='Accounts Receivable',
balance_type="debit",
active=True
)
entity.create_account(
coa_model=coa,
code="12000",
role=roles.ASSET_CA_INVENTORY,
name='Inventory',
balance_type="debit",
active=True)
entity.create_account(
coa_model=coa,
code="20100",
role=roles.LIABILITY_CL_ACC_PAYABLE,
name='Accounts Payable',
balance_type="credit",
active=True)
entity.create_account(
coa_model=coa,
code="40100",
role=roles.INCOME_OPERATIONAL,
name='Sales Income',
balance_type="credit",
active=True)
entity.create_account(
coa_model=coa,
code="50100",
role=roles.COGS,
name='Cost of Goods Sold',
balance_type="debit",
active=True)
uom = entity.create_uom(
name='Linear Feet',
unit_abbr='lin-ft'
)
service_model = entity.create_item_service(
name='Yoga Class',
uom_model=uom
)

47
scripts/ledger.py Normal file
View File

@ -0,0 +1,47 @@
from django_ledger import models as led
from inventory import models as inv_model
import os
from datetime import date, datetime
from decimal import Decimal
from random import randint, choices, random
from zoneinfo import ZoneInfo
# import django
# for easier visualization it is recommended to use pandas to render data...
# if pandas is not installed, you may install it with this command: pip install -U pandas
# pandas is not a dependecy of django_ledger...
# from django.core.exceptions import ObjectDoesNotExist
# # Set your django settings module if needed...
# os.environ['DJANGO_SETTINGS_MODULE'] = 'dev_env.settings'
# # if using jupyter notebook need to set DJANGO_ALLOW_ASYNC_UNSAFE as "true"
# os.environ['DJANGO_ALLOW_ASYNC_UNSAFE'] = 'true'
# # change your working directory as needed...
# os.chdir('../')
# django.setup()
from django_ledger.models.entity import EntityModel
from django_ledger.models.items import ItemModel
from django_ledger.models.invoice import InvoiceModel
from django_ledger.models.bill import BillModel
from django_ledger.models.estimate import EstimateModel
from django.contrib.auth import get_user_model
from django_ledger.io import roles, DEBIT, CREDIT
from django_ledger.io.io_library import IOBluePrint, IOLibrary
from rich import print
def run():
user = inv_model.Dealer.objects.first().user
entity_name = f"{user}-{user.pk}-{user.date_joined.date()}"
entity = EntityModel.objects.filter(name=f"4-{entity_name}").first()
bank_account_model = entity.create_bank_account(name='A big bank account!',
account_type='checking')
get_bank_accounts = entity.get_bank_accounts()
print(get_bank_accounts)

View File

@ -0,0 +1,19 @@
{% extends "base.html" %}
{% load crispy_forms_filters %}
{% block title %}{{ _("Create Bank Account") }}{% endblock title %}
{% block content %}
<div class="container mt-4">
<h3 class="text-center">{% trans "Create Bank Account" %}</h3>
<form method="post" class="needs-validation" novalidate>
{% csrf_token %}
{{ form|crispy }}
<!-- Save and Back Buttons -->
<div class="mt-4 text-center">
<button type="submit" class="btn btn-success me-2">{% trans "Save" %}</button>
<a href="{% url 'bank_account_list' %}" class="btn btn-secondary">{% trans "Cancel" %}</a>
</div>
</form>
</div>
{% endblock %}

View File

@ -0,0 +1 @@
{{bank_accounts}}