From c11fc359bd3770713d3ed105a0060d962e038845 Mon Sep 17 00:00:00 2001 From: gitea Date: Tue, 4 Mar 2025 21:13:23 +0000 Subject: [PATCH] add permissions --- inventory/filters.py | 6 + .../migrations/0054_alter_staff_staff_type.py | 18 ++ inventory/models.py | 53 ++-- inventory/services.py | 9 +- inventory/signals.py | 129 ++++---- inventory/urls.py | 3 +- inventory/views.py | 282 +++++++++++------ scripts/run.py | 60 ++-- templates/403.html | 92 ++++++ templates/404.html | 90 ++++++ templates/500.html | 90 ++++++ templates/crm/leads/lead_list.html | 16 +- templates/customers/customer_list.html | 24 +- templates/customers/view_customer.html | 17 +- templates/errors/403.html | 283 +---------------- templates/header.html | 289 ++++++++++-------- templates/inventory/car_detail.html | 15 +- templates/ledger/reports/dashboard.html | 1 + .../organizations/organization_list.html | 10 +- .../sales/estimates/estimate_detail.html | 5 +- templates/sales/invoices/invoice_detail.html | 12 +- 21 files changed, 862 insertions(+), 642 deletions(-) create mode 100644 inventory/migrations/0054_alter_staff_staff_type.py create mode 100644 templates/403.html create mode 100644 templates/404.html create mode 100644 templates/500.html diff --git a/inventory/filters.py b/inventory/filters.py index 8b137891..0d8b95f5 100644 --- a/inventory/filters.py +++ b/inventory/filters.py @@ -1 +1,7 @@ +from django_ledger.models import AccountModel +import django_filters +class AccountModelFilter(django_filters.FilterSet): + class Meta: + model = AccountModel + fields = ['code', 'name','role'] \ No newline at end of file diff --git a/inventory/migrations/0054_alter_staff_staff_type.py b/inventory/migrations/0054_alter_staff_staff_type.py new file mode 100644 index 00000000..1b6c0ae1 --- /dev/null +++ b/inventory/migrations/0054_alter_staff_staff_type.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.17 on 2025-03-04 01:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('inventory', '0053_lead_crn_lead_vrn'), + ] + + operations = [ + migrations.AlterField( + model_name='staff', + name='staff_type', + field=models.CharField(choices=[('inventory', 'Inventory'), ('accountant', 'Accountant'), ('sales', 'Sales')], max_length=255, verbose_name='Staff Type'), + ), + ] diff --git a/inventory/models.py b/inventory/models.py index 4736bae7..6be06d85 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -18,7 +18,7 @@ from django.utils.timezone import now from inventory.utils import get_user_type from .mixins import LocalizedNameMixin -from django_ledger.models import EntityModel, ItemModel,EstimateModel,InvoiceModel,AccountModel +from django_ledger.models import EntityModel, ItemModel,EstimateModel,InvoiceModel,AccountModel,EntityManagementModel from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from appointment.models import StaffMember @@ -936,13 +936,13 @@ class Dealer(models.Model, LocalizedNameMixin): class StaffTypes(models.TextChoices): - MANAGER = "manager", _("Manager") + # MANAGER = "manager", _("Manager") INVENTORY = "inventory", _("Inventory") ACCOUNTANT = "accountant", _("Accountant") SALES = "sales", _("Sales") - COORDINATOR = "coordinator", _("Coordinator") - RECEPTIONIST = "receptionist", _("Receptionist") - AGENT = "agent", _("Agent") + # COORDINATOR = "coordinator", _("Coordinator") + # RECEPTIONIST = "receptionist", _("Receptionist") + # AGENT = "agent", _("Agent") class Staff(models.Model, LocalizedNameMixin): @@ -970,13 +970,20 @@ class Staff(models.Model, LocalizedNameMixin): def clear_groups(self): + EntityManagementModel.objects.filter(user=self.user,entity=self.dealer.entity).delete() return self.user.groups.clear() def add_group(self,group): try: self.user.groups.add(group) + self.add_as_manager() except Exception as e: pass + def add_as_manager(self): + if self.staff_type in ["accountant","manager"]: + EntityManagementModel.objects.get_or_create( + user=self.user,entity=self.dealer.entity + ) class Meta: verbose_name = _("Staff") verbose_name_plural = _("Staff") @@ -1852,32 +1859,23 @@ class CustomGroup(models.Model): except Exception as e: pass - # def set_default_inventory_permissions(self): - # self.clear_permissions() - # allowed_models = ["car","carequipment","interiorcolors","exteriorcolors","carcolors","carlocation","customcard"] - # self.set_permissions(allowed_models=allowed_models,other_perms=['view_carfinance']) - # def set_default_accountant_permissions(self): - # self.clear_permissions() - # allowed_models = ["car","carfinance","carlocation","customcard"] - # allowed_models_ledger = ["accountmodel","chartofaccountmodel","customcard","billmodel"] - # self.set_permissions(allowed_models=allowed_models,other_perms=['view_carfinance']) - # self.set_permissions(app="django_ledger",allowed_models=allowed_models_ledger) - def set_default_permissions(self): self.clear_permissions() if self.name == "Manager": - self.set_permissions(app="inventory",allowed_models=["car","carfinance","carlocation","customcard"]) - self.set_permissions(app="django_ledger",allowed_models=["accountmodel","chartofaccountmodel","customcard","billmodel"]) + self.set_permissions(app="inventory",allowed_models=["car","carfinance","carlocation","customcard","cartransfer","carcolors","carequipment","interiorcolors","exteriorcolors","carreservation"]) + self.set_permissions(app="inventory",allowed_models=["lead","customgroup","saleorder","payment","staff","schedule","activity","opportunity"]) + self.set_permissions(app="django_ledger",allowed_models=["estimatemodel","invoicemodel","accountmodel","chartofaccountmodel","customermodel","billmodel"]) elif self.name == "Inventory": - self.set_permissions(allowed_models=["car","carequipment","interiorcolors","exteriorcolors","carcolors","carlocation","customcard"] - ,other_perms=['view_carfinance']) + self.set_permissions(app="inventory",allowed_models=["car","carequipment","interiorcolors","exteriorcolors","carcolors","carlocation","customcard","carreservation"]) elif self.name == "Sales": + self.set_permissions(app="django_ledger",allowed_models=["estimatemodel","invoicemodel","customermodel"]) + + self.set_permissions(app="inventory",allowed_models=["saleorder","payment","staff","schedule","activity","opportunity","customer","organization"]) self.set_permissions(app="inventory",allowed_models=["lead","salequotation","salequotationcar"], - other_perms=['view_car','view_carlocation','view_customcard','view_carcolors','view_cartransfer']. - extend(['view_estimatemodel','view_invoicemodel','view_saleorder'])) + other_perms=['view_car','view_carlocation','view_customcard','view_carcolors','view_cartransfer']) elif self.name == "Accountant": - self.set_permissions(app="inventory",allowed_models=["carfinance"],other_perms=['view_car','view_carlocation','view_customcard','view_carcolors','view_cartransfer']) - self.set_permissions(app="django_ledger",allowed_models=["accountmodel","chartofaccountmodel","customcard","billmodel"]) + self.set_permissions(app="inventory",allowed_models=["carfinance"],other_perms=['view_car','view_carlocation','view_customcard','view_carcolors','view_cartransfer','view_saleorder']) + self.set_permissions(app="django_ledger",allowed_models=["bankaccountmodel","accountmodel","chartofaccountmodel","customcard","billmodel","itemmodel","invoicemodel","vendormodel"],other_perms=['view_customermodel','view_estimatemodel']) elif self.name == "Agent": # Todo : set permissions for agent pass @@ -1888,11 +1886,10 @@ class CustomGroup(models.Model): for perm in Permission.objects.filter(content_type__app_label=app,content_type__model__in=allowed_models): self.add_permission(perm) for perm in other_perms: - Permission.objects.get(codename=perm) - self.add_permission(perm) + p = Permission.objects.get(codename=perm) + self.add_permission(p) except Exception as e: - pass - + print(e) class DealerSettings(models.Model): diff --git a/inventory/services.py b/inventory/services.py index cc782106..78f72874 100644 --- a/inventory/services.py +++ b/inventory/services.py @@ -17,15 +17,20 @@ from inventory.haikalna import decode_vin_haikalna def get_make(item): data = CarMake.objects.filter(name__iexact=item).first() + if not data: + r = item.split(" ") + for i in r: + if data:= CarMake.objects.filter(name__iexact=i).first(): + break return data def get_model(item,make): data = make.carmodel_set.filter(name__iexact=item).first() - if not data: + if not data: r = item.split(" ") for i in r: if data:=make.carmodel_set.filter(name__iexact=i).first(): - break + break return data def normalize_name(name): diff --git a/inventory/signals.py b/inventory/signals.py index 09135fd4..76094df6 100644 --- a/inventory/signals.py +++ b/inventory/signals.py @@ -86,7 +86,7 @@ def create_car_location(sender, instance, created, **kwargs): def create_dealer_settings(sender, instance, created, **kwargs): if created: models.DealerSettings.objects.create(dealer=instance) - + # Create Entity @receiver(post_save, sender=models.Dealer) def create_ledger_entity(sender, instance, created, **kwargs): @@ -106,7 +106,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): assign_as_default=True, commit=True, coa_name=_(f"{entity_name}-COA") ) if coa: - # Create unit of measures + # Create unit of measures entity.create_uom(name="Unit", unit_abbr="unit") for u in models.UnitOfMeasure.choices: entity.create_uom(name=u[1], unit_abbr=u[0]) @@ -147,7 +147,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): asset_ca_inventory.role_default = True asset_ca_inventory.save() - + # Prepaid Expenses Account asset_ca_prepaid = entity.create_account( coa_model=coa, @@ -159,7 +159,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): ) asset_ca_prepaid.role_default = True asset_ca_prepaid.save() - + # Employee Expenses Account asset_ca_prepaid_employee = entity.create_account( coa_model=coa, @@ -169,8 +169,8 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - - + + # VAT Payable Account liability_ltl_vat_receivable = entity.create_account( coa_model=coa, @@ -180,7 +180,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Buildings Accumulated Depreciation Account asset_ppe_buildings_accum_depreciation = entity.create_account( coa_model=coa, @@ -192,7 +192,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): ) 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, @@ -204,7 +204,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): ) 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, @@ -216,7 +216,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): ) 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, @@ -227,7 +227,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): # active=True, # ) # asset_lti_notes_receivable.role_default = True - # asset_lti_notes_receivable.save() + # asset_lti_notes_receivable.save() # # Land Account # asset_lti_land = entity.create_account( @@ -240,8 +240,8 @@ def create_ledger_entity(sender, instance, created, **kwargs): # ) # asset_lti_land.role_default = True # asset_lti_land.save() - - + + # Buildings Account asset_ppe_buildings = entity.create_account( coa_model=coa, @@ -254,7 +254,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): asset_ppe_buildings.role_default = True asset_ppe_buildings.save() - + # Accounts Payable Account liability_cl_acc_payable = entity.create_account( @@ -267,7 +267,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): ) 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, @@ -291,7 +291,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): ) 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, @@ -303,7 +303,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): ) 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, @@ -313,7 +313,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="credit", active=True, ) - + # taxes Payable Account liability_ltl_taxes_payable = entity.create_account( coa_model=coa, @@ -323,7 +323,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="credit", active=True, ) - + # social insurance Payable Account liability_ltl_social_insurance_payable = entity.create_account( coa_model=coa, @@ -336,7 +336,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): # 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, @@ -352,20 +352,20 @@ def create_ledger_entity(sender, instance, created, **kwargs): # 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() + 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, @@ -377,7 +377,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): ) equity_retained_earnings.role_default = True equity_retained_earnings.save() - + equity_retained_earnings_losses = entity.create_account( coa_model=coa, code="3402", @@ -419,15 +419,15 @@ def create_ledger_entity(sender, instance, created, **kwargs): 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, @@ -439,8 +439,8 @@ def create_ledger_entity(sender, instance, created, **kwargs): ) expense_cogs.role_default = True expense_cogs.save() - - + + # accrued Expenses Account expense_cogs = entity.create_account( coa_model=coa, @@ -450,7 +450,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # accrued salaries Account expense_cogs = entity.create_account( coa_model=coa, @@ -460,7 +460,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Rent Expense Account expense_rent = entity.create_account( coa_model=coa, @@ -472,7 +472,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): ) # expense_rent.role_default = True # expense_rent.save() - + # Salaries and Administrative Fees expense_salaries = entity.create_account( coa_model=coa, @@ -481,8 +481,8 @@ def create_ledger_entity(sender, instance, created, **kwargs): name=_("Salaries and Administrative Fees"), balance_type="debit", active=True, - ) - + ) + # Medical Insurance expense_medical_insurance = entity.create_account( coa_model=coa, @@ -492,7 +492,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Marketing and Advertising Expenses expense_marketing = entity.create_account( coa_model=coa, @@ -502,7 +502,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Commissions and Incentives expense_commissions = entity.create_account( coa_model=coa, @@ -512,7 +512,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Travel Tickets expense_travel = entity.create_account( coa_model=coa, @@ -522,7 +522,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Social Insurance expense_other = entity.create_account( coa_model=coa, @@ -532,7 +532,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Government Fees expense_other = entity.create_account( coa_model=coa, @@ -542,7 +542,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Fees and Subscriptions expense_other = entity.create_account( coa_model=coa, @@ -552,7 +552,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Office Services Expenses expense_other = entity.create_account( coa_model=coa, @@ -562,7 +562,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Office Supplies and Printing expense_other = entity.create_account( coa_model=coa, @@ -572,7 +572,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Hospitality Expenses expense_other = entity.create_account( coa_model=coa, @@ -582,7 +582,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Bank Commissions expense_other = entity.create_account( coa_model=coa, @@ -592,7 +592,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Other Expenses expense_other = entity.create_account( coa_model=coa, @@ -602,7 +602,7 @@ def create_ledger_entity(sender, instance, created, **kwargs): balance_type="debit", active=True, ) - + # Transportation Expenses expense_other = entity.create_account( coa_model=coa, @@ -612,30 +612,31 @@ def create_ledger_entity(sender, instance, created, **kwargs): 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) - - + + @receiver(post_save, sender=models.Dealer) def create_dealer_groups(sender, instance, created, **kwargs): - - group_names = ["Manager", "Inventory", "Accountant", "Agent", "Sales"] - + + group_names = ["Inventory", "Accountant", "Sales"] + def create_groups(): for group_name in group_names: group, created = Group.objects.get_or_create(name=f"{instance.pk}_{group_name}") 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 @@ -667,7 +668,7 @@ def create_ledger_vendor(sender, instance, created, **kwargs): def create_customer_user(sender, instance, created, **kwargs): if created: first_name = instance.additional_info.get("customer_info").get("first_name") - last_name = instance.additional_info.get("customer_info").get("last_name") + last_name = instance.additional_info.get("customer_info").get("last_name") user = User.objects.create( username=instance.email, email=instance.email, @@ -678,12 +679,12 @@ def create_customer_user(sender, instance, created, **kwargs): user.set_unusable_password() user.save() instance.user = user - instance.save() - + instance.save() + # Create Item @receiver(post_save, sender=models.Car) -def create_item_model(sender, instance, created, **kwargs): +def create_item_model(sender, instance, created, **kwargs): entity = instance.dealer.entity if created: coa = entity.get_default_coa() @@ -699,7 +700,7 @@ def create_item_model(sender, instance, created, **kwargs): product.additional_info = {} product.save() - product = entity.get_items_all().filter(name=instance.vin).first() + product = entity.get_items_all().filter(name=instance.vin).first() product.additional_info.update({'car_info': instance.to_dict()}) product.save() @@ -707,7 +708,7 @@ def create_item_model(sender, instance, created, **kwargs): @receiver(post_save, sender=models.CarFinance) def update_item_model_cost(sender, instance, created, **kwargs): entity = instance.car.dealer.entity - + product = entity.get_items_all().filter(name=instance.car.vin).first() product.default_amount = instance.selling_price @@ -795,7 +796,7 @@ def create_item_service(sender, instance, created, **kwargs): entity = instance.dealer.entity uom = entity.get_uom_all().get(unit_abbr=instance.uom) cogs = entity.get_all_accounts().get(role=roles.COGS) - + service_model = ItemModel.objects.create( name=instance.name, uom=uom, @@ -873,7 +874,7 @@ def update_car_status_on_reservation_update(sender, instance, **kwargs): # @receiver(post_save, sender=EstimateModel) # def update_estimate_status(sender, instance,created, **kwargs): - + # items = instance.get_itemtxs_data()[0].all() # total = sum([Decimal(item.item_model.additional_info['car_finance']["selling_price"]) * Decimal(item.ce_quantity) for item in items]) diff --git a/inventory/urls.py b/inventory/urls.py index 6c6a3dad..6920f664 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -1,3 +1,4 @@ +from django.conf.urls import handler403,handler400,handler404,handler500 from django.urls import path from django_tables2.export.export import TableExport @@ -85,7 +86,7 @@ urlpatterns = [ name="create_opportunity", ), path( - "customers//add-note/", + "customers//add-note/", views.add_note_to_customer, name="add_note_to_customer", ), diff --git a/inventory/views.py b/inventory/views.py index 94577fb6..a588d6ad 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -38,6 +38,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic import DetailView, RedirectView from django.contrib.messages.views import SuccessMessageMixin from django.contrib.auth.mixins import PermissionRequiredMixin +from django.contrib.auth.decorators import permission_required from django.shortcuts import render, get_object_or_404, redirect from django.views.generic import ( View, @@ -107,6 +108,8 @@ from django_ledger.views.mixins import ( # Other from plans.models import Plan + +from inventory.filters import AccountModelFilter from . import models, forms, tables from plans.quota import get_user_quota from django_tables2 import SingleTableView @@ -250,7 +253,7 @@ def dealer_signup(request, *args, **kwargs): # return False -class HomeView(TemplateView): +class HomeView(LoginRequiredMixin,TemplateView): template_name = "index.html" def dispatch(self, request, *args, **kwargs): @@ -438,10 +441,11 @@ class WelcomeView(TemplateView): return context -class CarCreateView(LoginRequiredMixin, CreateView): +class CarCreateView(LoginRequiredMixin,PermissionRequiredMixin, CreateView): model = models.Car form_class = forms.CarForm template_name = "inventory/car_form.html" + permission_required = ['inventory.add_car'] # success_url = reverse_lazy('inventory_stats') @@ -650,7 +654,7 @@ class AjaxHandlerView(LoginRequiredMixin, View): @method_decorator(csrf_exempt, name="dispatch") -class SearchCodeView(View): +class SearchCodeView(LoginRequiredMixin,View): template_name = "inventory/scan_vin.html" def get(self, request, *args, **kwargs): @@ -683,13 +687,14 @@ class SearchCodeView(View): return JsonResponse({"success": False, "error": "No image provided"}) -class CarInventory(LoginRequiredMixin, ListView): +class CarInventory(LoginRequiredMixin,PermissionRequiredMixin, ListView): model = models.Car home_label = _("inventory") template_name = "inventory/car_inventory.html" context_object_name = "cars" paginate_by = 10 ordering = ["receiving_date"] + permission_required = ['inventory.view_car'] def get_queryset(self, *args, **kwargs): query = self.request.GET.get("q") @@ -716,10 +721,11 @@ class CarInventory(LoginRequiredMixin, ListView): return context -class CarColorCreate(LoginRequiredMixin, CreateView): +class CarColorCreate(LoginRequiredMixin,PermissionRequiredMixin, CreateView): model = models.CarColors form_class = forms.CarColorsForm template_name = "inventory/add_colors.html" + permission_required = ['inventory.view_car'] def form_valid(self, form): car = get_object_or_404(models.Car, pk=self.kwargs["car_pk"]) @@ -734,11 +740,12 @@ class CarColorCreate(LoginRequiredMixin, CreateView): context["car"] = get_object_or_404(models.Car, pk=self.kwargs["car_pk"]) return context -class CarListView(LoginRequiredMixin, ListView): +class CarListView(LoginRequiredMixin,PermissionRequiredMixin, ListView): model = models.Car template_name = "inventory/car_list_view.html" context_object_name = "cars" paginate_by = 20 + permission_required = 'inventory.view_car' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) dealer = get_user_type(self.request) @@ -882,16 +889,17 @@ def inventory_stats_view(request): return render(request, "inventory/inventory_stats.html", {"inventory": result}) -class CarDetailView(LoginRequiredMixin, DetailView): +class CarDetailView(LoginRequiredMixin,PermissionRequiredMixin, DetailView): model = models.Car template_name = "inventory/car_detail.html" context_object_name = "car" + permission_required = ['inventory.view_car'] - -class CarFinanceCreateView(LoginRequiredMixin, CreateView): +class CarFinanceCreateView(LoginRequiredMixin,PermissionRequiredMixin, CreateView): model = models.CarFinance form_class = forms.CarFinanceForm template_name = "inventory/car_finance_form.html" + permission_required = ['inventory.add_carfinance'] def dispatch(self, request, *args, **kwargs): self.car = get_object_or_404(models.Car, pk=self.kwargs["car_pk"]) @@ -919,11 +927,12 @@ class CarFinanceCreateView(LoginRequiredMixin, CreateView): return form -class CarFinanceUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): +class CarFinanceUpdateView(LoginRequiredMixin,PermissionRequiredMixin, SuccessMessageMixin, UpdateView): model = models.CarFinance form_class = forms.CarFinanceForm template_name = "inventory/car_finance_form.html" success_message = _("Car finance details updated successfully.") + permission_required = ['inventory.change_carfinance'] def get_success_url(self): return reverse("car_detail", kwargs={"pk": self.object.car.pk}) @@ -948,30 +957,33 @@ class CarFinanceUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): return form -class CarUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): +class CarUpdateView(LoginRequiredMixin,PermissionRequiredMixin, SuccessMessageMixin, UpdateView): model = models.Car form_class = forms.CarUpdateForm template_name = "inventory/car_edit.html" success_message = _("Car updated successfully.") + permission_required = ['inventory.change_car'] def get_success_url(self): return reverse("car_detail", kwargs={"pk": self.object.pk}) -class CarDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteView): +class CarDeleteView(LoginRequiredMixin,PermissionRequiredMixin, SuccessMessageMixin, DeleteView): model = models.Car template_name = "inventory/car_confirm_delete.html" success_url = reverse_lazy("inventory_stats") + permission_required = ['inventory.delete_car'] def delete(self, request, *args, **kwargs): messages.success(request, _("Car deleted successfully.")) return super().delete(request, *args, **kwargs) -class CarLocationCreateView(CreateView): +class CarLocationCreateView(LoginRequiredMixin,PermissionRequiredMixin,CreateView): model = models.CarLocation form_class = forms.CarLocationForm template_name = "inventory/car_location_form.html" + permission_required = ['inventory.add_carlocation'] def get_success_url(self): return reverse_lazy("car_detail", kwargs={"pk": self.object.car.pk}) @@ -985,7 +997,7 @@ class CarLocationCreateView(CreateView): return super().form_valid(form) -class CarLocationUpdateView(UpdateView): +class CarLocationUpdateView(LoginRequiredMixin,UpdateView): model = models.CarLocation form_class = forms.CarLocationForm template_name = "inventory/car_location_form.html" @@ -994,7 +1006,7 @@ class CarLocationUpdateView(UpdateView): return reverse_lazy("car_detail", kwargs={"pk": self.object.car.pk}) -class CarTransferCreateView(CreateView): +class CarTransferCreateView(LoginRequiredMixin,CreateView): model = models.CarTransfer form_class = forms.CarTransferForm template_name = "inventory/car_transfer_form.html" @@ -1030,6 +1042,8 @@ class CarTransferDetailView(LoginRequiredMixin, SuccessMessageMixin, DetailView) context = super().get_context_data(**kwargs) context["action"] = self.request.GET.get("action") return context + +@login_required def car_transfer_approve(request, car_pk, transfer_pk): car = get_object_or_404(models.Car, pk=car_pk) transfer = get_object_or_404(models.CarTransfer, pk=transfer_pk) @@ -1061,6 +1075,7 @@ def car_transfer_approve(request, car_pk, transfer_pk): return redirect("car_detail", pk=car.pk) +@login_required def car_transfer_accept_reject(request, car_pk, transfer_pk): car = get_object_or_404(models.Car, pk=car_pk) transfer = get_object_or_404(models.CarTransfer, pk=transfer_pk) @@ -1089,6 +1104,7 @@ def car_transfer_accept_reject(request, car_pk, transfer_pk): return redirect("inventory_stats") +@login_required def CarTransferPreviewView(request, car_pk, transfer_pk): transfer = get_object_or_404(models.CarTransfer, pk=transfer_pk) if transfer.to_dealer != get_user_type(request): @@ -1217,13 +1233,14 @@ class DealerUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): def get_success_url(self): return reverse("dealer_detail", kwargs={"pk": self.object.pk}) -class CustomerListView(LoginRequiredMixin, ListView): +class CustomerListView(LoginRequiredMixin,PermissionRequiredMixin, ListView): model = CustomerModel home_label = _("customers") context_object_name = "customers" paginate_by = 10 template_name = "customers/customer_list.html" ordering = ["-created"] + permission_required = ['django_ledger.view_customermodel'] def get_queryset(self): query = self.request.GET.get("q") @@ -1237,10 +1254,11 @@ class CustomerListView(LoginRequiredMixin, ListView): return context -class CustomerDetailView(LoginRequiredMixin, DetailView): +class CustomerDetailView(LoginRequiredMixin,PermissionRequiredMixin, DetailView): model = CustomerModel template_name = "customers/view_customer.html" context_object_name = "customer" + permission_required = ['django_ledger.view_customermodel'] def get_context_data(self, **kwargs): dealer = get_user_type(self.request) @@ -1256,8 +1274,9 @@ class CustomerDetailView(LoginRequiredMixin, DetailView): context["total"] = total return context -def add_note_to_customer(request, customer_id): - customer = get_object_or_404(CustomerModel, pk=customer_id) +@login_required +def add_note_to_customer(request, customer_id): + customer = get_object_or_404(CustomerModel, uuid=customer_id) if request.method == "POST": form = forms.NoteForm(request.POST) if form.is_valid(): @@ -1272,6 +1291,7 @@ def add_note_to_customer(request, customer_id): return render(request, "customers/note_form.html", {"form": form, "customer": customer}) +@login_required def add_activity_to_customer(request, pk): customer = get_object_or_404(CustomerModel, pk=pk) if request.method == "POST": @@ -1289,6 +1309,8 @@ def add_activity_to_customer(request, pk): ) +@login_required +@permission_required('django_ledger.add_customermodel',raise_exception=True) def CustomerCreateView(request): form = forms.CustomerForm() if request.method == "POST": @@ -1333,6 +1355,8 @@ def CustomerCreateView(request): return render(request, "customers/customer_form.html", {"form": form}) +@login_required +@permission_required('django_ledger.change_customermodel',raise_exception=True) def CustomerUpdateView(request, pk): customer = get_object_or_404(CustomerModel, pk=pk) if request.method == "POST": @@ -1403,6 +1427,7 @@ class VendorListView(LoginRequiredMixin, ListView): vendors = dealer.entity.get_vendors().filter(active=True) return apply_search_filters(vendors, query) +@login_required def vendorDetailView(request, pk): vendor = get_object_or_404(models.Vendor, pk=pk) return render(request, template_name="vendors/view_vendor.html", context={"vendor": vendor}) @@ -1498,16 +1523,19 @@ class GroupUpdateView( def form_valid(self, form): dealer = get_user_type(self.request) instance = form.save(commit=False) + instance.set_defualt_permissions() instance.group.name = f"{dealer.pk}_{instance.name}" instance.save() return super().form_valid(form) +@login_required def GroupDeleteview(request, pk): group = get_object_or_404(models.CustomGroup, pk=pk) group.delete() messages.success(request, _("Group deleted successfully.")) return redirect("group_list") +@login_required def GroupPermissionView(request, pk): group = get_object_or_404(models.CustomGroup, pk=pk) if request.method == "POST": @@ -1522,7 +1550,7 @@ def GroupPermissionView(request, pk): return render(request,"groups/group_permission_form.html",{"group": group, "form": form}) # Users - +@login_required def UserGroupView(request, pk): staff = get_object_or_404(models.Staff, pk=pk) @@ -1597,10 +1625,11 @@ class UserCreateView( staff = form.save(commit=False) staff.staff_member = staff_member staff.dealer = dealer + staff.add_as_manager() group = Group.objects.filter(customgroup__name__iexact=staff.staff_type).first() + staff.save() if group: staff.add_group(group) - staff.save() return super().form_valid(form) @@ -1642,9 +1671,11 @@ class UserUpdateView( staff.arabic_name = form.cleaned_data["arabic_name"] staff.phone_number = form.cleaned_data["phone_number"] staff.staff_type = form.cleaned_data["staff_type"] + staff.add_as_manager() staff.save() return super().form_valid(form) +@login_required def UserDeleteview(request, pk): staff = get_object_or_404(models.Staff, pk=pk) staff.staff_member.delete() @@ -1653,23 +1684,6 @@ def UserDeleteview(request, pk): return redirect("user_list") -# errors -def custom_page_not_found_view(request, exception): - return render(request, "errors/404.html", {}) - - -def custom_error_view(request, exception=None): - return render(request, "errors/500.html", {}) - - -def custom_permission_denied_view(request, exception=None): - return render(request, "errors/403.html", {}) - - -def custom_bad_request_view(request, exception=None): - return render(request, "errors/400.html", {}) - - class OrganizationListView(LoginRequiredMixin, ListView): model = CustomerModel template_name = "organizations/organization_list.html" @@ -1684,12 +1698,13 @@ class OrganizationListView(LoginRequiredMixin, ListView): return apply_search_filters(organization, query) -class OrganizationDetailView(DetailView): +class OrganizationDetailView(LoginRequiredMixin,DetailView): model = CustomerModel template_name = "organizations/organization_detail.html" context_object_name = "organization" +@login_required def OrganizationCreateView(request): if request.method == "POST": form = forms.OrganizationForm(request.POST) @@ -1728,6 +1743,7 @@ def OrganizationCreateView(request): return render(request, "organizations/organization_form.html", {"form": form}) +@login_required def OrganizationUpdateView(request,pk): organization = get_object_or_404(CustomerModel, pk=pk) if request.method == "POST": @@ -1774,6 +1790,7 @@ def OrganizationUpdateView(request,pk): # template_name = "organizations/organization_confirm_delete.html" # success_url = reverse_lazy("organization_list") # success_message = "Organization deleted successfully." +@login_required def OrganizationDeleteView(request, pk): organization = get_object_or_404(CustomerModel, pk=pk) try: @@ -1798,7 +1815,7 @@ class RepresentativeListView(LoginRequiredMixin, ListView): return apply_search_filters(representative, query) -class RepresentativeDetailView(DetailView): +class RepresentativeDetailView(LoginRequiredMixin,DetailView): model = models.Representative template_name = "representatives/representative_detail.html" context_object_name = "representative" @@ -1836,11 +1853,12 @@ class RepresentativeDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteVi # BANK ACCOUNT -class BankAccountListView(LoginRequiredMixin, ListView): +class BankAccountListView(LoginRequiredMixin,PermissionRequiredMixin, ListView): model = BankAccountModel template_name = "ledger/bank_accounts/bank_account_list.html" context_object_name = "bank_accounts" paginate_by = 10 + permission_required = ['inventory.view_carfinance'] def get_queryset(self): query = self.request.GET.get("q") @@ -1849,12 +1867,13 @@ class BankAccountListView(LoginRequiredMixin, ListView): return apply_search_filters(bank_accounts, query) -class BankAccountCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView): +class BankAccountCreateView(LoginRequiredMixin,PermissionRequiredMixin, SuccessMessageMixin, CreateView): model = BankAccountModel form_class = BankAccountCreateForm template_name = "ledger/bank_accounts/bank_account_form.html" success_url = reverse_lazy("bank_account_list") success_message = "Bank account created successfully." + permission_required = ['inventory.view_carfinance'] def form_valid(self, form): dealer = get_user_type(self.request) @@ -1870,18 +1889,20 @@ class BankAccountCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView) return kwargs -class BankAccountDetailView(LoginRequiredMixin, DetailView): +class BankAccountDetailView(LoginRequiredMixin,PermissionRequiredMixin, DetailView): model = BankAccountModel template_name = "ledger/bank_accounts/bank_account_detail.html" context_object_name = "bank_account" + permission_required = ['inventory.view_carfinance'] -class BankAccountUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): +class BankAccountUpdateView(LoginRequiredMixin,PermissionRequiredMixin, SuccessMessageMixin, UpdateView): model = BankAccountModel form_class = BankAccountUpdateForm template_name = "ledger/bank_accounts/bank_account_form.html" success_url = reverse_lazy("bank_account_list") success_message = "Bank account updated successfully." + permission_required = ['inventory.view_carfinance'] def get_form_kwargs(self): dealer = get_user_type(self.request) @@ -1907,11 +1928,12 @@ def bank_account_delete(request, pk): # Accounts -class AccountListView(LoginRequiredMixin, ListView): +class AccountListView(LoginRequiredMixin,PermissionRequiredMixin, ListView): model = AccountModel template_name = "ledger/coa_accounts/account_list.html" context_object_name = "accounts" paginate_by = 10 + permission_required = ['inventory.view_carfinance'] def get_queryset(self): query = self.request.GET.get("q") @@ -1920,12 +1942,13 @@ class AccountListView(LoginRequiredMixin, ListView): return apply_search_filters(accounts, query) -class AccountCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView): +class AccountCreateView(LoginRequiredMixin,PermissionRequiredMixin, SuccessMessageMixin, CreateView): model = AccountModel form_class = AccountModelCreateForm template_name = "ledger/coa_accounts/account_form.html" success_url = reverse_lazy("account_list") success_message = "Account created successfully." + permission_required = ['inventory.view_carfinance'] def form_valid(self, form): dealer = get_user_type(self.request) @@ -1948,12 +1971,13 @@ class AccountCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView): return form -class AccountDetailView(LoginRequiredMixin, DetailView): +class AccountDetailView(LoginRequiredMixin,PermissionRequiredMixin, DetailView): model = AccountModel template_name = "ledger/coa_accounts/account_detail.html" context_object_name = "account" slug_field = "uuid" DEFAULT_TXS_DAYS = 30 + permission_required = ['inventory.view_carfinance'] extra_context = { "DEFAULT_TXS_DAYS": DEFAULT_TXS_DAYS, "header_subtitle_icon": "ic:round-account-tree", @@ -1985,12 +2009,13 @@ class AccountDetailView(LoginRequiredMixin, DetailView): return context -class AccountUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): +class AccountUpdateView(LoginRequiredMixin,PermissionRequiredMixin, SuccessMessageMixin, UpdateView): model = AccountModel form_class = AccountModelUpdateForm template_name = "ledger/coa_accounts/account_form.html" success_url = reverse_lazy("account_list") success_message = "Account updated successfully." + permission_required = ['inventory.view_carfinance'] def get_form(self, form_class=None): form = super().get_form(form_class) @@ -2000,6 +2025,7 @@ class AccountUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): @login_required +@permission_required('inventory.view_carfinance') def account_delete(request, pk): account = get_object_or_404(AccountModel, pk=pk) @@ -2010,6 +2036,7 @@ def account_delete(request, pk): # Sales list @login_required +@permission_required('inventory.view_lead',raise_exception=True) def sales_list_view(request): dealer = get_user_type(request) entity = dealer.entity @@ -2024,11 +2051,12 @@ def sales_list_view(request): # Estimates -class EstimateListView(LoginRequiredMixin, ListView): +class EstimateListView(LoginRequiredMixin,PermissionRequiredMixin, ListView): model = EstimateModel template_name = "sales/estimates/estimate_list.html" context_object_name = "estimates" paginate_by = 20 + permission_required = ['django_ledger.view_estimatemodel'] def get_queryset(self): dealer = get_user_type(self.request) @@ -2041,6 +2069,7 @@ class EstimateListView(LoginRequiredMixin, ListView): # @csrf_exempt @login_required +@permission_required('django_ledger.add_estimatemodel',raise_exception=True) def create_estimate(request,pk=None): dealer = get_user_type(request) entity = dealer.entity @@ -2202,10 +2231,11 @@ def create_estimate(request,pk=None): return render(request, "sales/estimates/estimate_form.html", context) -class EstimateDetailView(LoginRequiredMixin, DetailView): +class EstimateDetailView(LoginRequiredMixin, PermissionRequiredMixin,DetailView): model = EstimateModel template_name = "sales/estimates/estimate_detail.html" context_object_name = "estimate" + permission_required = ['django_ledger.view_estimatemodel'] def get_context_data(self, **kwargs): estimate = kwargs.get("object") @@ -2220,6 +2250,8 @@ class EstimateDetailView(LoginRequiredMixin, DetailView): return super().get_context_data(**kwargs) +@login_required +@permission_required('inventory.add_saleorder', raise_exception=True) def create_sale_order(request, pk): estimate = get_object_or_404(EstimateModel, pk=pk) items = estimate.get_itemtxs_data()[0].all() @@ -2254,6 +2286,7 @@ def create_sale_order(request, pk): ) +@login_required def preview_sale_order(request, pk): estimate = get_object_or_404(EstimateModel, pk=pk) data = get_car_finance_data(estimate) @@ -2264,10 +2297,11 @@ def preview_sale_order(request, pk): ) -class PaymentRequest(LoginRequiredMixin, DetailView): +class PaymentRequest(LoginRequiredMixin,PermissionRequiredMixin,DetailView): model = EstimateModel template_name = "sales/estimates/payment_request_detail.html" context_object_name = "estimate" + permission_required = ['django_ledger.view_invoicemodel'] def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) @@ -2279,10 +2313,11 @@ class PaymentRequest(LoginRequiredMixin, DetailView): return context -class EstimatePreviewView(DetailView): +class EstimatePreviewView(LoginRequiredMixin,PermissionRequiredMixin,DetailView): model = EstimateModel context_object_name = "estimate" template_name = "sales/estimates/estimate_preview.html" + permission_required = ['django_ledger.view_estimatemodel'] def get_context_data(self, **kwargs): estimate = kwargs.get("object") @@ -2298,6 +2333,7 @@ class EstimatePreviewView(DetailView): @login_required +@permission_required('django_ledger.change_estimatemodel', raise_exception=True) def estimate_mark_as(request, pk): estimate = get_object_or_404(EstimateModel, pk=pk) dealer = get_user_type(request) @@ -2331,6 +2367,12 @@ def estimate_mark_as(request, pk): messages.error(request, _("Estimate is not ready for cancelation")) return redirect("estimate_detail", pk=estimate.pk) estimate.mark_as_canceled() + try: + car = models.Car.objects.get(vin=estimate.get_itemtxs_data()[0].first().item_model.name) + car.status = "available" + car.save() + except Exception as e: + pass messages.success(request, _("Estimate canceled successfully.")) estimate.save() messages.success(request, "Estimate marked as " + mark.upper()) @@ -2339,11 +2381,12 @@ def estimate_mark_as(request, pk): # Invoice -class InvoiceListView(LoginRequiredMixin, ListView): +class InvoiceListView(LoginRequiredMixin,PermissionRequiredMixin, ListView): model = InvoiceModel template_name = "sales/invoices/invoice_list.html" context_object_name = "invoices" paginate_by = 20 + permission_required = ['django_ledger.view_invoicemodel'] def get_queryset(self): query = self.request.GET.get("q") @@ -2351,10 +2394,11 @@ class InvoiceListView(LoginRequiredMixin, ListView): invoices = dealer.entity.get_invoices() return apply_search_filters(invoices, query) -class InvoiceDetailView(LoginRequiredMixin, DetailView): +class InvoiceDetailView(LoginRequiredMixin,PermissionRequiredMixin, DetailView): model = InvoiceModel template_name = "sales/invoices/invoice_detail.html" context_object_name = "invoice" + permission_required = ['django_ledger.view_invoicemodel'] def get_context_data(self, **kwargs): invoice = kwargs.get("object") @@ -2370,11 +2414,12 @@ class InvoiceDetailView(LoginRequiredMixin, DetailView): return super().get_context_data(**kwargs) -class DraftInvoiceModelUpdateFormView(LoginRequiredMixin, UpdateView): +class DraftInvoiceModelUpdateFormView(LoginRequiredMixin,PermissionRequiredMixin, UpdateView): model = InvoiceModel form_class = DraftInvoiceModelUpdateForm template_name = "sales/invoices/draft_invoice_update.html" success_url = reverse_lazy("invoice_list") + permission_required = ['django_ledger.view_invoicemodel'] def get_form_kwargs(self): kwargs = super().get_form_kwargs() @@ -2384,11 +2429,12 @@ class DraftInvoiceModelUpdateFormView(LoginRequiredMixin, UpdateView): return kwargs -class ApprovedInvoiceModelUpdateFormView(LoginRequiredMixin, UpdateView): +class ApprovedInvoiceModelUpdateFormView(LoginRequiredMixin,PermissionRequiredMixin, UpdateView): model = InvoiceModel form_class = ApprovedInvoiceModelUpdateForm template_name = "sales/invoices/approved_invoice_update.html" success_url = reverse_lazy("invoice_list") + permission_required = ['django_ledger.view_invoicemodel'] def get_form_kwargs(self): kwargs = super().get_form_kwargs() @@ -2401,11 +2447,12 @@ class ApprovedInvoiceModelUpdateFormView(LoginRequiredMixin, UpdateView): return reverse_lazy("invoice_detail", kwargs={"pk": self.object.pk}) -class PaidInvoiceModelUpdateFormView(LoginRequiredMixin, UpdateView): +class PaidInvoiceModelUpdateFormView(LoginRequiredMixin,PermissionRequiredMixin, UpdateView): model = InvoiceModel form_class = PaidInvoiceModelUpdateForm template_name = "sales/invoices/paid_invoice_update.html" success_url = reverse_lazy("invoice_list") + permission_required = ['django_ledger.view_invoicemodel'] def get_form_kwargs(self): kwargs = super().get_form_kwargs() @@ -2430,6 +2477,7 @@ class PaidInvoiceModelUpdateFormView(LoginRequiredMixin, UpdateView): @login_required +@permission_required('django_ledger.change_invoicemodel',raise_exception=True) def invoice_mark_as(request, pk): invoice = get_object_or_404(InvoiceModel, pk=pk) dealer = get_user_type(request) @@ -2445,6 +2493,8 @@ def invoice_mark_as(request, pk): return redirect("invoice_detail", pk=invoice.pk) +@login_required +@permission_required('django_ledger.add_invoicemodel',raise_exception=True) def invoice_create(request, pk): estimate = get_object_or_404(EstimateModel, pk=pk) dealer = get_user_type(request) @@ -2507,10 +2557,11 @@ def invoice_create(request, pk): return render(request, "sales/invoices/invoice_create.html", context) -class InvoicePreviewView(LoginRequiredMixin, DetailView): +class InvoicePreviewView(LoginRequiredMixin,PermissionRequiredMixin, DetailView): model = InvoiceModel context_object_name = "invoice" template_name = "sales/invoices/invoice_preview.html" + permission_required = ['django_ledger.view_invoicemodel'] def get_context_data(self, **kwargs): dealer = get_user_type(self.request) @@ -2524,6 +2575,8 @@ class InvoicePreviewView(LoginRequiredMixin, DetailView): # payments +@login_required +@permission_required('django_ledger.add_journalentrymodel',raise_exception=True) def PaymentCreateView(request, pk): invoice = InvoiceModel.objects.filter(pk=pk).first() bill = BillModel.objects.filter(pk=pk).first() @@ -2575,6 +2628,8 @@ def PaymentCreateView(request, pk): ) +@login_required +@permission_required('django_ledger.view_journalentrymodel',raise_exception=True) def PaymentListView(request): dealer = get_user_type(request) entity = dealer.entity @@ -2582,6 +2637,8 @@ def PaymentListView(request): return render(request, "sales/payments/payment_list.html", {"journals": journals}) +@login_required +@permission_required('django_ledger.view_journalentrymodel',raise_exception=True) def PaymentDetailView(request, pk): journal = JournalEntryModel.objects.filter(pk=pk).first() transactions = ( @@ -2596,6 +2653,8 @@ def PaymentDetailView(request, pk): ) +@login_required +@permission_required('django_ledger.change_journalentrymodel',raise_exception=True) def payment_mark_as_paid(request, pk): invoice = get_object_or_404(InvoiceModel, pk=pk) if request.method == "POST": @@ -2625,7 +2684,7 @@ def payment_mark_as_paid(request, pk): # activity log -class UserActivityLogListView(ListView): +class UserActivityLogListView(LoginRequiredMixin,ListView): model = models.UserActivityLog template_name = "dealers/activity_log.html" context_object_name = "logs" @@ -2639,11 +2698,12 @@ class UserActivityLogListView(ListView): # CRM RELATED VIEWS -class LeadListView(ListView): +class LeadListView(LoginRequiredMixin,PermissionRequiredMixin,ListView): model = models.Lead template_name = "crm/leads/lead_list.html" context_object_name = "leads" paginate_by = 10 + permission_required = ['inventory.view_lead'] def get_queryset(self): dealer = get_user_type(self.request) @@ -2656,9 +2716,10 @@ class LeadListView(ListView): return models.Lead.objects.none() -class LeadDetailView(DetailView): +class LeadDetailView(LoginRequiredMixin,PermissionRequiredMixin,DetailView): model = models.Lead template_name = "crm/leads/lead_detail.html" + permission_required = ['inventory.view_lead'] def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) @@ -2682,6 +2743,8 @@ class LeadDetailView(DetailView): return context +@login_required +@permission_required('inventory.add_lead',raise_exception=True) def lead_create(request): form = forms.LeadForm() make = request.GET.get("id_car_make", None) @@ -2746,11 +2809,12 @@ def lead_create(request): return render(request, "crm/leads/lead_form.html", {"form": form}) -class LeadUpdateView(UpdateView): +class LeadUpdateView(LoginRequiredMixin,PermissionRequiredMixin,UpdateView): model = models.Lead form_class = forms.LeadForm template_name = "crm/leads/lead_form.html" success_url = reverse_lazy("lead_list") + permission_required = ['inventory.change_lead'] def get_form(self, form_class=None): form = super().get_form(form_class) @@ -2759,6 +2823,7 @@ class LeadUpdateView(UpdateView): @login_required +@permission_required('inventory.delete_lead',raise_exception=True) def LeadDeleteView(request,pk): lead = get_object_or_404(models.Lead, pk=pk) try: @@ -2772,6 +2837,7 @@ def LeadDeleteView(request,pk): @login_required +@permission_required('inventory.add_notes',raise_exception=True) def add_note_to_lead(request, pk): lead = get_object_or_404(models.Lead, pk=pk) if request.method == "POST": @@ -2788,6 +2854,7 @@ def add_note_to_lead(request, pk): return render(request, "crm/note_form.html", {"form": form, "lead": lead}) @login_required +@permission_required('inventory.add_notes',raise_exception=True) def add_note_to_opportunity(request, pk): opportunity = get_object_or_404(models.Opportunity, pk=pk) if request.method == "POST": @@ -2801,6 +2868,7 @@ def add_note_to_opportunity(request, pk): @login_required +@permission_required('inventory.change_notes',raise_exception=True) def update_note(request, pk): note = get_object_or_404(models.Notes, pk=pk, created_by=request.user) lead_pk = note.content_object.pk @@ -2821,6 +2889,7 @@ def update_note(request, pk): @login_required +@permission_required('inventory.delete_notes',raise_exception=True) def delete_note(request, pk): note = get_object_or_404(models.Notes, pk=pk, created_by=request.user) lead_pk = note.content_object.pk @@ -2830,6 +2899,7 @@ def delete_note(request, pk): @login_required +@permission_required('inventory.change_lead',raise_exception=True) def lead_convert(request, pk): lead = get_object_or_404(models.Lead, pk=pk) dealer = get_user_type(request) @@ -2842,6 +2912,7 @@ def lead_convert(request, pk): return redirect("lead_list") @login_required +@permission_required('inventory.add_appointmentrequest',raise_exception=True) def schedule_lead(request, pk): if not request.is_staff: messages.error(request, "You do not have permission to schedule lead.") @@ -2895,6 +2966,7 @@ def schedule_lead(request, pk): @login_required +@permission_required('inventory.change_lead',raise_exception=True) def lead_transfer(request,pk): lead = get_object_or_404(models.Lead, pk=pk) if request.method == "POST": @@ -2908,6 +2980,7 @@ def lead_transfer(request,pk): return redirect("lead_list") @login_required +@permission_required('inventory.add_email',raise_exception=True) def send_lead_email(request, pk,email_pk=None): lead = get_object_or_404(models.Lead, pk=pk) status = request.GET.get("status") @@ -3019,7 +3092,7 @@ class OpportunityCreateView(CreateView, LoginRequiredMixin): return reverse_lazy("opportunity_detail", kwargs={"pk": self.object.pk}) -class OpportunityUpdateView(UpdateView, LoginRequiredMixin): +class OpportunityUpdateView(LoginRequiredMixin,UpdateView): model = models.Opportunity form_class = forms.OpportunityForm template_name = "crm/opportunities/opportunity_form.html" @@ -3028,7 +3101,7 @@ class OpportunityUpdateView(UpdateView, LoginRequiredMixin): return reverse_lazy("opportunity_detail", kwargs={"pk": self.object.pk}) -class OpportunityDetailView(DetailView): +class OpportunityDetailView(LoginRequiredMixin,DetailView): model = models.Opportunity template_name = "crm/opportunities/opportunity_detail.html" context_object_name = "opportunity" @@ -3052,7 +3125,7 @@ class OpportunityDetailView(DetailView): return context -class OpportunityListView(ListView): +class OpportunityListView(LoginRequiredMixin,ListView): model = models.Opportunity template_name = "crm/opportunities/opportunity_list.html" context_object_name = "opportunities" @@ -3069,6 +3142,7 @@ def delete_opportunity(request, pk): messages.success(request, _("Opportunity deleted successfully.")) return redirect("opportunity_list") +@login_required def opportunity_update_status(request,pk): opportunity = get_object_or_404(models.Opportunity, pk=pk) status = request.GET.get("status") @@ -3113,13 +3187,14 @@ def fetch_notifications(request): return render(request, "notifications.html", {"notifications_": notifications}) -class ItemServiceCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView): +class ItemServiceCreateView(LoginRequiredMixin,PermissionRequiredMixin, SuccessMessageMixin, CreateView): model = models.AdditionalServices form_class = forms.AdditionalServiceForm template_name = "items/service/service_create.html" success_url = reverse_lazy("item_service_list") success_message = _("Service created successfully.") context_object_name = "service" + permission_required = ["django_ledger.add_itemmodel"] def form_valid(self, form): vat = models.VatRate.objects.get(is_active=True) @@ -3130,13 +3205,14 @@ class ItemServiceCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView) return super().form_valid(form) -class ItemServiceUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): +class ItemServiceUpdateView(LoginRequiredMixin,PermissionRequiredMixin, SuccessMessageMixin, UpdateView): model = models.AdditionalServices form_class = forms.AdditionalServiceForm template_name = "items/service/service_create.html" success_url = reverse_lazy("item_service_list") success_message = _("Service updated successfully.") context_object_name = "service" + permission_required = ["django_ledger.change_itemmodel"] def form_valid(self, form): vat = models.VatRate.objects.get(is_active=True) @@ -3147,22 +3223,24 @@ class ItemServiceUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView) return super().form_valid(form) -class ItemServiceListView(ListView, LoginRequiredMixin): +class ItemServiceListView(LoginRequiredMixin,PermissionRequiredMixin,ListView): model = models.AdditionalServices template_name = "items/service/service_list.html" context_object_name = "services" paginate_by = 20 + permission_required = ["django_ledger.view_itemmodel"] def get_queryset(self): dealer = get_user_type(self.request) return models.AdditionalServices.objects.filter(dealer=dealer).all() -class ItemExpenseCreateView(CreateView, LoginRequiredMixin): +class ItemExpenseCreateView(LoginRequiredMixin,PermissionRequiredMixin, CreateView): model = ItemModel form_class = ExpenseItemCreateForm template_name = "items/expenses/expense_create.html" success_url = reverse_lazy("item_expense_list") + permission_required = ["django_ledger.add_itemmodel"] def get_form_kwargs(self): dealer = get_user_type(self.request) @@ -3177,11 +3255,12 @@ class ItemExpenseCreateView(CreateView, LoginRequiredMixin): return super().form_valid(form) -class ItemExpenseUpdateView(UpdateView, LoginRequiredMixin): +class ItemExpenseUpdateView(LoginRequiredMixin,PermissionRequiredMixin, UpdateView): model = ItemModel form_class = ExpenseItemUpdateForm template_name = "items/expenses/expense_update.html" success_url = reverse_lazy("item_expense_list") + permission_required = ["django_ledger.change_itemmodel"] def get_form_kwargs(self): dealer = get_user_type(self.request) @@ -3196,21 +3275,23 @@ class ItemExpenseUpdateView(UpdateView, LoginRequiredMixin): return super().form_valid(form) -class ItemExpenseListView(ListView, LoginRequiredMixin): +class ItemExpenseListView(LoginRequiredMixin,PermissionRequiredMixin,ListView): model = ItemModel template_name = "items/expenses/expenses_list.html" context_object_name = "expenses" paginate_by = 20 + permission_required = ["django_ledger.view_itemmodel"] def get_queryset(self): dealer = get_user_type(self.request) return dealer.entity.get_items_expenses() -class BillListView(ListView, LoginRequiredMixin): +class BillListView(LoginRequiredMixin,PermissionRequiredMixin, ListView): model = BillModel template_name = "ledger/bills/bill_list.html" context_object_name = "bills" + permission_required = ["django_ledger.view_billmodel"] def get_queryset(self): dealer = get_user_type(self.request) @@ -3218,10 +3299,11 @@ class BillListView(ListView, LoginRequiredMixin): return qs -class BillDetailView(LoginRequiredMixin, DetailView): +class BillDetailView(LoginRequiredMixin,PermissionRequiredMixin, DetailView): model = BillModel template_name = "ledger/bills/bill_detail.html" context_object_name = "bill" + permission_required = ["django_ledger.view_billmodel"] def get_context_data(self, **kwargs): bill = kwargs.get("object") @@ -3246,13 +3328,14 @@ class BillDetailView(LoginRequiredMixin, DetailView): return super().get_context_data(**kwargs) -class InReviewBillView(LoginRequiredMixin, UpdateView): +class InReviewBillView(LoginRequiredMixin,PermissionRequiredMixin, UpdateView): model = BillModel form_class = InReviewBillModelUpdateForm template_name = "ledger/bills/bill_update_form.html" success_url = reverse_lazy("bill_list") success_message = _("Bill updated successfully.") context_object_name = "bill" + permission_required = ["django_ledger.change_billmodel"] def get_form_kwargs(self): kwargs = super().get_form_kwargs() @@ -3271,13 +3354,14 @@ class InReviewBillView(LoginRequiredMixin, UpdateView): return super().form_valid(form) -class ApprovedBillModelView(LoginRequiredMixin, UpdateView): +class ApprovedBillModelView(LoginRequiredMixin,PermissionRequiredMixin, UpdateView): model = BillModel form_class = ApprovedBillModelUpdateForm template_name = "ledger/bills/bill_update_form.html" success_url = reverse_lazy("bill_list") success_message = _("Bill updated successfully.") context_object_name = "bill" + permission_required = ["django_ledger.change_billmodel"] def get_form_kwargs(self): kwargs = super().get_form_kwargs() @@ -3298,6 +3382,7 @@ class ApprovedBillModelView(LoginRequiredMixin, UpdateView): @login_required +@permission_required("django_ledger.change_billmodel", raise_exception=True) def bill_mark_as_approved(request, pk): bill = get_object_or_404(BillModel, pk=pk) if request.method == "POST": @@ -3312,6 +3397,7 @@ def bill_mark_as_approved(request, pk): @login_required +@permission_required("django_ledger.change_billmodel", raise_exception=True) def bill_mark_as_paid(request, pk): bill = get_object_or_404(BillModel, pk=pk) if request.method == "POST": @@ -3332,6 +3418,7 @@ def bill_mark_as_paid(request, pk): return redirect("bill_detail", pk=bill.pk) @login_required +@permission_required("django_ledger.add_billmodel", raise_exception=True) def bill_create(request): dealer = get_user_type(request) entity = dealer.entity @@ -3448,16 +3535,18 @@ def bill_create(request): @login_required +@permission_required("django_ledger.delete_billmodel", raise_exception=True) def BillDeleteView(request, pk): bill = get_object_or_404(BillModel, pk=pk) bill.delete() return redirect("bill_list") # orders -class OrderListView(ListView): +class OrderListView(LoginRequiredMixin,PermissionRequiredMixin, ListView): model = models.SaleOrder template_name = "sales/orders/order_list.html" context_object_name = "orders" + permission_required = ["inventory.view_saleorder"] def get_queryset(self): dealer = get_user_type(self.request) @@ -3466,6 +3555,7 @@ class OrderListView(ListView): # email @login_required +@permission_required("django_ledger.view_estimate", raise_exception=True) def send_email_view(request, pk): estimate = get_object_or_404(EstimateModel, pk=pk) if request.method == "POST": @@ -3516,7 +3606,7 @@ def send_email_view(request, pk): # errors -def custom_page_not_found_view(request, exception): +def custom_page_not_found_view(request, exception=None): return render(request, "errors/404.html", {}) @@ -3533,7 +3623,7 @@ def custom_bad_request_view(request, exception=None): # BALANCE SHEET -class BaseBalanceSheetRedirectView(DjangoLedgerSecurityMixIn, RedirectView): +class BaseBalanceSheetRedirectView(RedirectView): def get_redirect_url(self, *args, **kwargs): year = get_localdate().year return reverse( @@ -3541,10 +3631,20 @@ class BaseBalanceSheetRedirectView(DjangoLedgerSecurityMixIn, RedirectView): kwargs={"entity_slug": self.kwargs["entity_slug"], "year": year}, ) + def get_login_url(self): + return reverse('account_login') class FiscalYearBalanceSheetViewBase(FiscalYearBalanceSheetView,DjangoLedgerSecurityMixIn): template_name = "ledger/reports/balance_sheet.html" + # AUTHORIZE_SUPERUSER = False + # permission_required = [] + # def get_authorized_entity_queryset(self): + # dealer = get_user_type(self.request) + # return EntityModel.objects.filter(admin=dealer) + + def get_login_url(self): + return reverse('account_login') class QuarterlyBalanceSheetView(FiscalYearBalanceSheetViewBase, QuarterlyReportMixIn, DjangoLedgerSecurityMixIn): """ @@ -3574,11 +3674,13 @@ class BaseIncomeStatementRedirectViewBase(BaseIncomeStatementRedirectView, Djang return reverse( "entity-ic-year", kwargs={"entity_slug": dealer.entity.slug, "year": year} ) - - + def get_login_url(self): + return reverse('account_login') class FiscalYearIncomeStatementViewBase(FiscalYearIncomeStatementView, DjangoLedgerSecurityMixIn): template_name = "ledger/reports/income_statement.html" - + permission_required = ['inventory.view_carfinance'] + def get_login_url(self): + return reverse('account_login') class QuarterlyIncomeStatementView( FiscalYearIncomeStatementViewBase, QuarterlyReportMixIn, DjangoLedgerSecurityMixIn @@ -3610,11 +3712,14 @@ class BaseCashFlowStatementRedirectViewBase(BaseCashFlowStatementRedirectView, D return reverse( "entity-cf-year", kwargs={"entity_slug": dealer.entity.slug, "year": year} ) - + def get_login_url(self): + return reverse('account_login') class FiscalYearCashFlowStatementViewBase(FiscalYearCashFlowStatementView, DjangoLedgerSecurityMixIn): template_name = "ledger/reports/cash_flow_statement.html" - + permission_required = ['inventory.view_carfinance'] + def get_login_url(self): + return reverse('account_login') class QuarterlyCashFlowStatementView( FiscalYearCashFlowStatementViewBase, QuarterlyReportMixIn, DjangoLedgerSecurityMixIn @@ -3696,7 +3801,9 @@ class FiscalYearEntityModelDashboardView(EntityModelDetailBaseViewBase, DjangoLe """ Entity Fiscal Year Dashboard View. """ - + permission_required = ['inventory.view_carfinance'] + def get_login_url(self): + return reverse('account_login') class QuarterlyEntityDashboardView(FiscalYearEntityModelDashboardView, QuarterlyReportMixIn, DjangoLedgerSecurityMixIn): """ @@ -3816,7 +3923,7 @@ class PnLAPIView(DjangoLedgerSecurityMixIn, EntityUnitMixIn, View): }, status=401) -class EmployeeCalendarView(ListView): +class EmployeeCalendarView(LoginRequiredMixin, ListView): template_name = 'crm/employee_calendar.html' model = Appointment context_object_name = 'appointments' @@ -3831,7 +3938,6 @@ class EmployeeCalendarView(ListView): return apply_search_filters(appointments, query) - def apply_search_filters(queryset, query): if not query: return queryset @@ -3845,7 +3951,7 @@ def apply_search_filters(queryset, query): return queryset.filter(search_filters).distinct() -class CarListViewTable(ExportMixin, LoginRequiredMixin, SingleTableView): +class CarListViewTable(LoginRequiredMixin, ExportMixin, SingleTableView): model = models.Car table_class = tables.CarTable template_name = "inventory/car_list_table.html" @@ -3856,6 +3962,7 @@ class CarListViewTable(ExportMixin, LoginRequiredMixin, SingleTableView): "finances", "colors__exterior", "colors__interior" ).filter(dealer=dealer) +@login_required def DealerSettingsView(request,pk): dealer_setting = get_object_or_404(models.DealerSettings, pk=pk) dealer = get_user_type(request) @@ -3879,6 +3986,7 @@ def DealerSettingsView(request,pk): form.fields['bill_unearned_account'].queryset = dealer.entity.get_all_accounts().filter(role=roles.LIABILITY_CL_ACC_PAYABLE) return render(request, 'account/user_settings.html', {'form': form}) +@login_required def schedule_cancel(request,pk): schedule = get_object_or_404(models.Schedule, pk=pk) schedule.status = "Canceled" diff --git a/scripts/run.py b/scripts/run.py index b853355f..30c3b438 100644 --- a/scripts/run.py +++ b/scripts/run.py @@ -1,8 +1,9 @@ +from django.contrib.auth.models import Permission from django.contrib.auth.models import Group 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 +from django_ledger.models import EstimateModel,EntityModel,ItemModel,ItemTransactionModel,AccountModel,CustomerModel,EntityManagementModel from rich import print from datetime import date from inventory.models import Car, Dealer, VatRate,Lead,CarMake,CarModel,Schedule,CustomGroup @@ -16,10 +17,10 @@ import hashlib User = get_user_model() -def run(): +def run(): # print(Service.objects.first().pk) # print(Appointment.objects.first().client) - + # appointment = Appointment.objects.create( # client_name="John Doe", # client_email="john@example.com", @@ -41,7 +42,7 @@ def run(): # staff="John Doe", # priority="high", # ) - + # schedult = Schedule.objects.create( # name="John Doe", # email="john@example.com", @@ -57,27 +58,27 @@ def run(): # ) # now = timezone.now() # end_time = now + timedelta(minutes=10) - + # service = Service.objects.first() # appointment_request = AppointmentRequest.objects.create( # date=now.date(), - # start_time=now.time(), + # start_time=now.time(), # end_time=end_time.time(), # service=service, - # staff_member=StaffMember.objects.first(), + # staff_member=StaffMember.objects.first(), # ) - + # appointment = Appointment.objects.create( # client=User.objects.first(), # appointment_request=appointment_request, # phone="123-456-7890", - # address="123 Main St", + # address="123 Main St", # ) # dealer = Dealer.objects.get(user__email="ismail.mosa.ibrahim@gmail.com") # entity = dealer.entity - + # car_list = Car.objects.filter(dealer=dealer).all() - # context = { + # context = { # "items": [ # { # "car": x, @@ -94,7 +95,7 @@ def run(): # hash_object.update(f"{i.id_car_make.name}{i.id_car_model.name}".encode('utf-8')) # print(hash_object.hexdigest() , i.id_car_make.name, i.id_car_model.name) - + # def get_item(tx:ItemTransactionModel): # data = {"data": {}} # data["data"]["info"] = tx.item_model.additional_info.get('car_info') @@ -108,7 +109,7 @@ def run(): # data["data"]["has_invoice"] = True # data["data"]["customer"] = tx.invoice_model.customer # return data - + # transactions = ItemTransactionModel.objects.all() # output = [] # for transaction in transactions: @@ -119,21 +120,32 @@ def run(): # 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) - + # print(CustomerModel.objects.all()) # customer = CustomerModel.objects.first() # dealer = Dealer.objects.filter(user__email="esma3el555@gmail.com").first() # customer = CustomerModel.objects.filter(dealer=dealer).first() # print(Car.objects.filter(dealer=dealer,status="available")) - + # CustomGroup.objects.all().delete() # Group.objects.all().delete() - - dealer = Dealer.objects.filter(user__email="esma3el555@gmail.com").first() - group_names = ["Manager", "Inventory", "Accountant", "Agent", "Sales"] - for group_name in group_names: - group,created = Group.objects.get_or_create(name=f"{dealer.pk}_{group_name}") - group_manager,created = CustomGroup.objects.get_or_create(name=group_name, dealer=dealer, group=group) - group_manager.set_default_permissions() - - print(CustomGroup.objects.all()) \ No newline at end of file + + # dealer = Dealer.objects.filter(user__email="esma3el555@gmail.com").first() + # group_names = ["Manager", "Inventory", "Accountant", "Agent", "Sales"] + # for group_name in group_names: + # group,created = Group.objects.get_or_create(name=f"{dealer.pk}_{group_name}") + # group_manager,created = CustomGroup.objects.get_or_create(name=group_name, dealer=dealer, group=group) + # group_manager.set_default_permissions() + + # for perm in Permission.objects.filter(content_type__app_label='django_ledger',content_type__model__in=["estimatemodel","invoicemodel","customermodel"]): + # sales = CustomGroup.objects.last() + # sales.set_default_permissions() + # for perm in Permission.objects.filter(content_type__app_label='inventory',content_type__model__in=["lead","salequotation","salequotationcar"]): + # print(perm) + # print(Permission.objects.filter(codename__in=['view_car','view_carlocation','view_customcard','view_carcolors','view_cartransfer','view_estimatemodel','view_invoicemodel','view_saleorder'])) + # print(Permission.objects.filter(codename__in=['view_estimatemodel','view_invoicemodel','view_saleorder'])) + # CustomGroup.objects.filter(name='Accountant').last().set_default_permissions() + CustomGroup.objects.filter(name='Inventory').last().set_default_permissions() + + # EntityManagementModel.objects.create(entity=,user=) + # print(Permission.objects.filter(codename__icontains='customermodel').first().codename) diff --git a/templates/403.html b/templates/403.html new file mode 100644 index 00000000..73099d1b --- /dev/null +++ b/templates/403.html @@ -0,0 +1,92 @@ +{% load static i18n %} + + + + + Access Forbidden + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ +
+
+ +

Access Forbidden!

+

+ Halt! Thou art endeavouring to trespass upon a realm not granted unto thee.
granted unto thee. +

Go Home +
+
+
+
+
+
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/404.html b/templates/404.html new file mode 100644 index 00000000..a2857741 --- /dev/null +++ b/templates/404.html @@ -0,0 +1,90 @@ +{% load static i18n %} + + + + + Access Forbidden + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ +
+
+ +

Page Missing!

+

But no worries! Our ostrich is looking everywhere
while you wait safely.

Go Home +
+
+
+
+
+
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/500.html b/templates/500.html new file mode 100644 index 00000000..0b5739e9 --- /dev/null +++ b/templates/500.html @@ -0,0 +1,90 @@ +{% load static i18n %} + + + + + Access Forbidden + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ +
+
+ +

Unknow error!

+

But relax! Our cat is here to play you some music.

Go Home +
+
+
+
+
+
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/crm/leads/lead_list.html b/templates/crm/leads/lead_list.html index 869b0b04..cada3432 100644 --- a/templates/crm/leads/lead_list.html +++ b/templates/crm/leads/lead_list.html @@ -8,9 +8,11 @@
- + {% if perms.inventory.add_lead %} + + {% endif %}
@@ -217,14 +219,18 @@
{% endif %} diff --git a/templates/customers/customer_list.html b/templates/customers/customer_list.html index 355a9469..54fab4b8 100644 --- a/templates/customers/customer_list.html +++ b/templates/customers/customer_list.html @@ -10,9 +10,11 @@
- + {% if perms.django_ledger.add_customermodel %} + + {% endif %}
@@ -88,15 +90,19 @@ {{ customer.created|date }} + {% if perms.django_ledger.change_customermodel %} - + {% endif %} + {% if perms.django_ledger.delete_customermodel %} + + {% endif %} {% endfor %} diff --git a/templates/customers/view_customer.html b/templates/customers/view_customer.html index f6b8d5c8..736c2ea9 100644 --- a/templates/customers/view_customer.html +++ b/templates/customers/view_customer.html @@ -15,17 +15,20 @@
- + {% endif %}
- {{_("Update")}} - + {% if perms.django_ledger.change_customermodel %} + {{_("Update")}} + {% endif %}
diff --git a/templates/errors/403.html b/templates/errors/403.html index 3a741db3..bffc7d91 100644 --- a/templates/errors/403.html +++ b/templates/errors/403.html @@ -1,277 +1,8 @@ - - - - - - - - - - - - Phoenix - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-

Access Forbidden!

-

Halt! Thou art endeavouring to trespass upon a realm not granted unto thee.
granted unto thee.

Go Home -
-
-
-
-
- -
-
-
- - - -
-
- -
-
- - - - - -
-
-
-
-
Theme Customizer
-

Explore different styles according to your preferences

-
- -
- -
-
-
-
Color Scheme
-
-
- - -
-
- - -
-
- - -
-
-
-
-
-
RTL
-
- -
-
-

Change text direction

-
-
-
-
Support Chat
-
- -
-
-

Toggle support chat

-
-
-
Navigation Type
-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
-
Vertical Navbar Appearance
-
-
- - -
-
- - -
-
-
-
-
Horizontal Navbar Shape
-
-
- - -
-
- - -
-
-
-
-
Horizontal Navbar Appearance
-
-
- - -
-
- - -
-
-
Purchase template -
-
-
-
-
- - -
-
customize -
-
- - - - - - - - - - - - - - - - - - - \ No newline at end of file +
+
+
+

Access Forbidden!

+

Halt! Thou art endeavouring to trespass upon a realm not granted unto thee.
granted unto thee.

Go Home +
+
\ No newline at end of file diff --git a/templates/header.html b/templates/header.html index 9f99ab76..d82a9db0 100644 --- a/templates/header.html +++ b/templates/header.html @@ -2,7 +2,7 @@ {% if user.is_authenticated %}