From ab097f333c9d09b960f1ed623817176605c95506 Mon Sep 17 00:00:00 2001 From: gitea Date: Wed, 25 Dec 2024 14:52:36 +0000 Subject: [PATCH 1/3] update --- .gitignore | 3 +- car_inventory/settings.py | 21 ++-- .../0016_additionalservices_vatable.py | 18 +++ .../0017_alter_additionalservices_vatable.py | 18 +++ inventory/migrations/0018_dealer_entity.py | 20 ++++ ...0019_remove_dealer_dealer_type_and_more.py | 40 +++++++ ...ename_phone_users_phone_number_and_more.py | 23 ++++ ...ove_additionalservices_vatable_and_more.py | 35 ++++++ inventory/views.py | 72 +++++------ scripts/l.py | 113 ++++++++++++++++++ scripts/ledger.py | 47 ++++++++ .../bank_accounts/bank_account_create.html | 19 +++ .../bank_accounts/bank_account_list.html | 1 + 13 files changed, 386 insertions(+), 44 deletions(-) create mode 100644 inventory/migrations/0016_additionalservices_vatable.py create mode 100644 inventory/migrations/0017_alter_additionalservices_vatable.py create mode 100644 inventory/migrations/0018_dealer_entity.py create mode 100644 inventory/migrations/0019_remove_dealer_dealer_type_and_more.py create mode 100644 inventory/migrations/0020_rename_phone_users_phone_number_and_more.py create mode 100644 inventory/migrations/0021_remove_additionalservices_vatable_and_more.py create mode 100644 scripts/l.py create mode 100644 scripts/ledger.py create mode 100644 templates/sales/bank_accounts/bank_account_create.html create mode 100644 templates/sales/bank_accounts/bank_account_list.html diff --git a/.gitignore b/.gitignore index 3bc4a7b9..16c1bd8a 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/car_inventory/settings.py b/car_inventory/settings.py index cbe804fd..301a7d42 100644 --- a/car_inventory/settings.py +++ b/car_inventory/settings.py @@ -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', } } diff --git a/inventory/migrations/0016_additionalservices_vatable.py b/inventory/migrations/0016_additionalservices_vatable.py new file mode 100644 index 00000000..b202b0fa --- /dev/null +++ b/inventory/migrations/0016_additionalservices_vatable.py @@ -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'), + ), + ] diff --git a/inventory/migrations/0017_alter_additionalservices_vatable.py b/inventory/migrations/0017_alter_additionalservices_vatable.py new file mode 100644 index 00000000..192154ac --- /dev/null +++ b/inventory/migrations/0017_alter_additionalservices_vatable.py @@ -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'), + ), + ] diff --git a/inventory/migrations/0018_dealer_entity.py b/inventory/migrations/0018_dealer_entity.py new file mode 100644 index 00000000..31f2f982 --- /dev/null +++ b/inventory/migrations/0018_dealer_entity.py @@ -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'), + ), + ] diff --git a/inventory/migrations/0019_remove_dealer_dealer_type_and_more.py b/inventory/migrations/0019_remove_dealer_dealer_type_and_more.py new file mode 100644 index 00000000..d2f56483 --- /dev/null +++ b/inventory/migrations/0019_remove_dealer_dealer_type_and_more.py @@ -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), + ), + ] diff --git a/inventory/migrations/0020_rename_phone_users_phone_number_and_more.py b/inventory/migrations/0020_rename_phone_users_phone_number_and_more.py new file mode 100644 index 00000000..5ebcdee0 --- /dev/null +++ b/inventory/migrations/0020_rename_phone_users_phone_number_and_more.py @@ -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'), + ), + ] diff --git a/inventory/migrations/0021_remove_additionalservices_vatable_and_more.py b/inventory/migrations/0021_remove_additionalservices_vatable_and_more.py new file mode 100644 index 00000000..3c397128 --- /dev/null +++ b/inventory/migrations/0021_remove_additionalservices_vatable_and_more.py @@ -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', + ), + ] diff --git a/inventory/views.py b/inventory/views.py index 12e4e019..4132d025 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -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): diff --git a/scripts/l.py b/scripts/l.py new file mode 100644 index 00000000..07444a19 --- /dev/null +++ b/scripts/l.py @@ -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 +) \ No newline at end of file diff --git a/scripts/ledger.py b/scripts/ledger.py new file mode 100644 index 00000000..bcc457fb --- /dev/null +++ b/scripts/ledger.py @@ -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) \ No newline at end of file diff --git a/templates/sales/bank_accounts/bank_account_create.html b/templates/sales/bank_accounts/bank_account_create.html new file mode 100644 index 00000000..a2567139 --- /dev/null +++ b/templates/sales/bank_accounts/bank_account_create.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} +{% load crispy_forms_filters %} + +{% block title %}{{ _("Create Bank Account") }}{% endblock title %} + +{% block content %} +
+

{% trans "Create Bank Account" %}

+
+ {% csrf_token %} + {{ form|crispy }} + +
+ + {% trans "Cancel" %} +
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/sales/bank_accounts/bank_account_list.html b/templates/sales/bank_accounts/bank_account_list.html new file mode 100644 index 00000000..cf0c4ee5 --- /dev/null +++ b/templates/sales/bank_accounts/bank_account_list.html @@ -0,0 +1 @@ +{{bank_accounts}} \ No newline at end of file From 3a6d2408ff6038b51f45a5e1eea82db961c3e679 Mon Sep 17 00:00:00 2001 From: gitea Date: Wed, 25 Dec 2024 15:33:36 +0000 Subject: [PATCH 2/3] some updates --- .../migrations/0022_merge_20241225_1754.py | 14 ++++++++++++++ .../migrations/0023_remove_dealer_email.py | 17 +++++++++++++++++ inventory/migrations/0024_dealer_email.py | 19 +++++++++++++++++++ inventory/models.py | 3 +-- inventory/signals.py | 3 +-- templates/base.html | 6 ++++-- 6 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 inventory/migrations/0022_merge_20241225_1754.py create mode 100644 inventory/migrations/0023_remove_dealer_email.py create mode 100644 inventory/migrations/0024_dealer_email.py diff --git a/inventory/migrations/0022_merge_20241225_1754.py b/inventory/migrations/0022_merge_20241225_1754.py new file mode 100644 index 00000000..b69fff19 --- /dev/null +++ b/inventory/migrations/0022_merge_20241225_1754.py @@ -0,0 +1,14 @@ +# Generated by Django 4.2.17 on 2024-12-25 14:54 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('inventory', '0017_dealer_email'), + ('inventory', '0021_remove_additionalservices_vatable_and_more'), + ] + + operations = [ + ] diff --git a/inventory/migrations/0023_remove_dealer_email.py b/inventory/migrations/0023_remove_dealer_email.py new file mode 100644 index 00000000..42c5ffd4 --- /dev/null +++ b/inventory/migrations/0023_remove_dealer_email.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.17 on 2024-12-25 15:05 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('inventory', '0022_merge_20241225_1754'), + ] + + operations = [ + migrations.RemoveField( + model_name='dealer', + name='email', + ), + ] diff --git a/inventory/migrations/0024_dealer_email.py b/inventory/migrations/0024_dealer_email.py new file mode 100644 index 00000000..524efd73 --- /dev/null +++ b/inventory/migrations/0024_dealer_email.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.17 on 2024-12-25 15:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('inventory', '0023_remove_dealer_email'), + ] + + operations = [ + migrations.AddField( + model_name='dealer', + name='email', + field=models.EmailField(default='ismail@tenhal.com', max_length=254, unique=True, verbose_name='Email'), + preserve_default=False, + ), + ] diff --git a/inventory/models.py b/inventory/models.py index ed06a68f..cbba93d3 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -499,6 +499,7 @@ class Dealer(models.Model, LocalizedNameMixin): upload_to="logos/users", blank=True, null=True, verbose_name=_("Logo") ) joined_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Joined At")) + # entity = models.ForeignKey(EntityModel,on_delete=models.CASCADE,null=True,blank=True) email = models.EmailField(unique=True, verbose_name=_("Email")) parent_dealer = models.ForeignKey( "self", @@ -535,8 +536,6 @@ class Dealer(models.Model, LocalizedNameMixin): return None - - class Meta: verbose_name = _("Dealer") verbose_name_plural = _("Dealers") diff --git a/inventory/signals.py b/inventory/signals.py index f5adbeed..437e9510 100644 --- a/inventory/signals.py +++ b/inventory/signals.py @@ -66,8 +66,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): if created: entity, created = EntityModel.objects.get_or_create( name=instance.get_root_dealer.name, - admin=instance.get_root_dealer.user, - # address_1=instance.address, + admin=instance.get_root_dealer.user, accrual_method=False, fy_start_month=1, depth=0, diff --git a/templates/base.html b/templates/base.html index 3e595344..db0b2cbc 100644 --- a/templates/base.html +++ b/templates/base.html @@ -418,8 +418,9 @@ {% if user.is_authenticated and user.dealer or user.subdealer%} + + + diff --git a/templates/ledger_accounts/account_confirm_delete.html b/templates/ledger_accounts/account_confirm_delete.html new file mode 100644 index 00000000..6ec980b2 --- /dev/null +++ b/templates/ledger_accounts/account_confirm_delete.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} + +{% block content %} +

Delete Account

+

Are you sure you want to delete "{{ object }}"?

+
+ {% csrf_token %} + + Cancel +
+{% endblock %} \ No newline at end of file diff --git a/templates/ledger_accounts/account_form.html b/templates/ledger_accounts/account_form.html new file mode 100644 index 00000000..05f3a750 --- /dev/null +++ b/templates/ledger_accounts/account_form.html @@ -0,0 +1,13 @@ +{% extends 'base.html' %} +{% load crispy_forms_tags %} + +{% block title %}{% if object %}Edit{% else %}Create{% endif %} Account{% endblock %} + +{% block content %} +

{% if object %}Edit{% else %}Create{% endif %} Account

+
+ {% csrf_token %} + {{ form|crispy }} + +
+{% endblock %} \ No newline at end of file diff --git a/templates/ledger_accounts/account_list.html b/templates/ledger_accounts/account_list.html new file mode 100644 index 00000000..e45674df --- /dev/null +++ b/templates/ledger_accounts/account_list.html @@ -0,0 +1,33 @@ +{% extends 'base.html' %} + +{% block content %} +

Accounts

+Create New Account + + + + + + + + + + + + + {% for account in accounts %} + + + + + + + + + {% endfor %} + +
CodeNameRoleBalance TypeActiveActions
{{ account.code }}{{ account.name }}{{ account.role }}{{ account.balance_type }}{{ account.active }} + Edit + Delete +
+{% endblock %} \ No newline at end of file diff --git a/templates/sales/additional_services/additional_service_detail.html b/templates/sales/additional_services/additional_service_detail.html new file mode 100644 index 00000000..e69de29b diff --git a/templates/sales/additional_services/additional_service_form.html b/templates/sales/additional_services/additional_service_form.html new file mode 100644 index 00000000..1f97cd02 --- /dev/null +++ b/templates/sales/additional_services/additional_service_form.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} +{% load i18n %} +{% load crispy_forms_filters %} +{% block title %}{% trans "Additional Services" %}{% endblock title %} +{% block additional_services %} + + {% trans "Additional Services"|capfirst %} + (current) + +{% endblock %} +{% block content %} +
{% csrf_token %}{{ form|crispy }}
+{% endblock %} \ No newline at end of file diff --git a/templates/sales/additional_services/additional_service_list.html b/templates/sales/additional_services/additional_service_list.html new file mode 100644 index 00000000..025894a1 --- /dev/null +++ b/templates/sales/additional_services/additional_service_list.html @@ -0,0 +1,47 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block title %}{% trans "Additional Services" %}{% endblock title %} + +{% block additional_services %} + + {% trans "Additional Services" %} + (current) + +{% endblock %} + +{% block content %} +{% trans "Create" %} + + + + + + + + + + + + + + + {% for service in services %} + + + + + + + + + + {% endfor %} + +
#NameArabic NameDescriptionPriceVatableActions
{{service.name}}{{service.arabic_name}}{{service.description}}{{service.price}}{{service.vatable}} + {% trans "Details" %} + {% trans "Update" %} +
+ + +{% endblock %} \ No newline at end of file