Compare commits

...

23 Commits

Author SHA1 Message Date
2b3834ac10 Update On po upload 2025-06-26 18:59:08 +03:00
75c800d9de Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend 2025-06-26 18:00:09 +03:00
f09a18c7e9 update 2025-06-26 17:59:31 +03:00
f49c63da95 fix the uploaded 2025-06-26 17:59:13 +03:00
28b575139d Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend 2025-06-26 16:07:37 +03:00
3f85df0124 fix 2025-06-26 16:07:25 +03:00
d5b7e7fa7e Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend 2025-06-26 15:52:53 +03:00
80a3f69bbc update 2025-06-26 15:52:00 +03:00
51d0c11ffa updated the po_detail.html missing tags 2025-06-26 15:51:52 +03:00
2693f549a1 Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend 2025-06-26 12:55:50 +03:00
83c4707886 update 2025-06-26 12:53:44 +03:00
c3fbb3ea22 fix the cancel button in car confirm delete 2025-06-26 12:53:20 +03:00
77d4a76a65 Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend 2025-06-26 12:34:52 +03:00
49d90936fe update 2025-06-26 12:34:39 +03:00
640478d29b some fixes 2025-06-26 12:34:11 +03:00
bcb180c053 update 2025-06-26 12:04:26 +03:00
c1d329af64 update 2025-06-26 12:00:57 +03:00
c9fad7b79c fix the middleware issue 2025-06-26 12:00:16 +03:00
3a5ab31f83 add user and organization dealer slug 2025-06-26 11:40:58 +03:00
6c172fce3d update 2025-06-26 10:26:00 +03:00
630a9d95f7 Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend 2025-06-25 20:14:01 +03:00
bf8e0dd06f new update 2025-06-25 20:11:35 +03:00
9beeedd5bd add slug for the remaining of the apps 2025-06-25 20:10:12 +03:00
50 changed files with 433 additions and 376 deletions

View File

@ -97,7 +97,7 @@ class InjectDealerMiddleware:
request.is_staff = False
if hasattr(request.user, "dealer"):
request.is_dealer = True
if hasattr(request.user, "staffmember"):
elif hasattr(request.user, "staffmember"):
request.is_staff = True
except Exception:
pass
@ -122,10 +122,12 @@ class DealerSlugMiddleware:
return response
def process_view(self, request, view_func, view_args, view_kwargs):
if request.user.is_authenticated:
dealer = get_user_type(request)
if "dealer_slug" not in view_kwargs:
return redirect("home", dealer_slug=dealer.slug, **view_kwargs)
elif view_kwargs["dealer_slug"] != dealer.slug:
raise Http404("Dealer slug mismatch")
return None
if not request.user.is_authenticated:
return None
if request.path.startswith('/en/ledger/') or request.path.startswith('/ar/ledger/'):
return None
if not view_kwargs.get("dealer_slug"):
return None
dealer = get_user_type(request)
if view_kwargs["dealer_slug"] != dealer.slug:
raise Http404("Dealer slug mismatch")

View File

@ -31,6 +31,8 @@ from django_ledger.models import (
InvoiceModel,
AccountModel,
EntityManagementModel,
PurchaseOrderModel,
ItemTransactionModel,
)
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
@ -720,7 +722,9 @@ class Car(Base):
car=self, exterior=exterior, interior=interior
)
self.save()
@property
def logo(self):
return self.id_car_make.logo.url if self.id_car_make.logo else None
class CarTransfer(models.Model):
car = models.ForeignKey(
@ -2833,3 +2837,18 @@ class PaymentHistory(models.Model):
######################################################################################################
######################################################################################################
######################################################################################################
class PoItemsUploaded(models.Model):
dealer = models.ForeignKey(Dealer, on_delete=models.CASCADE, null=True, blank=True)
po = models.ForeignKey(
PurchaseOrderModel, on_delete=models.CASCADE, null=True, blank=True, related_name="items"
)
item = models.ForeignKey(
ItemTransactionModel,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="po_items",
)
status = models.CharField(max_length=100, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

View File

@ -13,6 +13,7 @@ from django_ledger.models import (
TransactionModel,
LedgerModel,
AccountModel,
PurchaseOrderModel
)
from . import models
from django.utils.timezone import now
@ -892,3 +893,10 @@ def update_finance_cost(sender, instance, created, **kwargs):
# save_journal(instance,ledger,vendor)
# else:
# save_journal(instance,ledger,vendor)
@receiver(post_save, sender=PurchaseOrderModel)
def create_po_item_upload(sender,instance,created,**kwargs):
if instance.po_status == "fulfilled":
for item in instance.get_itemtxs_data()[0]:
dealer = models.Dealer.objects.get(entity=instance.entity)
models.PoItemsUploaded.objects.create(dealer=dealer,po=instance, item=item, status="fulfilled")

View File

@ -50,12 +50,12 @@ urlpatterns = [
# path('tasks/<int:task_id>/detail/', views.task_detail, name='task_detail'),
# Dashboards
# path("user/<int:pk>/settings/", views.UserSettingsView.as_view(), name="user_settings"),
path("pricing/", views.pricing_page, name="pricing_page"),
path("submit_plan/", views.submit_plan, name="submit_plan"),
path("payment-callback/", views.payment_callback, name="payment_callback"),
path("<slug:dealer_slug>/pricing/", views.pricing_page, name="pricing_page"),
path("<slug:dealer_slug>/submit_plan/", views.submit_plan, name="submit_plan"),
path("<slug:dealer_slug>/payment-callback/", views.payment_callback, name="payment_callback"),
#
path(
"dealers/activity/",
"<slug:dealer_slug>/dealers/activity/",
views.UserActivityLogListView.as_view(),
name="dealer_activity",
),
@ -64,7 +64,7 @@ urlpatterns = [
views.DealerSettingsView,
name="dealer_settings",
),
path("dealers/assign-car-makes/", views.assign_car_makes, name="assign_car_makes"),
path("<slug:dealer_slug>/dealers/assign-car-makes/", views.assign_car_makes, name="assign_car_makes"),
path(
"dashboards/manager/",
views.ManagerDashboard.as_view(),
@ -76,7 +76,7 @@ urlpatterns = [
path("export/format/", TableExport, name="export"),
# Dealer URLs
path(
"dealers/<slug:slug>/", views.DealerDetailView.as_view(), name="dealer_detail"
"<slug:slug>/dealers/", views.DealerDetailView.as_view(), name="dealer_detail"
),
path(
"dealers/<slug:slug>/update/",
@ -267,21 +267,25 @@ urlpatterns = [
name="mark_notification_as_read",
),
path("crm/calender/", views.EmployeeCalendarView.as_view(), name="calendar_list"),
#######################################################
# Vendor URLs
path("vendors/create/", views.VendorCreateView.as_view(), name="vendor_create"),
path("vendors", views.VendorListView.as_view(), name="vendor_list"),
path("vendors/<slug:slug>/", views.vendorDetailView, name="vendor_detail"),
#######################################################
path("<slug:dealer_slug>/vendors/create/", views.VendorCreateView.as_view(), name="vendor_create"),
path("<slug:dealer_slug>/vendors", views.VendorListView.as_view(), name="vendor_list"),
path("<slug:dealer_slug>/vendors/<slug:slug>/", views.vendorDetailView, name="vendor_detail"),
path(
"vendors/<slug:slug>/update/",
"<slug:dealer_slug>/vendors/<slug:slug>/update/",
views.VendorUpdateView.as_view(),
name="vendor_update",
),
path(
"vendors/<slug:slug>/delete/",
"<slug:dealer_slug>/vendors/<slug:slug>/delete/",
views.delete_vendor,
name="vendor_delete",
),
#######################################################
# Car URLs
#######################################################
path("<slug:dealer_slug>/cars/upload_cars/", views.upload_cars, name="upload_cars"),
path(
"<slug:dealer_slug>/cars/<uuid:pk>/upload_cars/",
@ -477,24 +481,24 @@ urlpatterns = [
# name="payment_create",
# ),
# Users URLs
path("user/", views.UserListView.as_view(), name="user_list"),
path("user/create/", views.UserCreateView.as_view(), name="user_create"),
path("user/<slug:slug>/", views.UserDetailView.as_view(), name="user_detail"),
path("user/<slug:slug>/groups/", views.UserGroupView, name="user_groups"),
path("<slug:dealer_slug>/user/", views.UserListView.as_view(), name="user_list"),
path("<slug:dealer_slug>/user/create/", views.UserCreateView.as_view(), name="user_create"),
path("<slug:dealer_slug>/user/<slug:slug>/", views.UserDetailView.as_view(), name="user_detail"),
path("<slug:dealer_slug>/user/<slug:slug>/groups/", views.UserGroupView, name="user_groups"),
path(
"user/<slug:slug>/update/", views.UserUpdateView.as_view(), name="user_update"
"<slug:dealer_slug>/user/<slug:slug>/update/", views.UserUpdateView.as_view(), name="user_update"
),
path("user/<slug:slug>/confirm/", views.UserDeleteview, name="user_delete"),
path("<slug:dealer_slug>/user/<slug:slug>/confirm/", views.UserDeleteview, name="user_delete"),
# Group URLs
path("group/create/", views.GroupCreateView.as_view(), name="group_create"),
path("<slug:dealer_slug>/group/create/", views.GroupCreateView.as_view(), name="group_create"),
path(
"group/<int:pk>/update/", views.GroupUpdateView.as_view(), name="group_update"
"<slug:dealer_slug>/group/<int:pk>/update/", views.GroupUpdateView.as_view(), name="group_update"
),
path("group/<int:pk>/", views.GroupDetailView.as_view(), name="group_detail"),
path("group/", views.GroupListView.as_view(), name="group_list"),
path("group/<int:pk>/confirm/", views.GroupDeleteview, name="group_delete"),
path("<slug:dealer_slug>/group/<int:pk>/", views.GroupDetailView.as_view(), name="group_detail"),
path("<slug:dealer_slug>/group/", views.GroupListView.as_view(), name="group_list"),
path("<slug:dealer_slug>/group/<int:pk>/confirm/", views.GroupDeleteview, name="group_delete"),
path(
"group/<int:pk>/permission/", views.GroupPermissionView, name="group_permission"
"<slug:dealer_slug>/group/<int:pk>/permission/", views.GroupPermissionView, name="group_permission"
),
# Organization URLs
path(
@ -546,34 +550,35 @@ urlpatterns = [
views.RepresentativeDeleteView.as_view(),
name="representative_delete",
),
# Ledger URLS
#####################################################################
# Ledger
path("ledgers/", views.LedgerModelListView.as_view(), name="ledger_list"),
#####################################################################
path("<slug:dealer_slug>/ledgers/", views.LedgerModelListView.as_view(), name="ledger_list"),
path(
"ledgers/create/", views.LedgerModelCreateView.as_view(), name="ledger_create"
"<slug:dealer_slug>/ledgers/create/", views.LedgerModelCreateView.as_view(), name="ledger_create"
),
path(
"ledgers/<slug:entity_slug>/detail/<uuid:pk>/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/detail/<uuid:pk>/",
views.LedgerModelDetailView.as_view(),
name="ledger_detail",
),
path(
"ledgers/<slug:entity_slug>/lock_all_journals/<uuid:pk>/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/lock_all_journals/<uuid:pk>/",
views.ledger_lock_all_journals,
name="lock_all_journals",
),
path(
"ledgers/<slug:entity_slug>/unlock_all_journals/<uuid:pk>/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/unlock_all_journals/<uuid:pk>/",
views.ledger_unlock_all_journals,
name="unlock_all_journals",
),
path(
"ledgers/<slug:entity_slug>/post_all_journals/<uuid:pk>/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/post_all_journals/<uuid:pk>/",
views.ledger_post_all_journals,
name="post_all_journals",
),
path(
"ledgers/<slug:entity_slug>/unpost_all_journals/<uuid:pk>/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/unpost_all_journals/<uuid:pk>/",
views.ledger_unpost_all_journals,
name="unpost_all_journals",
),
@ -581,77 +586,81 @@ urlpatterns = [
# "ledgers/create/", views.LedgerModelCreateView.as_view(), name="ledger_create"
# ),
path(
"journalentries/<uuid:pk>/list/",
"<slug:dealer_slug>/journalentries/<uuid:pk>/list/",
views.JournalEntryListView.as_view(),
name="journalentry_list",
),
path(
"journalentries/<uuid:pk>/create/",
"<slug:dealer_slug>/journalentries/<uuid:pk>/create/",
views.JournalEntryCreateView.as_view(),
name="journalentry_create",
),
path(
"journalentries/<uuid:pk>/delete/",
"<slug:dealer_slug>/journalentries/<uuid:pk>/delete/",
views.JournalEntryDeleteView,
name="journalentry_delete",
),
path(
"journalentries/<uuid:pk>/transactions/",
"<slug:dealer_slug>/journalentries/<uuid:pk>/transactions/",
views.JournalEntryTransactionsView,
name="journalentry_transactions",
),
path(
"journalentries/<slug:entity_slug>/<uuid:ledger_pk>/detail/<uuid:je_pk>/txs/",
"<slug:dealer_slug>/journalentries/<slug:entity_slug>/<uuid:ledger_pk>/detail/<uuid:je_pk>/txs/",
views.JournalEntryModelTXSDetailView.as_view(),
name="journalentry_txs",
),
##############################################################
# ledger actions
##############################################################
path(
"ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/post/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/post/",
views.LedgerModelModelActionView.as_view(action_name="post"),
name="ledger-action-post",
),
path(
"ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/post-journal-entries/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/post-journal-entries/",
views.LedgerModelModelActionView.as_view(action_name="post_journal_entries"),
name="ledger-action-post-journal-entries",
),
path(
"ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/unpost/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/unpost/",
views.LedgerModelModelActionView.as_view(action_name="unpost"),
name="ledger-action-unpost",
),
path(
"ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/lock/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/lock/",
views.LedgerModelModelActionView.as_view(action_name="lock"),
name="ledger-action-lock",
),
path(
"ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/lock-journal-entries/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/lock-journal-entries/",
views.LedgerModelModelActionView.as_view(action_name="lock_journal_entries"),
name="ledger-action-lock-journal-entries",
),
path(
"ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/unlock/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/unlock/",
views.LedgerModelModelActionView.as_view(action_name="unlock"),
name="ledger-action-unlock",
),
path(
"ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/hide/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/hide/",
views.LedgerModelModelActionView.as_view(action_name="hide"),
name="ledger-action-hide",
),
path(
"ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/unhide/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/action/<uuid:ledger_pk>/unhide/",
views.LedgerModelModelActionView.as_view(action_name="unhide"),
name="ledger-action-unhide",
),
path(
"ledgers/<slug:entity_slug>/delete/<uuid:ledger_pk>/",
"<slug:dealer_slug>/ledgers/<slug:entity_slug>/delete/<uuid:ledger_pk>/",
views.LedgerModelDeleteView.as_view(),
name="ledger-delete",
),
##############################################################
# Bank Account
##############################################################
path(
"<slug:dealer_slug>/bank_accounts/",
views.BankAccountListView.as_view(),
@ -833,31 +842,31 @@ urlpatterns = [
# path('sales/journal/<uuid:pk>/create/', views.JournalEntryCreateView.as_view(), name='journal_create'),
# Items
path(
"items/services/", views.ItemServiceListView.as_view(), name="item_service_list"
"<slug:dealer_slug>/items/services/", views.ItemServiceListView.as_view(), name="item_service_list"
),
path(
"items/services/create/",
"<slug:dealer_slug>/items/services/create/",
views.ItemServiceCreateView.as_view(),
name="item_service_create",
),
path(
"items/services/<int:pk>/update/",
"<slug:dealer_slug>/items/services/<int:pk>/update/",
views.ItemServiceUpdateView.as_view(),
name="item_service_update",
),
# Expanese
path(
"items/expeneses/",
"<slug:dealer_slug>/items/expeneses/",
views.ItemExpenseListView.as_view(),
name="item_expense_list",
),
path(
"items/expeneses/create/",
"<slug:dealer_slug>/items/expeneses/create/",
views.ItemExpenseCreateView.as_view(),
name="item_expense_create",
),
path(
"items/expeneses/<uuid:pk>/update/",
"<slug:dealer_slug>/items/expeneses/<uuid:pk>/update/",
views.ItemExpenseUpdateView.as_view(),
name="item_expense_update",
),
@ -1099,20 +1108,20 @@ urlpatterns = [
name="entity-json-pnl",
),
# Admin Management...
path("management/", views.management_view, name="management"),
path("management/user_management/", views.user_management, name="user_management"),
path("<slug:dealer_slug>/management/", views.management_view, name="management"),
path("<slug:dealer_slug>/management/user_management/", views.user_management, name="user_management"),
path(
"management/<str:content_type>/<slug:slug>/activate_account/",
"<slug:dealer_slug>/management/<str:content_type>/<slug:slug>/activate_account/",
views.activate_account,
name="activate_account",
),
path(
"management/<str:content_type>/<slug:slug>/permenant_delete_account/",
"<slug:dealer_slug>/management/<str:content_type>/<slug:slug>/permenant_delete_account/",
views.permenant_delete_account,
name="permenant_delete_account",
),
path(
"management/audit_log_dashboard/",
"<slug:dealer_slug>/management/audit_log_dashboard/",
views.AuditLogDashboardView,
name="audit_log_dashboard",
),

View File

@ -1366,7 +1366,7 @@ def create_user_dealer(email, password, name, arabic_name, phone, crn, vrn, addr
def handle_payment(request, order):
url = "https://api.moyasar.com/v1/payments"
callback_url = request.build_absolute_uri(reverse("payment_callback"))
callback_url = request.build_absolute_uri(reverse("payment_callback", args=[request.dealer.slug]))
if request.user.is_authenticated:
# email = request.user.email

View File

@ -349,15 +349,6 @@ class HomeView(LoginRequiredMixin, TemplateView):
template_name = "index.html"
def dispatch(self, request, *args, **kwargs):
# Redirect unauthenticated users to the welcome page
if not request.user.is_authenticated:
return redirect("welcome")
if not kwargs.get("dealer_slug"):
dealer = get_user_type(request)
return redirect("home", dealer_slug=dealer.slug)
return super().dispatch(request, *args, **kwargs)
class TestView(TemplateView):
"""
@ -1582,12 +1573,25 @@ class CarDeleteView(
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)
def get_success_url(self):
"""
Returns the URL to redirect to after a successful car deletion.
It dynamically includes the dealer_slug from the URL.
"""
dealer_slug = self.kwargs.get('dealer_slug')
if dealer_slug:
return reverse_lazy("car_list", kwargs={'dealer_slug': dealer_slug})
else:
messages.error(self.request, _("Could not determine dealer for redirection."))
return reverse_lazy("home")
class CarLocationCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
@ -2432,7 +2436,7 @@ class VendorListView(LoginRequiredMixin, ListView):
@login_required
def vendorDetailView(request, slug):
def vendorDetailView(request, dealer_slug,slug):
"""
Fetches and renders the detail view for a specific vendor.
@ -2480,7 +2484,6 @@ class VendorCreateView(
model = models.Vendor
form_class = forms.VendorForm
template_name = "vendors/vendor_form.html"
success_url = reverse_lazy("vendor_list")
success_message = _("Vendor created successfully")
def form_valid(self, form):
@ -2500,7 +2503,8 @@ class VendorCreateView(
form.instance.save()
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("vendor_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]})
class VendorUpdateView(
LoginRequiredMixin,
@ -2531,7 +2535,6 @@ class VendorUpdateView(
model = models.Vendor
form_class = forms.VendorForm
template_name = "vendors/vendor_form.html"
success_url = reverse_lazy("vendor_list")
success_message = _("Vendor updated successfully")
# def get_initial(self):
@ -2553,10 +2556,11 @@ class VendorUpdateView(
# instance.additional_info = additionals
# instance.save()
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("vendor_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]})
@login_required
def delete_vendor(request, slug):
def delete_vendor(request, dealer_slug,slug):
"""
Deletes an existing vendor record from the database.
@ -2576,7 +2580,7 @@ def delete_vendor(request, slug):
vendor.vendor_model.active = False
vendor.save()
messages.success(request, _("Vendor deleted successfully"))
return redirect("vendor_list")
return redirect("vendor_list", dealer_slug=dealer_slug)
# group
@ -2662,7 +2666,6 @@ class GroupCreateView(
model = models.CustomGroup
form_class = forms.GroupForm
template_name = "groups/group_form.html"
success_url = reverse_lazy("group_list")
success_message = _("Group created successfully")
def form_valid(self, form):
@ -2674,6 +2677,8 @@ class GroupCreateView(
instance.save()
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("group_list", args=[self.request.dealer.slug])
class GroupUpdateView(
LoginRequiredMixin,
@ -2705,20 +2710,20 @@ class GroupUpdateView(
model = models.CustomGroup
form_class = forms.GroupForm
template_name = "groups/group_form.html"
success_url = reverse_lazy("group_list")
success_message = _("Group updated successfully")
def form_valid(self, form):
dealer = get_user_type(self.request)
instance = form.save(commit=False)
instance.set_defualt_permissions()
instance.set_default_permissions()
instance.group.name = f"{dealer.slug}_{instance.name}"
instance.save()
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("group_list", args=[self.request.dealer.slug])
@login_required
def GroupDeleteview(request, pk):
def GroupDeleteview(request, dealer_slug,pk):
"""
Handles the deletion of a specific group instance. This view ensures that only
authenticated users can perform the deletion. Upon successful deletion, a
@ -2731,14 +2736,15 @@ def GroupDeleteview(request, pk):
:return: The HTTP response that redirects the user to the group list page
after the group is successfully deleted.
"""
get_object_or_404(models.Dealer,slug=dealer_slug)
group = get_object_or_404(models.CustomGroup, pk=pk)
group.delete()
messages.success(request, _("Group deleted successfully"))
return redirect("group_list")
return redirect("group_list",dealer_slug=dealer_slug)
@login_required
def GroupPermissionView(request, pk):
def GroupPermissionView(request, dealer_slug,pk):
"""
Handles the view for adding or modifying permissions of a specific group. This view
fetches the group based on the primary key passed as a parameter, and either displays
@ -2760,6 +2766,7 @@ def GroupPermissionView(request, pk):
the group's permissions and redirects to the group's detail page.
:rtype: HttpResponse
"""
get_object_or_404(models.Dealer,slug=dealer_slug)
group = get_object_or_404(models.CustomGroup, pk=pk)
if request.method == "POST":
form = forms.PermissionForm(request.POST)
@ -2768,7 +2775,7 @@ def GroupPermissionView(request, pk):
for i in permissions:
group.add_permission(Permission.objects.get(id=int(i)))
messages.success(request, _("Permission added successfully"))
return redirect("group_detail", pk=group.pk)
return redirect("group_detail", dealer_slug=dealer_slug,pk=group.pk)
form = forms.PermissionForm(initial={"name": group.permissions})
return render(
request, "groups/group_permission_form.html", {"group": group, "form": form}
@ -2777,7 +2784,7 @@ def GroupPermissionView(request, pk):
# Users
@login_required
def UserGroupView(request, slug):
def UserGroupView(request, dealer_slug,slug):
"""
Handles the assignment of user groups to a specific staff member. This view
allows updating the groups a staff member belongs to via a form submission.
@ -2793,6 +2800,7 @@ def UserGroupView(request, slug):
user detail page after successful submission for POST requests.
:rtype: HttpResponse or HttpResponseRedirect
"""
get_object_or_404(models.Dealer,slug=dealer_slug)
staff = get_object_or_404(models.Staff, slug=slug)
if request.method == "POST":
form = forms.UserGroupForm(request.POST)
@ -2804,7 +2812,7 @@ def UserGroupView(request, slug):
staff.add_group(cg.group)
messages.success(request, _("Group added successfully"))
return redirect("user_detail", slug=staff.slug)
return redirect("user_detail",dealer_slug=dealer_slug, slug=staff.slug)
form = forms.UserGroupForm(initial={"name": staff.groups})
form.fields["name"].queryset = models.CustomGroup.objects.filter(
@ -2840,7 +2848,7 @@ class UserListView(LoginRequiredMixin, ListView):
def get_queryset(self):
query = self.request.GET.get("q")
dealer = get_user_type(self.request)
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
staff = models.Staff.objects.filter(dealer=dealer, active=True).all()
return apply_search_filters(staff, query)
@ -2903,7 +2911,7 @@ class UserCreateView(
success_message = _("User created successfully")
def form_valid(self, form):
dealer = get_user_type(self.request)
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
# quota_dict = get_user_quota(dealer.user)
# allowed_users = quota_dict.get("Users")
@ -2921,21 +2929,22 @@ class UserCreateView(
return self.form_invalid(form)
email = form.cleaned_data["email"]
password = "Tenhal@123"
try:
user = User.objects.create_user(
username=email, email=email, password=password
)
user.is_staff = True
user.save()
except IntegrityError as e:
if User.objects.filter(email=email).exists():
messages.error(
self.request,
_(
"A user with this email already exists. Please use a different email."
),
)
return redirect("user_create")
return redirect("user_create", dealer_slug=dealer.slug)
password = "Tenhal@123"
user = User.objects.create_user(
username=email, email=email, password=password
)
user.is_staff = True
user.save()
staff_member = StaffMember.objects.create(user=user)
for service in form.cleaned_data["service_offered"]:
staff_member.services_offered.add(service)
@ -2948,7 +2957,8 @@ class UserCreateView(
if group:
staff.add_group(group)
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("user_list", args=[self.request.dealer.slug])
class UserUpdateView(
LoginRequiredMixin,
@ -3015,10 +3025,11 @@ class UserUpdateView(
staff.add_as_manager()
staff.save()
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("user_list", args=[self.request.dealer.slug])
@login_required
def UserDeleteview(request, slug):
def UserDeleteview(request, dealer_slug,slug):
"""
Deletes a user and its associated staff member from the database and redirects
to the user list page. Displays a success message upon successful deletion
@ -3029,10 +3040,11 @@ def UserDeleteview(request, slug):
:return: An HTTP redirect to the user list page.
"""
get_object_or_404(models.Dealer,slug=dealer_slug)
staff = get_object_or_404(models.Staff, slug=slug)
staff.deactivate_account()
messages.success(request, _("User deleted successfully"))
return redirect("user_list")
return redirect("user_list",dealer_slug=dealer_slug)
class OrganizationListView(LoginRequiredMixin, ListView):
@ -3418,23 +3430,23 @@ class BankAccountCreateView(
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)
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
form.instance.entity_model = dealer.entity
return super().form_valid(form)
def get_form_kwargs(self):
dealer = get_user_type(self.request)
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
entity = dealer.entity
kwargs = super().get_form_kwargs()
kwargs["entity_slug"] = entity.slug
kwargs["user_model"] = entity.admin
return kwargs
def get_success_url(self):
return reverse_lazy("bank_account_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]})
class BankAccountDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
"""
@ -3530,17 +3542,12 @@ def bank_account_delete(request, dealer_slug, pk):
rendering the confirmation template if accessed via GET.
:rtype: HttpResponse
"""
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
get_object_or_404(models.Dealer, slug=dealer_slug)
bank_account = get_object_or_404(BankAccountModel, pk=pk)
if request.method == "POST":
bank_account.delete()
messages.success(request, _("Bank account deleted successfully"))
return redirect("bank_account_list", dealer_slug=dealer_slug)
return render(
request,
"ledger/bank_accounts/bank_account_delete.html",
{"bank_account": bank_account},
)
bank_account.delete()
messages.success(request, _("Bank account deleted successfully"))
return redirect("bank_account_list", dealer_slug=dealer_slug)
# Accounts
@ -5572,7 +5579,7 @@ def schedule_lead(request, dealer_slug,slug):
messages.success(request, _("Appointment Created Successfully"))
try:
if lead.opportunity:
return redirect("opportunity_detail", slug=lead.opportunity.slug)
return redirect("opportunity_detail", dealer_slug=lead.dealer.slug, slug=lead.opportunity.slug)
except models.Lead.opportunity.RelatedObjectDoesNotExist:
return redirect("lead_list", dealer_slug=lead.dealer.slug)
else:
@ -6134,7 +6141,6 @@ class ItemServiceCreateView(
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"]
@ -6147,6 +6153,8 @@ class ItemServiceCreateView(
form.instance.price = (form.instance.price * vat.rate) + form.instance.price
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("item_service_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]})
class ItemServiceUpdateView(
LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, UpdateView
@ -6179,7 +6187,6 @@ class ItemServiceUpdateView(
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"]
@ -6191,8 +6198,8 @@ class ItemServiceUpdateView(
if form.instance.taxable:
form.instance.price = (form.instance.price * vat.rate) + form.instance.price
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("item_service_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]})
class ItemServiceListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
"""
Handles the listing of additional services for a dealer.
@ -6265,7 +6272,8 @@ class ItemExpenseCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateV
dealer = get_user_type(self.request)
form.instance.entity = dealer.entity
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("item_expense_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]})
class ItemExpenseUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
"""
@ -6305,7 +6313,8 @@ class ItemExpenseUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateV
dealer = get_user_type(self.request)
form.instance.entity = dealer.entity
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("item_expense_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]})
class ItemExpenseListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
"""
@ -8195,7 +8204,7 @@ def schedule_cancel(request,dealer_slug, pk):
@login_required
def assign_car_makes(request):
def assign_car_makes(request,dealer_slug):
"""
Assigns car makes to a dealer.
@ -8212,7 +8221,7 @@ def assign_car_makes(request):
dealer detail page after successful form submission.
:rtype: HttpResponse
"""
dealer = get_user_type(request)
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
if request.method == "POST":
form = forms.DealersMakeForm(request.POST, dealer=dealer)
if form.is_valid():
@ -8371,7 +8380,7 @@ class LedgerModelModelActionView(LedgerModelModelActionViewBase):
"""
def get_redirect_url(self, *args, **kwargs):
return reverse("ledger_list")
return reverse("ledger_list", args=[self.kwargs["dealer_slug"]])
class LedgerModelDeleteView(LedgerModelDeleteViewBase, SuccessMessageMixin):
@ -8394,7 +8403,7 @@ class LedgerModelDeleteView(LedgerModelDeleteViewBase, SuccessMessageMixin):
success_message = "Ledger deleted"
def get_success_url(self):
return reverse("ledger_list")
return reverse("ledger_list", args=[self.kwargs["dealer_slug"]])
# class LedgerModelCreateView(LoginRequiredMixin,SuccessMessageMixin, CreateView):
@ -8497,7 +8506,7 @@ class JournalEntryCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView
def get_success_url(self):
ledger = LedgerModel.objects.filter(pk=self.kwargs["pk"]).first()
return reverse("journalentry_list", kwargs={"pk": ledger.pk})
return reverse("journalentry_list", kwargs={"dealer_slug":self.kwargs["dealer_slug"],"pk": ledger.pk})
def JournalEntryDeleteView(request, pk):
@ -8532,7 +8541,7 @@ def JournalEntryDeleteView(request, pk):
)
def JournalEntryTransactionsView(request, pk):
def JournalEntryTransactionsView(request, dealer_slug,pk):
"""
Handles the retrieval and display of journal entry transactions for a specific journal
entry instance. It retrieves the journal entry and its associated transactions, ordering
@ -8546,12 +8555,8 @@ def JournalEntryTransactionsView(request, pk):
its transactions.
:rtype: django.http.HttpResponse
"""
get_object_or_404(models.Dealer,slug=dealer_slug)
journal = JournalEntryModel.objects.filter(pk=pk).first()
# transactions = (
# TransactionModel.objects.filter(journal_entry=journal)
# .order_by("account__code")
# .all()
# )
qs = TransactionModel.objects.filter(journal_entry=journal).all()
transactions = qs.annotate(
debit_credit_sort_order=Case(
@ -8583,7 +8588,7 @@ class JournalEntryModelTXSDetailView(JournalEntryModelTXSDetailViewBase):
template_name = "ledger/journal_entry/journal_entry_txs.html"
def ledger_lock_all_journals(request, entity_slug, pk):
def ledger_lock_all_journals(request,dealer_slug, entity_slug, pk):
"""
Locks all journals associated with a specific ledger. If the ledger is already locked,
it will notify the user through an error message. Otherwise, it initiates the locking of
@ -8600,17 +8605,18 @@ def ledger_lock_all_journals(request, entity_slug, pk):
:return: HttpResponse redirecting to the journal entry list page of the locked ledger.
:rtype: HttpResponse
"""
get_object_or_404(models.Dealer,slug=dealer_slug)
ledger = LedgerModel.objects.filter(pk=pk).first()
if ledger.is_locked():
messages.error(request, _("Ledger is already locked"))
return redirect("journalentry_list", pk=ledger.pk)
return redirect("journalentry_list",dealer_slug=dealer_slug, pk=ledger.pk)
ledger.lock_journal_entries()
ledger.lock()
ledger.save()
return redirect("journalentry_list", pk=ledger.pk)
return redirect("journalentry_list", dealer_slug=dealer_slug,pk=ledger.pk)
def ledger_unlock_all_journals(request, entity_slug, pk):
def ledger_unlock_all_journals(request, dealer_slug, entity_slug, pk):
"""
Unlocks all journal entries associated with a specific ledger. This function first checks if the
ledger is locked. If it is already unlocked, it shows an error message and redirects the user
@ -8627,10 +8633,11 @@ def ledger_unlock_all_journals(request, entity_slug, pk):
:return: A redirection to the journal entry list page for the specified ledger.
:rtype: HttpResponseRedirect
"""
get_object_or_404(models.Dealer,slug=dealer_slug)
ledger = LedgerModel.objects.filter(pk=pk).first()
if not ledger.is_locked():
messages.error(request, _("Ledger is already Unlocked"))
return redirect("journalentry_list", pk=ledger.pk)
return redirect("journalentry_list",dealer_slug=dealer_slug, pk=ledger.pk)
ledger.unlock()
ledger.save()
@ -8638,10 +8645,10 @@ def ledger_unlock_all_journals(request, entity_slug, pk):
for je in qs:
je.unlock()
je.save()
return redirect("journalentry_list", pk=ledger.pk)
return redirect("journalentry_list", dealer_slug=dealer_slug, pk=ledger.pk)
def ledger_post_all_journals(request, entity_slug, pk):
def ledger_post_all_journals(request, dealer_slug, entity_slug, pk):
"""
Posts all journal entries associated with a ledger. This function updates the ledger's
state to reflect that its journal entries have been posted. If the ledger is already
@ -8656,17 +8663,18 @@ def ledger_post_all_journals(request, entity_slug, pk):
:return: A redirect to the journal entry list view for the specified ledger.
:rtype: HttpResponseRedirect
"""
get_object_or_404(models.Dealer,slug=dealer_slug)
ledger = LedgerModel.objects.filter(pk=pk).first()
if ledger.is_posted():
messages.error(request, _("Ledger is already posted"))
return redirect("journalentry_list", pk=ledger.pk)
return redirect("journalentry_list",dealer_slug=dealer_slug, pk=ledger.pk)
ledger.post_journal_entries()
ledger.post()
ledger.save()
return redirect("journalentry_list", pk=ledger.pk)
return redirect("journalentry_list",dealer_slug=dealer_slug, pk=ledger.pk)
def ledger_unpost_all_journals(request, entity_slug, pk):
def ledger_unpost_all_journals(request,dealer_slug, entity_slug, pk):
"""
Unposts all journal entries for a specified ledger and marks the ledger as unposted.
@ -8686,10 +8694,11 @@ def ledger_unpost_all_journals(request, entity_slug, pk):
page for the specified ledger.
:rtype: HttpResponseRedirect
"""
get_object_or_404(models.Dealer,slug=dealer_slug)
ledger = LedgerModel.objects.filter(pk=pk).first()
if not ledger.is_posted():
messages.error(request, _("Ledger is already Unposted"))
return redirect("journalentry_list", pk=ledger.pk)
return redirect("journalentry_list",dealer_slug=dealer_slug, pk=ledger.pk)
qs = ledger.journal_entries.posted()
for je in qs:
je.mark_as_unposted()
@ -8697,18 +8706,19 @@ def ledger_unpost_all_journals(request, entity_slug, pk):
ledger.unpost()
ledger.save()
return redirect("journalentry_list", pk=ledger.pk)
return redirect("journalentry_list",dealer_slug=dealer_slug, pk=ledger.pk)
def pricing_page(request):
def pricing_page(request,dealer_slug):
get_object_or_404(models.Dealer,slug=dealer_slug)
plan_list = PlanPricing.objects.all()
form = forms.PaymentPlanForm()
return render(request, "pricing_page.html", {"plan_list": plan_list, "form": form})
# @require_POST
def submit_plan(request):
dealer = get_user_type(request)
def submit_plan(request,dealer_slug):
dealer = get_object_or_404(models.Dealer,slug=dealer_slug)
selected_plan_id = request.POST.get("selected_plan")
pp = PlanPricing.objects.get(pk=selected_plan_id)
@ -8725,9 +8735,9 @@ def submit_plan(request):
return redirect(transaction_url)
def payment_callback(request):
def payment_callback(request,dealer_slug):
message = request.GET.get("message")
dealer = get_user_type(request)
dealer = get_object_or_404(models.Dealer,slug=dealer_slug)
payment_id = request.GET.get("id")
history = models.PaymentHistory.objects.filter(transaction_id=payment_id).first()
payment_status = request.GET.get("status")
@ -8966,11 +8976,13 @@ def update_note(request,dealer_slug, pk):
# Admin Management
def management_view(request):
def management_view(request,dealer_slug):
get_object_or_404(models.Dealer,slug=dealer_slug)
return render(request, "admin_management/management.html")
def user_management(request):
def user_management(request,dealer_slug):
get_object_or_404(models.Dealer,slug=dealer_slug)
context = {
"customers": models.Customer.objects.filter(active=False),
"organizations": models.Organization.objects.filter(active=False),
@ -8980,12 +8992,13 @@ def user_management(request):
return render(request, "admin_management/user_management.html", context)
def AuditLogDashboardView(request):
def AuditLogDashboardView(request,dealer_slug):
"""
Displays audit logs (User Actions, Login Events, Request Events) with pagination.
Log type is determined by the 'q' query parameter (e.g., ?q=userActions).
Pagination page number is passed as a query parameter (e.g., ?page=2).
"""
get_object_or_404(models.Dealer,slug=dealer_slug)
q = request.GET.get("q") # Get the log type from the 'q' query parameter
current_pagination_page = request.GET.get("page", 1)
context = {}
@ -9113,7 +9126,8 @@ def AuditLogDashboardView(request):
return render(request, template_name, context)
def activate_account(request, content_type, slug):
def activate_account(request,dealer_slug, content_type, slug):
get_object_or_404(models.Dealer,slug=dealer_slug)
try:
model = apps.get_model(f"inventory.{content_type}")
except LookupError:
@ -9123,13 +9137,14 @@ def activate_account(request, content_type, slug):
if request.method == "POST":
obj.activate_account()
messages.success(request, _("Account activated successfully"))
return redirect("user_management")
return redirect("user_management", dealer_slug=dealer_slug)
return render(
request, "admin_management/confirm_activate_account.html", {"obj": obj}
)
def permenant_delete_account(request, content_type, slug):
def permenant_delete_account(request,dealer_slug, content_type, slug):
get_object_or_404(models.Dealer,slug=dealer_slug)
try:
model = apps.get_model(f"inventory.{content_type}")
except LookupError:
@ -9147,7 +9162,7 @@ def permenant_delete_account(request, content_type, slug):
)
except Exception as e:
messages.error(request, _(f"Error deleting account: {e}"))
return redirect("user_management")
return redirect("user_management", dealer_slug=dealer_slug)
return render(
request, "admin_management/permenant_delete_account.html", {"obj": obj}
)
@ -9182,6 +9197,9 @@ def InventoryItemCreateView(request, dealer_slug):
cogs_accounts = entity.get_coa_accounts().filter(role="cogs_regular")
if request.method == "POST":
response = HttpResponse()
response["HX-Refresh"] = "true"
name = request.POST.get("name")
account = request.POST.get("account")
account = inventory_accounts.get(pk=account)
@ -9213,10 +9231,11 @@ def InventoryItemCreateView(request, dealer_slug):
.first()
):
messages.error(request, _("Inventory item already exists"))
return redirect(
f"{reverse('inventory_item_create')}?for_po={for_po}",
dealer_slug=dealer.slug,
)
return response
# return redirect(
# f"{reverse('inventory_item_create')}?for_po={for_po}",
# dealer_slug=dealer.slug,
# )
uom = entity.get_uom_all().get(name="Unit")
entity.create_item_inventory(
name=inventory_name,
@ -9226,7 +9245,8 @@ def InventoryItemCreateView(request, dealer_slug):
coa_model=coa,
)
messages.success(request, _("Inventory item created successfully"))
return redirect("purchase_order_list", dealer_slug=dealer.slug)
return response
# return redirect("purchase_order_list", dealer_slug=dealer.slug)
if for_po:
form = forms.CSVUploadForm()
form.fields["vendor"].queryset = dealer.vendors.filter(active=True)
@ -9515,8 +9535,7 @@ class PurchaseOrderMarkAsApprovedView(BasePurchaseOrderActionActionView):
class PurchaseOrderMarkAsFulfilledView(BasePurchaseOrderActionActionView):
action_name = "mark_as_fulfilled"
class PurchaseOrderMarkAsCanceledView(BasePurchaseOrderActionActionView):
action_name = "mark_as_canceled"
@ -9583,36 +9602,23 @@ class BillModelActionForceMigrateView(BaseBillActionView):
def view_items_inventory(request, dealer_slug, entity_slug, po_pk):
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
get_object_or_404(models.Dealer, slug=dealer_slug)
po = PurchaseOrderModel.objects.get(pk=po_pk)
items = po.get_itemtxs_data()[0]
items_per_page = 30
paginator = Paginator(items, items_per_page)
items = po.items.all()
page_number = request.GET.get("page")
try:
page_obj = paginator.get_page(page_number)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
page_obj = paginator.get_page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
page_obj = paginator.get_page(paginator.num_pages)
return render(
request,
"purchase_orders/po_upload_cars.html",
{"po": po, "items": items, "page_obj": page_obj},
)
return render(request,"purchase_orders/po_upload_cars.html",{"po": po, "items": items})
def upload_cars(request, dealer_slug, pk=None):
item = None
po_item = None
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
response = redirect("upload_cars", dealer_slug=dealer_slug)
if pk:
item = get_object_or_404(ItemTransactionModel, pk=pk)
po_item = models.PoItemsUploaded.objects.get(dealer=dealer, item=item)
response = redirect("upload_cars", dealer_slug=dealer_slug, pk=pk)
if item.item_model.additional_info.get("uploaded"):
if po_item.status == "uploaded":
messages.add_message(request, messages.ERROR, "Item already uploaded.")
return redirect(
"view_items_inventory",
@ -9626,7 +9632,6 @@ def upload_cars(request, dealer_slug, pk=None):
try:
if item:
item = ItemTransactionModel.objects.get(pk=pk)
data = [x.strip() for x in item.item_model.name.split("||")]
make = models.CarMake.objects.filter(is_sa_import=True).get(
name=data[0]
@ -9706,9 +9711,9 @@ def upload_cars(request, dealer_slug, pk=None):
)
car.add_colors(exterior=exterior, interior=interior)
cars_created += 1
if item:
item.item_model.additional_info["uploaded"] = True
item.item_model.save()
if po_item:
po_item.status = "uploaded"
po_item.save()
messages.success(request, f"Successfully imported {cars_created} cars")
return response

View File

@ -108,3 +108,4 @@ html[dir="rtl"] .form-icon-container .form-control {
padding-right: 35px;
padding-left: 10px;
}

View File

@ -9,7 +9,7 @@
{% csrf_token %}
<div class="d-flex justify-content-center">
<button class="btn btn-phoenix-primary mx-2" type="submit">Activate</button>
<a class="btn btn-phoenix-danger mx-2" href="{% url 'user_management' %}">Cancel</a>
<a class="btn btn-phoenix-danger mx-2" href="{% url 'user_management' request.dealer.slug %}">Cancel</a>
</div>
</form>
</div>

View File

@ -4,7 +4,7 @@
{% block content %}
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-4 g-4 mt-10">
<div class="col">
<a href="{% url 'user_management' %}">
<a href="{% url 'user_management' request.dealer.slug %}">
<div class="card h-100">
<div class="card-header text-center">
<h5 class="card-title">{{ _("User Management")}}</h5>
@ -14,7 +14,7 @@
</a>
</div>
<div class="col">
<a href="{% url 'audit_log_dashboard' %}">
<a href="{% url 'audit_log_dashboard' request.dealer.slug %}">
<div class="card h-100">
<div class="card-header text-center">
<h5 class="card-title">{{ _("Audit Log Dashboard")}}</h5>

View File

@ -2,17 +2,17 @@
<ul class="nav nav-tabs" id="accountTypeTabs" role="tablist">
<li class="nav-item me-3" role="presentation">
<a href="{% url 'audit_log_dashboard' %}?q=userActions">
<a href="{% url 'audit_log_dashboard' request.dealer.slug %}?q=userActions">
<i class="fas fa-history me-2"></i>{% trans "User Actions" %}
</a>
</li>
<li class="nav-item me-3" role="presentation">
<a href="{% url 'audit_log_dashboard' %}?q=loginEvents">
<a href="{% url 'audit_log_dashboard' request.dealer.slug %}?q=loginEvents">
<i class="fas fa-right-to-bracket me-2"></i>{% trans "User Login Events" %}
</a>
</li>
<li class="nav-item" role="presentation">
<a href="{% url 'audit_log_dashboard' %}?q=userRequests">
<a href="{% url 'audit_log_dashboard' request.dealer.slug %}?q=userRequests">
<i class="fas fa-file-alt me-2"></i>{% trans "User Page Requests" %}
</a>
</li>

View File

@ -9,7 +9,7 @@
{% csrf_token %}
<div class="d-flex justify-content-center">
<button class="btn btn-phoenix-danger mx-2" type="submit"><i class="fas fa-trash me-2"></i> Delete Permenantly</button>
<a class="btn btn-phoenix-secondary mx-2" href="{% url 'user_management' %}"><i class="fas fa-ban me-2"></i>Cancel</a>
<a class="btn btn-phoenix-secondary mx-2" href="{% url 'user_management' request.dealer.slug %}"><i class="fas fa-ban me-2"></i>Cancel</a>
</div>
</form>
</div>

View File

@ -51,9 +51,9 @@
<span class="fas fa-ellipsis-h fs-10"></span>
</button>
<div class="dropdown-menu dropdown-menu-end py-2">
<a href="{% url 'activate_account' 'customer' customer.slug %}"><button class="dropdown-item text-primary">{% trans "Activate" %}</button></a>
<a href="{% url 'activate_account' request.dealer.slug 'customer' customer.slug %}"><button class="dropdown-item text-primary">{% trans "Activate" %}</button></a>
<div class="dropdown-divider"></div>
<a href="{% url 'permenant_delete_account' 'customer' customer.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
<a href="{% url 'permenant_delete_account' request.dealer.slug 'customer' customer.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
</div>
</div>
</td>
@ -115,9 +115,9 @@
<span class="fas fa-ellipsis-h fs-10"></span>
</button>
<div class="dropdown-menu dropdown-menu-end py-2">
<a href="{% url 'activate_account' 'organization' organization.slug %}"><button class="dropdown-item text-primary">{% trans "Activate" %}</button></a>
<a href="{% url 'activate_account' request.dealer.slug 'organization' organization.slug %}"><button class="dropdown-item text-primary">{% trans "Activate" %}</button></a>
<div class="dropdown-divider"></div>
<a href="{% url 'permenant_delete_account' 'organization' organization.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
<a href="{% url 'permenant_delete_account' request.dealer.slug 'organization' organization.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
</div>
</div>
</td>
@ -179,9 +179,9 @@
<span class="fas fa-ellipsis-h fs-10"></span>
</button>
<div class="dropdown-menu dropdown-menu-end py-2">
<a href="{% url 'activate_account' 'vendor' vendor.slug %}"><button class="dropdown-item text-primary">{% trans "Activate" %}</button></a>
<a href="{% url 'activate_account' request.dealer.slug 'vendor' vendor.slug %}"><button class="dropdown-item text-primary">{% trans "Activate" %}</button></a>
<div class="dropdown-divider"></div>
<a href="{% url 'permenant_delete_account' 'vendor' vendor.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
<a href="{% url 'permenant_delete_account' request.dealer.slug 'vendor' vendor.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
</div>
</div>
</td>
@ -245,7 +245,7 @@
<div class="dropdown-menu dropdown-menu-end py-2">
<a href="{% url 'activate_account' 'staff' obj.slug %}"><button class="dropdown-item text-primary">{% trans "Activate" %}</button></a>
<div class="dropdown-divider"></div>
<a href="{% url 'permenant_delete_account' 'staff' obj.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
<a href="{% url 'permenant_delete_account' request.dealer.slug 'staff' obj.slug %}"><button class="dropdown-item text-danger">{% trans "Permenantly Delete" %}</button></a>
</div>
</div>
</td>

View File

@ -12,7 +12,7 @@
<div class="row justify-content-between mb-2">
<div class="col-6 col-md-4 col-xxl-2 text-center border-translucent border-start-xxl border-end-xxl-0 border-bottom-xxl-0 border-end border-bottom pb-4 pb-xxl-0 ">
<span class="uil fs-5 lh-1 uil-users-alt text-success"></span>
<a href="{% url 'user_list' %}"><h4 class="fs-6 pt-3">{{ staff }}</h4></a>
<a href="{% url 'user_list' request.dealer.slug %}"><h4 class="fs-6 pt-3">{{ staff }}</h4></a>
<p class="fs-9 mb-0">{{ _("Staff")}}</p>
</div>
<div class="col-6 col-md-4 col-xxl-2 text-center border-translucent border-start-xxl border-end-xxl-0 border-bottom-xxl-0 border-end border-bottom pb-4 pb-xxl-0 ">
@ -32,12 +32,12 @@
</div>
<div class="col-6 col-md-4 col-xxl-2 text-center border-translucent border-start-xxl border-end-xxl-0 border-bottom-xxl-0 border-end border-bottom pb-4 pb-xxl-0 ">
<span class="uil fs-5 lh-1 uil-comment-alt-question text-success-dark"></span>
<a href="{% url 'estimate_list' %}"><h4 class="fs-6 pt-3">{{ estimates }}</h4></a>
<a href="{% url 'estimate_list' request.dealer.slug %}"><h4 class="fs-6 pt-3">{{ estimates }}</h4></a>
<p class="fs-9 mb-0">{{ _("Quotations")}}</p>
</div>
<div class="col-6 col-md-4 col-xxl-2 text-center border-translucent border-start-xxl border-end-xxl-0 border-bottom-xxl-0 border-end border-bottom pb-4 pb-xxl-0 ">
<span class="uil fs-5 lh-1 uil-receipt-alt text-secondary"></span>
<a href="{% url 'purchase_order_list' %}"><h4 class="fs-6 pt-3">{{ purchase_orders }}</h4></a>
<a href="{% url 'purchase_order_list' request.dealer.slug %}"><h4 class="fs-6 pt-3">{{ purchase_orders }}</h4></a>
<p class="fs-9 mb-0">{{ _("Purchase Orders")}}</p>
</div>
</div>

View File

@ -58,7 +58,7 @@
<h2>{{ _("Select Car Makes You Sell") }}</h2>
<form method="post" action="{% url 'assign_car_makes' %}">
<form method="post" action="{% url 'assign_car_makes' request.dealer.slug %}">
{% csrf_token %}
<div class="car-makes-grid">

View File

@ -114,13 +114,13 @@
<span class="badge badge-phoenix fs-9 badge-phoenix-success"> <span class="badge-label">{% trans 'Active' %}</span><span class="ms-1" data-feather="check" style="height:16px;width:16px;"></span> </span>
{% else %}
<span class="badge badge-phoenix fs-9 badge-phoenix-danger"> <span class="badge-label">{% trans 'Expired' %}</span><span class="ms-1" data-feather="times" style="height:16px;width:16px;"></span> </span>
<a href="{% url 'pricing_page' %}" class="btn btn-phoenix-secondary ms-2"><span class="fas fa-arrow-right me-2"></span>{{ _("Renew") }}</a>
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-phoenix-secondary ms-2"><span class="fas fa-arrow-right me-2"></span>{{ _("Renew") }}</a>
{% endif %}
{% if dealer.user.userplan.plan.name != "Enterprise" %}
<a href="{% url 'pricing_page' %}" class="btn btn-sm btn-phoenix-primary ms-2"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade") }}</a>
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-sm btn-phoenix-primary ms-2"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade") }}</a>
{% endif %}
{% else %}
<span class="text-body-tertiary fw-semibold">You have no active plan.</span> <a href="{% url 'pricing_page' %}" class="btn btn-phoenix-secondary ms-2"><span class="fas fa-arrow-right me-2"></span>{{ _("Subscribe") }}</a>
<span class="text-body-tertiary fw-semibold">You have no active plan.</span> <a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-phoenix-secondary ms-2"><span class="fas fa-arrow-right me-2"></span>{{ _("Subscribe") }}</a>
{% endif %}
</div>
@ -172,7 +172,7 @@
{% endfor %}
</div>
<div class="row">
<a class="btn btn-sm btn-phoenix-warning" href="{% url 'assign_car_makes' %}">{{ _("Select Makes")}}</a>
<a class="btn btn-sm btn-phoenix-warning" href="{% url 'assign_car_makes' request.dealer.slug %}">{{ _("Select Makes")}}</a>
</div>
</div>

View File

@ -28,7 +28,7 @@
</button>
<a type="button"
class="btn btn-sm btn-phoenix-danger"
href="{% url 'group_delete' group.id %}">
href="{% url 'group_delete' request.dealer.slug group.id %}">
{% trans 'Yes' %}
</a>
</div>
@ -74,7 +74,7 @@
<div class="card-header ">
</div>
<h4 class="my-4">Permissions</h4>
<a class="btn btn-sm btn-phoenix-primary mt-2 mb-4" href="{% url 'group_permission' group.id %}"><i class="fa-solid fa-unlock"></i> Manage Permissions</a>
<a class="btn btn-sm btn-phoenix-primary mt-2 mb-4" href="{% url 'group_permission' request.dealer.slug group.id %}"><i class="fa-solid fa-unlock"></i> Manage Permissions</a>
<table class="table table-hover table-responsive-sm fs-9 mb-0">
<thead>
@ -98,7 +98,7 @@
</table>
</div>
<div class="card-footer d-flex ">
<a class="btn btn-sm btn-phoenix-primary me-1" href="{% url 'group_update' group.id %}">
<a class="btn btn-sm btn-phoenix-primary me-1" href="{% url 'group_update' request.dealer.slug group.id %}">
<i class="fa-solid fa-pen-to-square"></i>
{{ _("Edit") }}
</a>
@ -109,7 +109,11 @@
{{ _("Delete") }}
</a>
<a class="btn btn-sm btn-phoenix-secondary"
href="{% url 'group_list' %}">
<<<<<<< HEAD
href="{% url 'group_list' request.dealer.slug%}">
=======
href="{% url 'group_list' request.dealer.slug %}">
>>>>>>> c9fad7b79c346875a636122fdc7514814180dbc7
<i class="fa-solid fa-arrow-left"></i>
{% trans "Back to List" %}
</a>

View File

@ -11,7 +11,7 @@
<div class="col-auto">
<div class="d-md-flex justify-content-between">
<div>
<a href="{% url 'group_create' %}" class="btn btn-sm btn-phoenix-primary"><span class="fas fa-plus me-2"></span>{% trans "Add Group" %}</a>
<a href="{% url 'group_create' request.dealer.slug %}" class="btn btn-sm btn-phoenix-primary"><span class="fas fa-plus me-2"></span>{% trans "Add Group" %}</a>
</div>
</div>
@ -35,7 +35,7 @@
<td class="align-middle white-space-nowrap"><i class="fa-solid fa-unlock me-1"></i> {{ group.permissions.count }}</td>
<td class="align-middle white-space-nowrap">
<a class="btn btn-phoenix-success"
href="{% url 'group_detail' group.id %}">
href="{% url 'group_detail' request.dealer.slug group.id %}">
<i class="fa-solid fa-eye"></i>
{% trans 'view'|capfirst %}
</a>

View File

@ -32,7 +32,7 @@
<div class="text-danger">{{ error }}</div>
{% endfor %}
<div class="d-flex mb-3">
<a href="{% url 'group_detail' group.pk %}" class="btn btn-phoenix-primary me-2 "><i class="fa-solid fa-ban"></i> {% trans "Cancel"|capfirst %}</a>
<a href="{% url 'group_detail' request.dealer.slug group.pk %}" class="btn btn-phoenix-primary me-2 "><i class="fa-solid fa-ban"></i> {% trans "Cancel"|capfirst %}</a>
<button class="btn btn-phoenix-primary" type="submit">
<i class="fa-solid fa-floppy-disk"></i>
{{ _("Save") }}

View File

@ -28,20 +28,6 @@
</div>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'inventory_item_create' request.dealer.slug %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-plus-circle"></span></span><span class="nav-link-text">{% trans "add inventory item"|capfirst %}</span>
</div>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'upload_cars' request.dealer.slug %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-file-import"></span></span><span class="nav-link-text">{% trans "Bulk Upload"|capfirst %}</span>
</div>
</a>
</li>
{% endif %}
<li class="nav-item">
@ -59,6 +45,13 @@
</div>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'upload_cars' request.dealer.slug %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-file-import"></span></span><span class="nav-link-text">{% trans "Bulk Upload"|capfirst %}</span>
</div>
</a>
</li>
</ul>
</div>
</div>
@ -226,7 +219,7 @@
{% endif %}
{% if perms.django_ledger.view_itemmodel %}
<li class="nav-item">
<a class="nav-link" href="{% url 'ledger_list' %}">
<a class="nav-link" href="{% url 'ledger_list' request.dealer.slug %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-book"></span></span><span class="nav-link-text">{% trans "Ledgers"|capfirst %}</span>
</div>
@ -234,7 +227,7 @@
</li>
{% endif %}
<li class="nav-item">
<a class="nav-link" href="{% url 'item_service_list' %}">
<a class="nav-link" href="{% url 'item_service_list' request.dealer.slug %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span data-feather="activity"></span></span><span class="nav-link-text">{% trans "Services"|capfirst %}</span>
</div>
@ -242,7 +235,7 @@
</li>
{% if perms.django_ledger.view_itemmodel %}
<li class="nav-item">
<a class="nav-link" href="{% url 'item_expense_list' %}">
<a class="nav-link" href="{% url 'item_expense_list' request.dealer.slug %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-users-cog"></span></span><span class="nav-link-text">{% trans "Expenses"|capfirst %}</span>
</div>
@ -251,7 +244,7 @@
{% endif %}
{% if perms.django_ledger.view_vendormodel %}
<li class="nav-item">
<a class="nav-link" href="{% url 'vendor_list' %}">
<a class="nav-link" href="{% url 'vendor_list' request.dealer.slug %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'vendors'|capfirst %}</span>
</div>
@ -267,13 +260,15 @@
</a>
</li>
{% endif %}
{% if perms.django_ledger.view_purchaseordermodel %}
<li class="nav-item">
<a class="nav-link" href="{% url 'purchase_order_list' request.dealer.slug %}">
<div class="d-flex align-items-center">
<span class="nav-link-icon"><span class="fas fa-truck-fast"></span></span><span class="nav-link-text">{% trans "purchase Orders"|capfirst %}</span>
<span class="nav-link-icon"><span class="fas fa-warehouse"></span></span><span class="nav-link-text">{% trans "purchase Orders"|capfirst %}</span>
</div>
</a>
</li>
{% endif %}
</ul>
</div>
</div>
@ -365,7 +360,7 @@
aria-label="Toggle Navigation">
<span class="navbar-toggle-icon"><span class="toggle-line"></span></span>
</button>
<a class="navbar-brand me-1 me-sm-3" href="{% url 'home' request.dealer.slug %}">
<a class="navbar-brand me-1 me-sm-3" href="{% url 'home' %}">
<div class="d-flex align-items-center">
<img class="logo-img d-dark-none" src="{% static 'images/logos/logo-d.png' %}" alt="haikal" width="27" />
<img class="logo-img d-light-none" src="{% static 'images/logos/logo.png' %}" alt="haikal" width="27" />
@ -442,10 +437,10 @@
{% endif %}
{% if request.is_dealer %}
<li class="nav-item">
<a class="nav-link px-3 d-block" href="{% url 'user_list' %}"><span class="me-2 text-body align-bottom" data-feather="users"></span>{{ _("Staff & Groups") }}</a>
<a class="nav-link px-3 d-block" href="{% url 'user_list' request.dealer.slug %}"><span class="me-2 text-body align-bottom" data-feather="users"></span>{{ _("Staff & Groups") }}</a>
</li>
<li class="nav-item">
<a class="nav-link px-3 d-block" href="{% url 'dealer_activity' %}"> <span class="me-2 text-body align-bottom" data-feather="lock"></span>{{ _("Activities") }}</a>
<a class="nav-link px-3 d-block" href="{% url 'dealer_activity' request.dealer.slug %}"> <span class="me-2 text-body align-bottom" data-feather="lock"></span>{{ _("Activities") }}</a>
</li>
{% endif %}
<li class="nav-item">
@ -455,7 +450,7 @@
</li>
<li class="nav-item">
{% if request.is_dealer %}
<a class="nav-link px-3 d-block" href="{% url 'management' %}"> <span class="me-2 text-body align-bottom" data-feather="shield"></span>{{ _("Admin Managemnet") }}</a>
<a class="nav-link px-3 d-block" href="{% url 'management' request.dealer.slug %}"> <span class="me-2 text-body align-bottom" data-feather="shield"></span>{{ _("Admin Managemnet") }}</a>
{% endif %}
</li>
<li class="nav-item">

View File

@ -3,11 +3,13 @@
{% load i18n %}
{% block title %}Delete Car{% endblock %}
{% block content %}
<div class="mt-4 ms-4">
<h1>Delete Car</h1>
<p>Are you sure you want to delete the car "{{ car }}"?</p>
<p class="text-danger">Are you sure you want to delete the car "{{ car }}"?</p>
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-phoenix-danger">Confirm Delete</button>
<a href="{% url 'car_detail' car.pk %}" class="btn btn-phoenix-secondary">{% trans 'Cancel' %}</a>
<a href="{% url 'car_list' request.dealer.slug %}" class="btn btn-phoenix-secondary">{% trans 'Cancel' %}</a>
</form>
</div>
{% endblock %}

View File

@ -21,7 +21,7 @@
<div class="alert alert-outline-warning d-flex align-items-center"
role="alert">
<i class="fa-solid fa-circle-info fs-6"></i>
<p class="mb-0 flex-1">{{ _("Please Add A Vendor, Before Adding A Car .") }} <a href="{% url 'vendor_create' %}" class="ms-3 text-body-primary fs-9" >{{ _("Add Vendor") }}</a> </p>
<p class="mb-0 flex-1">{{ _("Please Add A Vendor, Before Adding A Car .") }} <a href="{% url 'vendor_create' request.dealer.slug %}" class="ms-3 text-body-primary fs-9" >{{ _("Add Vendor") }}</a> </p>
<button class="btn-close"
type="button"
data-bs-dismiss="alert"

View File

@ -11,7 +11,7 @@
<div class="card shadow-sm border-0">
<div class="card-header text-white">
<h2 class="h4 mb-0 fw-light text-center">
<i class="bi bi-cart-check me-2"></i>{% trans "Inventory Ordered" %}
<i class="fas fa-cart-arrow-down me-2"></i>{% trans "Inventory Ordered" %}
</h2>
</div>
<div class="card-body p-0">
@ -34,7 +34,7 @@
<div class="card shadow-sm border-0">
<div class="card-header text-white">
<h2 class="h4 mb-0 fw-light text-center">
<i class="bi bi-truck me-2"></i>{% trans "Inventory In Transit" %}
<i class="fas fa-truck-moving me-2"></i>{% trans "Inventory In Transit" %}
</h2>
</div>
<div class="card-body p-0">
@ -57,7 +57,7 @@
<div class="card shadow-sm border-0">
<div class="card-header text-white">
<h2 class="h4 mb-0 fw-light text-center">
<i class="bi bi-check-circle me-2"></i>{% trans "Inventory Received" %}
<i class="fas fa-check-circle me-2"></i>{% trans "Inventory Received" %}
</h2>
</div>
<div class="card-body p-0">
@ -80,4 +80,4 @@
</div>
</div>
</div>
{% endblock %}
{% endblock %}

View File

@ -20,6 +20,6 @@
{% for error in form.reservation_end.errors %}<div class="invalid-feedback">{{ error }}</div>{% endfor %}
</div>
<button type="submit" class="btn btn-phoenix-primary">{% trans "Reserve" %}</button>
<a href="{% url 'car_detail' car.pk %}" class="btn btn-phoenix-secondary">{% trans "Cancel" %}</a>
<a href="{% url 'car_detail' request.dealer.slug car.pk %}" class="btn btn-phoenix-secondary">{% trans "Cancel" %}</a>
</form>
{% endblock %}

View File

@ -5,7 +5,6 @@
<table class="table table-hover table-bordered align-middle">
<thead class="table-light">
<tr class="text-center">
<th class="py-3 text-start">{% trans "Created at" %}</th>
<th class="py-3 text-start">{% trans "Item" %}</th>
<th class="py-3">{% trans "UOM" %}</th>
<th class="py-3">{% trans "Quantity" %}</th>
@ -17,8 +16,6 @@
{% for i in inventory_list %}
<tr class="hover-actions-trigger">
<td class="ps-2 fw-medium">{{ i.item_model__name }}</td>
<td class="ps-2 fw-medium">{{ i.item_model__name }}</td>
<td class="text-center">{{ i.item_model__uom__name }}</td>
<td class="text-end pe-3">{{ i.total_quantity | floatformat:3 }}</td>

View File

@ -9,7 +9,7 @@
<div class="d-flex justify-content-between mb-2">
<h3 class="">{% trans "Expenses" %}</h3>
<a href="{% url 'item_expense_create' %}" class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{% trans "Add Expense" %}</a>
<a href="{% url 'item_expense_create' request.dealer.slug %}" class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{% trans "Add Expense" %}</a>
</div>
{% include "partials/search_box.html" %}
{% if page_obj.object_list %}
@ -39,7 +39,7 @@
{{ expense.uom }}
</td>
<td class="align-middle product white-space-nowrap">
<a href="{% url 'item_expense_update' expense.pk %}"
<a href="{% url 'item_expense_update' request.dealer.slug expense.pk %}"
class="btn btn-sm btn-phoenix-success">
{% trans "Update" %}
</a>

View File

@ -8,7 +8,7 @@
<div class="d-flex justify-content-between mb-2">
<h3 class="">{% trans "Services" %}</h3>
<a href="{% url 'item_service_create' %}" class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{% trans "Add Service" %}</a>
<a href="{% url 'item_service_create' request.dealer.slug %}" class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{% trans "Add Service" %}</a>
</div>
{% include "partials/search_box.html" %}
{% if page_obj.object_list %}
@ -46,7 +46,7 @@
{{ service.item.co }}
</td>
<td class="align-middle white-space-nowrap text-start">
<a href="{% url 'item_service_update' service.pk %}"
<a href="{% url 'item_service_update' request.dealer.slug service.pk %}"
class="btn btn-sm btn-phoenix-success">
{% trans "Update" %}
</a>

View File

@ -27,7 +27,7 @@
</button>
<a type="button"
class="btn btn-sm btn-phoenix-danger"
href="{% url 'bank_account_delete' bank_account.pk %}">
href="{% url 'bank_account_delete' request.dealer.slug bank_account.pk %}">
{% trans 'Yes' %}
</a>
</div>
@ -52,7 +52,7 @@
</div>
</div>
<div class="card-footer d-flex ">
<a class="btn btn-sm btn-phoenix-primary me-1" href="{% url 'bank_account_update' bank_account.pk %}">
<a class="btn btn-sm btn-phoenix-primary me-1" href="{% url 'bank_account_update' request.dealer.slug bank_account.pk %}">
<!--<i class="bi bi-pencil-square"></i> -->
{{ _("Edit") }}
</a>
@ -63,7 +63,7 @@
{{ _("Delete") }}
</a>
<a class="btn btn-sm btn-phoenix-secondary"
href="{% url 'bank_account_list' %}">
href="{% url 'bank_account_list' request.dealer.slug %}">
<!--<i class="bi bi-arrow-left-square-fill"></i>-->
{% trans "Back to List" %}
</a>

View File

@ -27,7 +27,9 @@
{% for bank in bank_accounts %}
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
<td class="align-middle product white-space-nowrap px-1">
{{ bank.name }}
<a href="{% url 'bank_account_detail' request.dealer.slug bank.pk %}">
{{ bank.name }}
</a>
</td>
<td class="align-middle product white-space-nowrap">
{{ bank.account_number }}

View File

@ -38,19 +38,19 @@
<div class="card-footer">
<div class="d-flex justify-content-between">
{% if journal_entry.can_lock %}
<a href="{{ journal_entry.get_lock_url }}?next={% url 'journalentry_txs' journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}"
<a href="{{ journal_entry.get_lock_url }}?next={% url 'journalentry_txs' request.dealer.slug journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}"
class="btn btn-phoenix-success font-weight-bold">{% trans 'Lock' %}</a>
{% endif %}
{% if journal_entry.can_unlock %}
<a href="{{ journal_entry.get_unlock_url }}?next={% url 'journalentry_txs' journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}"
<a href="{{ journal_entry.get_unlock_url }}?next={% url 'journalentry_txs' request.dealer.slug journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}"
class="btn btn-phoenix-warning font-weight-bold">{% trans 'UnLock' %}</a>
{% endif %}
{% if journal_entry.can_post %}
<a href="{{ journal_entry.get_post_url }}?next={% url 'journalentry_txs' journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}"
<a href="{{ journal_entry.get_post_url }}?next={% url 'journalentry_txs' request.dealer.slug journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}"
class="btn btn-phoenix-success font-weight-bold">{% trans 'Post' %}</a>
{% endif %}
{% if journal_entry.can_unpost %}
<a href="{{ journal_entry.get_unpost_url }}?next={% url 'journalentry_txs' journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}"
<a href="{{ journal_entry.get_unpost_url }}?next={% url 'journalentry_txs' request.dealer.slug journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}"
class="btn btn-phoenix-danger font-weight-bold">{% trans 'UnPost' %}</a>
{% endif %}
</div>

View File

@ -14,7 +14,7 @@
</div>
<div class="mt-5 text-center">
<button type="submit" class="btn btn-phoenix-success me-2"><i class="fa-solid fa-floppy-disk me-1"></i>{% trans "Save" %}</button>
<a href="{% url 'journalentry_list' ledger.pk %}" class="btn btn-phoenix-secondary"><i class="fa-solid fa-ban me-1"></i> {% trans "Cancel" %}</a>
<a href="{% url 'journalentry_list' request.dealer.slug ledger.pk %}" class="btn btn-phoenix-secondary"><i class="fa-solid fa-ban me-1"></i> {% trans "Cancel" %}</a>
</div>
</form>
</div>

View File

@ -36,7 +36,7 @@
<div class="d-flex justify-content-between mb-2">
<h3 class="">{% trans "Journal Entries" %}</h3>
<a href="{% url 'journalentry_create' ledger.pk %}" class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{% trans "Add Journal Entry" %}</a>
<a href="{% url 'journalentry_create' request.dealer.slug ledger.pk %}" class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{% trans "Add Journal Entry" %}</a>
</div>
@ -96,10 +96,10 @@
<span class="fas fa-ellipsis-h fs-10"></span>
</button>
<div class="dropdown-menu dropdown-menu-end py-2">
<a class="dropdown-item" href="{% url 'journalentry_transactions' je.pk %}">{% trans "View" %}</a>
<a class="dropdown-item" href="{% url 'journalentry_txs' je.entity_slug je.ledger_id je.pk %}">{% trans "Transactions" %}</a>
<a class="dropdown-item" href="{% url 'journalentry_transactions' request.dealer.slug je.pk %}">{% trans "View" %}</a>
<a class="dropdown-item" href="{% url 'journalentry_txs' request.dealer.slug je.entity_slug je.ledger_id je.pk %}">{% trans "Transactions" %}</a>
{% if je.can_delete %}
<a class="dropdown-item" href="{% url 'journalentry_delete' je.pk %}">{% trans "Delete" %}</a>
<a class="dropdown-item" href="{% url 'journalentry_delete' request.dealer.slug je.pk %}">{% trans "Delete" %}</a>
{% endif %}
</div>
</div>

View File

@ -62,30 +62,30 @@
{% trans 'Save' %}
</button>
<a class="btn btn-phoenix-secondary"
href="{% url 'journalentry_list' journal_entry.ledger_id %}">
href="{% url 'journalentry_list' request.dealer.slug journal_entry.ledger_id %}">
{% trans 'Done' %}
</a>
{% if journal_entry.can_lock %}
<a class="btn btn-phoenix-danger"
href="{{ journal_entry.get_action_lock_url }}?next={% url 'journalentry_txs' journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}">
href="{{ journal_entry.get_action_lock_url }}?next={% url 'journalentry_txs' request.dealer.slug journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}">
{% trans 'Lock' %}
</a>
{% endif %}
{% if journal_entry.can_unlock %}
<a class="btn btn-phoenix-warning"
href="{{ journal_entry.get_action_unlock_url }}?next={% url 'journalentry_txs' journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}">
href="{{ journal_entry.get_action_unlock_url }}?next={% url 'journalentry_txs' request.dealer.slug journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}">
{% trans 'UnLock' %}
</a>
{% endif %}
{% if journal_entry.can_post %}
<a class="btn btn-phoenix-danger"
href="{{ journal_entry.get_action_post_url }}?next={% url 'journalentry_txs' journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}">
href="{{ journal_entry.get_action_post_url }}?next={% url 'journalentry_txs' request.dealer.slug journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}">
{% trans 'Post' %}
</a>
{% endif %}
{% if journal_entry.can_unpost %}
<a class="btn btn-phoenix-warning"
href="{{ journal_entry.get_action_unpost_url }}?next={% url 'journalentry_txs' journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}">
href="{{ journal_entry.get_action_unpost_url }}?next={% url 'journalentry_txs' request.dealer.slug journal_entry.entity_slug journal_entry.ledger_id journal_entry.pk %}">
{% trans 'UnPost' %}
</a>
{% endif %}

View File

@ -10,7 +10,7 @@
<div class="d-flex justify-content-between mb-2">
<h3 class="">{% trans "Ledger" %}</h3>
<a href="{% url 'ledger_create' %}" class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{% trans 'Create Ledger' %}</a>
<a href="{% url 'ledger_create' request.dealer.slug %}" class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{% trans 'Create Ledger' %}</a>
</div>
<div class="table-responsive px-1 scrollbar mt-3">
<table class="table align-items-center table-flush">
@ -32,16 +32,16 @@
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
<td class="align-middle product white-space-nowrap px-1">
{% if ledger.invoicemodel %}
<a href="{% url 'invoice_detail' ledger.invoicemodel.pk %}">{{ ledger.get_wrapped_model_instance }}</a>
<a href="{% url 'invoice_detail' request.dealer.slug ledger.invoicemodel.pk %}">{{ ledger.get_wrapped_model_instance }}</a>
{% elif ledger.billmodel %}
<a href="{% url 'bill_detail' ledger.billmodel.pk %}">{{ ledger.get_wrapped_model_instance }}</a>
<a href="{% url 'bill-detail' request.dealer.slug request.dealer.entity.slug ledger.billmodel.pk %}">{{ ledger.get_wrapped_model_instance }}</a>
{% else %}
<a href="#">{{ ledger.name }}</a>
{% endif %}
</td>
<td class="align-middle product white-space-nowrap">
<a class="btn btn-sm btn-phoenix-primary"
href="{% url 'journalentry_list' ledger.pk %}">
href="{% url 'journalentry_list' request.dealer.slug ledger.pk %}">
<i class="fa-solid fa-right-left"></i>
<span>
<span class="has-text-weight-bold">{{ ledger.journal_entries__count }}</span>
@ -80,33 +80,33 @@
</button>
<div class="dropdown-menu dropdown-menu-end py-2">
{% if ledger.can_lock %}
<a href="{% url 'ledger-action-lock' entity_slug=entity_slug ledger_pk=ledger.uuid %}"
<a href="{% url 'ledger-action-lock' dealer_slug=request.dealer.slug entity_slug=entity_slug ledger_pk=ledger.uuid %}"
class="dropdown-item has-text-info has-text-weight-bold">{% trans 'Lock' %}</a>
{% endif %}
{% if ledger.can_unlock %}
<a href="{% url 'ledger-action-unlock' entity_slug=entity_slug ledger_pk=ledger.uuid %}"
<a href="{% url 'ledger-action-unlock' dealer_slug=request.dealer.slug entity_slug=entity_slug ledger_pk=ledger.uuid %}"
class="dropdown-item has-text-warning has-text-weight-bold">{% trans 'UnLock' %}</a>
{% endif %}
{% if ledger.can_post %}
<a href="{% url 'ledger-action-post' entity_slug=entity_slug ledger_pk=ledger.uuid %}"
<a href="{% url 'ledger-action-post' dealer_slug=request.dealer.slug entity_slug=entity_slug ledger_pk=ledger.uuid %}"
class="dropdown-item has-text-info has-text-weight-bold text-success">{% trans 'Post' %}</a>
{% endif %}
{% if ledger.can_unpost %}
<a href="{% url 'ledger-action-unpost' entity_slug=entity_slug ledger_pk=ledger.uuid %}"
<a href="{% url 'ledger-action-unpost' dealer_slug=request.dealer.slug entity_slug=entity_slug ledger_pk=ledger.uuid %}"
class="dropdown-item has-text-warning has-text-weight-bold text-info">{% trans 'UnPost' %}</a>
{% endif %}
{% if ledger.can_hide %}
<a href="{% url 'ledger-action-hide' entity_slug=entity_slug ledger_pk=ledger.uuid %}"
<a href="{% url 'ledger-action-hide' dealer_slug=request.dealer.slug entity_slug=entity_slug ledger_pk=ledger.uuid %}"
class="dropdown-item has-text-warning has-text-weight-bold text-danger">{% trans 'Hide' %}</a>
{% endif %}
{% if ledger.can_unhide %}
<a href="{% url 'ledger-action-unhide' entity_slug=entity_slug ledger_pk=ledger.uuid %}"
<a href="{% url 'ledger-action-unhide' dealer_slug=request.dealer.slug entity_slug=entity_slug ledger_pk=ledger.uuid %}"
class="dropdown-item has-text-danger has-text-weight-bold">{% trans 'UnHide' %}</a>
{% endif %}
{% if ledger.can_delete %}
<a href="{% url 'ledger-delete' entity_slug=entity_slug ledger_pk=ledger.uuid %}"
<a href="{% url 'ledger-delete' dealer_slug=request.dealer.slug entity_slug=entity_slug ledger_pk=ledger.uuid %}"
class="dropdown-item has-text-danger has-text-weight-bold text-danger">{% trans 'Delete' %}</a>
{% endif %}
</div>

View File

@ -42,7 +42,7 @@
<span class="text-muted small">{% trans "Plan" %}</span>
<div class="d-flex align-items-center justify-content-between">
<span class="fw-semibold">{{ userplan.plan }}</span>
<a href="{% url 'pricing_page' %}" class="btn btn-sm btn-phoenix-primary">
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-sm btn-phoenix-primary">
{% trans "Upgrade" %}
</a>
</div>

View File

@ -98,7 +98,7 @@
<div class="d-flex justify-content-between align-items-end mt-2">
<span class="fs-5 fw-bold">{{ plan_pricing.price }} <span class="icon-saudi_riyal"></span></span>
{% if plan_pricing.plan == userplan.plan or userplan.is_expired or userplan.plan.is_free %}
<a href="{% url 'pricing_page' %}" class="btn btn-sm btn-phoenix-success">
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-sm btn-phoenix-success">
{% trans "Buy" %}
</a>
{% endif %}

View File

@ -51,7 +51,7 @@
{% block content %}
<div class="container py-5">
<h1 class="text-center mb-5">{{ _("Choose Your Plan")}}</h1>
<form method="POST" action="{% url 'submit_plan' %}" id="wizardForm">
<form method="POST" action="{% url 'submit_plan' request.dealer.slug %}" id="wizardForm">
{% csrf_token %}
<!-- Step 1: Plan Selection -->
<div class="step" id="step1">

View File

@ -1,8 +1,10 @@
{% extends "base.html" %}
{% load static i18n crispy_forms_tags %}
{% block customCSS %}
<style>
.color-card {
{% block content %}
<form hx-boost="true" hx-swap="none" action="{% url 'inventory_item_create' request.dealer.slug %}?for_po=1" method="post">
<style>
.color-card {
cursor: pointer;
transition: all 0.3s ease;
border: 2px solid transparent;
@ -67,10 +69,7 @@
gap: 10px;
margin-bottom: 20px;
}
</style>
{% endblock %}
{% block content %}
<form action="" method="post">
</style>
{% csrf_token %}
<div class="row g-4">
<div class="col">
@ -139,6 +138,6 @@
</div>
</div>
</div>
<button type="submit" class="btn btn-primary mt-5">Add New Item To Inventory</button>
<button type="submit" class="btn btn-primary mt-5">{% trans 'Save' %}</button>
</form>
{% endblock content %}

View File

@ -18,7 +18,19 @@
<table class="table table-hover table-bordered">
<thead class="">
<tr>
<th>{% trans 'Item' %}</th>
<th class="d-flex justify-content-between align-items-center">
{% trans 'Item' %}
<button type="button"
class="btn btn-sm btn-phoenix-success"
data-bs-toggle="modal"
data-bs-target="#mainModal"
hx-get="{% url 'inventory_item_create' dealer_slug %}?for_po=1"
hx-target=".main-modal-body"
hx-select="form"
hx-swap="innerHTML">
<i class="fas fa-plus me-1"></i>{% trans 'Add Item' %}
</button>
</th>
<th>{% trans 'Unit Cost' %}</th>
<th>{% trans 'Quantity' %}</th>
<th>{% trans 'Unit' %}</th>

View File

@ -7,7 +7,7 @@
{% block content %}
<div class="container-fluid mt-4">
<div class="row g-1">
<div class="col-lg-12">
<div class="d-flex flex-column gap-3">
<div class="card">
@ -23,8 +23,7 @@
</div>
</div>
<div class="col-lg-12">
<div class="col-lg-12">
<div class="card mb-4">
<div class="card-body">
<div class="row text-center">
@ -47,27 +46,21 @@
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<h3 class="h4 fw-light mb-2">{{ po_model.po_title }}</h3>
</div>
<div class="table-responsive">
{% po_item_table1 po_items %}
</div>
</div>
<div class="col-lg-12">
<div class="table-responsive">
{% po_item_table1 po_items %}
</div>
</div>
</div>
</div>
</div>
</div>
{% include "purchase_orders/includes/mark_as.html" %}
{% endblock %}
{% block customJS %}

View File

@ -57,7 +57,7 @@
<button class="btn btn-phoenix-primary" data-bs-toggle="modal" data-bs-target="#POModal"><span class="d-none d-sm-inline-block"><i class="fa-solid fa-receipt"></i> {% trans 'View Purchase Order' %}</span></button>
<a href="{% url 'purchase_order_list' %}" class="btn btn-phoenix-secondary">Back to List</a>
<a href="{% url 'purchase_order_list' request.dealer.slug %}" class="btn btn-phoenix-secondary">Back to List</a>
</div>
</div>

View File

@ -21,8 +21,6 @@
<div>
<a href="{% url 'purchase_order_create' request.dealer.slug %}"
class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{{ _("Create New PO") }}</a>
<a href="{% url 'inventory_item_create' request.dealer.slug %}?for_po=1"
class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{{ _("Create Inventory Item for PO") }}</a>
</div>
</div>
{% include "partials/search_box.html" %}
@ -68,7 +66,11 @@
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button>
<div class="dropdown-menu dropdown-menu-end py-2">
<a href="{% url 'purchase_order_detail' request.dealer.slug po.pk %}" class="dropdown-item text-success-dark">{% trans 'Detail' %}</a>
<a href="{% url 'view_items_inventory' dealer_slug=request.dealer.slug entity_slug=entity_slug po_pk=po.pk %}" class="dropdown-item text-success-dark">{% trans 'View Inventory Items' %}</a>
{% if po.po_status == 'fulfilled' %}
<a href="{% url 'view_items_inventory' dealer_slug=request.dealer.slug entity_slug=entity_slug po_pk=po.pk %}" class="dropdown-item text-success-dark">{% trans 'View Inventory Items' %}</a>
{% else %}
<button class="dropdown-item text-warning-dark" disabled><span class="fas fa-exclamation-triangle me-1"></span> Fulfill the PO Before Viewing Inventory</button>
{% endif %}
</div>
</div>
</td>

View File

@ -90,6 +90,26 @@
</div>
</div>
{% include "purchase_orders/includes/mark_as.html" %}
<div class="modal fade"
id="mainModal"
tabindex="-1"
aria-labelledby="mainModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="mainModalLabel">{% trans 'Add' %}</h5>
<button type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="main-modal-body" style="padding: 20px;">
<!-- Content will be loaded here via AJAX -->
</div>
</div>
</div>
</div>
{% endblock %}
{% block customJS %}

View File

@ -22,10 +22,6 @@
{% endif %}
</div>
<div class="table-responsive mt-3">
<table class="table table-striped table-hover align-middle">
<thead>
@ -37,16 +33,16 @@
</tr>
</thead>
<tbody>
{% for item in items %}
{% for i in items %}
<tr>
<th scope="row">{{ item.item_model }}</th>
<th scope="row">{{ item.po_quantity }}</th>
<th scope="row">{{ item.po_unit_cost }}</th>
<th scope="row">{{ i.item.item_model }}</th>
<th scope="row">{{ i.item.po_quantity }}</th>
<th scope="row">{{ i.item.po_unit_cost }}</th>
<th scope="row">
{% if item.item_model.additional_info.uploaded %}
{% if i.status == "uploaded" %}
<i data-feather="check-circle" class="text-success"></i>
{% else %}
<a href="{% url 'upload_cars' item.pk %}" class="btn btn-sm btn-phoenix-primary">
<a href="{% url 'upload_cars' request.dealer.slug i.item.pk %}" class="btn btn-sm btn-phoenix-primary">
<i data-feather="upload" class="me-2"></i>Upload Data
</a>
{% endif %}
@ -56,15 +52,5 @@
</tbody>
</table>
</div>
{% if page_obj.paginator.num_pages > 1 %}
<div class="d-flex justify-content-end mt-3">
<div class="d-flex">
{% include 'partials/pagination.html'%}
</div>
</div>
{% endif %}
<div>
{% endblock content %}

View File

@ -74,12 +74,6 @@
</div>
</div>
<div class="d-flex align-items-center gap-2">
{% if estimate.invoicemodel_set.first %}
<a href="{% url 'invoice_detail' request.dealer.slug estimate.invoicemodel_set.first.pk %}" class="btn btn-phoenix-primary btn-sm" type="button"><i class="fa-solid fa-receipt"></i>
{{ _("View Invoice")}}</a>
<button class="btn btn-phoenix-primary" data-bs-toggle="modal" data-bs-target="#POModal"><span class="d-none d-sm-inline-block"><i class="fa-solid fa-receipt"></i> {% trans 'View Purchase Order' %}</span></button>
{% endif %}
{% if estimate.status == 'draft' %}
<a href="{% url 'send_email' request.dealer.slug estimate.pk %}" class="btn btn-phoenix-primary me-2"><span class="fa-regular fa-paper-plane me-sm-2"></span><span class="d-none d-sm-inline-block">{% trans 'Send Quotation' %}</span></a>
<button id="mark_as_sent_estimate" class="btn btn-phoenix-secondary" onclick="setFormAction('review')" data-bs-toggle="modal" data-bs-target="#confirmModal"><span class="d-none d-sm-inline-block"><i class="fa-solid fa-check-double"></i> {% trans 'Mark As Sent' %}</span></button>
@ -87,16 +81,23 @@
<button id="accept_estimate" onclick="setFormAction('approved')" class="btn btn-phoenix-secondary" data-bs-toggle="modal" data-bs-target="#confirmModal"><span class="d-none d-sm-inline-block"><i class="fa-solid fa-check-double"></i> {% trans 'Mark As Accept' %}</span></button>
{% elif estimate.status == 'approved' %}
{% if estimate.sale_orders.first %}
{% if estimate.sale_orders.first %}
<!--if sale order exist-->
<a href="{% url 'invoice_create' request.dealer.slug estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block"><i class="fa-solid fa-receipt"></i> {% trans 'Create Invoice' %}</span></a>
<a href="{% url 'preview_sale_order' request.dealer.slug estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{{ _("Preview Sale Order") }}</span></a>
{% else %}
<a href="{% url 'order_detail' request.dealer.slug estimate.sale_orders.first.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{{ _("Preview Sale Order") }}</span></a>
{% else %}
<a href="{% url 'create_sale_order' request.dealer.slug estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block"><i class="fa-solid fa-file-import"></i> {% trans 'Create Sale Order' %}</span></a>
{% comment %} {% endcomment %}
{% endif %}
{% elif estimate.status == 'in_review' %}
<a href="{% url 'estimate_preview' request.dealer.slug estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block"><i class="fa-regular fa-eye"></i> {% trans 'Preview' %}</span></a>
{% endif %}
{% elif estimate.status == 'completed' %}
<a href="{% url 'order_detail' request.dealer.slug estimate.sale_orders.first.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{{ _("Preview Sale Order") }}</span></a>
<a href="{% url 'invoice_detail' request.dealer.slug estimate.invoicemodel_set.first.pk %}" class="btn btn-phoenix-primary btn-sm" type="button"><i class="fa-solid fa-receipt"></i>
{{ _("View Invoice")}}</a>
{% endif %}
{% if estimate.can_cancel %}
{% if perms.django_ledger.change_estimatemodel %}
<button class="btn btn-phoenix-danger" data-bs-toggle="modal" data-bs-target="#CancelModal"><i class="fa-solid fa-ban"></i> {% trans "Cancel" %}</button>

View File

@ -102,7 +102,7 @@
<div class="row g-4 g-xl-1 g-xxl-3 justify-content-between">
<div class="col-sm-auto">
<div class="d-sm-block d-inline-flex d-md-flex flex-xl-column flex-xxl-row align-items-center align-items-xl-start align-items-xxl-center">
<div class="d-flex bg-success-subtle rounded flex-center me-3 mb-sm-3 mb-md-0 mb-xl-3 mb-xxl-0" style="width:32px; height:32px"><span class="text-success-dark" data-feather="dollar-sign" style="width:24px; height:24px"></span></div>
<div class="d-flex bg-success-subtle rounded flex-center me-3 mb-sm-3 mb-md-0 mb-xl-3 mb-xxl-0" style="width:32px; height:32px"><span class="text-success-dark icon-saudi_riyal" style="width:24px; height:24px;font-weight: bold"></span></div>
<div>
<p class="fw-bold mb-1">{% trans 'Paid Amount' %}</p>
<h4 class="fw-bolder text-nowrap {% if invoice.is_paid %}text-success{% endif %}">{{invoice.amount_paid}}&nbsp;<span class="icon-saudi_riyal"></span></h4>

View File

@ -136,7 +136,7 @@
<div class="row">
<div class="col-md-6">
<p>
<strong>{% trans "Ledger Number" %}: </strong><a href="{% url 'ledger_detail' entity_slug=sale_order.invoice.ledger.entity.slug pk=sale_order.invoice.ledger.pk %}" target="_blank" rel="noopener noreferrer"> {{ sale_order.invoice.ledger }} <i class="fa fa-external-link" aria-hidden="true"></i></a><br>
<strong>{% trans "Ledger Number" %}: </strong><a href="{% url 'ledger_detail' dealer_slug=request.dealer.slug entity_slug=sale_order.invoice.ledger.entity.slug pk=sale_order.invoice.ledger.pk %}" target="_blank" rel="noopener noreferrer"> {{ sale_order.invoice.ledger }} <i class="fa fa-external-link" aria-hidden="true"></i></a><br>
<strong>{% trans "Date" %}:</strong> {{ sale_order.invoice.ledger.created|date }}<br>
</p>
</div>

View File

@ -23,11 +23,11 @@
</div>
</div>
<div class="table-responsive scrollbar mx-n1 px-1">
<div class="card-header ">
<div class="card-header ">
</div>
<h4 class="my-4">Groups</h4>
<a class="btn btn-sm btn-phoenix-primary mt-2 mb-4" href="{% url 'user_groups' user_.slug %}"><i class="fa-solid fa-users"></i> Manage Groups</a>
<a class="btn btn-sm btn-phoenix-primary mt-2 mb-4" href="{% url 'user_groups' request.dealer.slug user_.slug %}"><i class="fa-solid fa-users"></i> Manage Groups</a>
<table class="table table-hover table-responsive-sm fs-9 mb-0">
<thead>
<tr>
@ -48,20 +48,20 @@
</table>
</div>
<div class="card-footer d-flex ">
<a class="btn btn-sm btn-phoenix-primary me-1" href="{% url 'user_update' user_.slug %}">
<a class="btn btn-sm btn-phoenix-primary me-1" href="{% url 'user_update' request.dealer.slug user_.slug %}">
{{ _("Edit") }}
<i class="fa-solid fa-pen-to-square"></i>
</a>
<button class="btn btn-phoenix-danger btn-sm delete-btn me-1"
data-url="{% url 'user_delete' user_.slug %}"
data-message="{{ _("Are you sure you want to delete this user?")}}"
data-url="{% url 'user_delete' request.dealer.slug user_.slug %}"
data-message='{{ _("Are you sure you want to delete this user?")}}'
data-bs-toggle="modal" data-bs-target="#deleteModal">
{{ _("Delete") }}
<i class="fas fa-trash"></i>
</button>
<a class="btn btn-sm btn-phoenix-secondary"
href="{% url 'user_list' %}">
href="{% url 'user_list' request.dealer.slug %}">
{{ _("Back to List") }}
<i class="fa-regular fa-circle-left"></i>
</a>

View File

@ -12,12 +12,12 @@
<div class="d-md-flex justify-content-between">
<div>
{% if request.user.userplan %}
<a href="{% url 'user_create' %}" class="btn btn-sm btn-phoenix-primary me-4"><i class="fa-solid fa-user-tie me-1"></i> {% trans "Add New Staff" %}</a>
<a href="{% url 'group_list' %}" class="btn btn-sm btn-phoenix-success"><i class="fa-solid fa-user-group me-1"></i> {% trans "Manage Groups & Permissions" %}</a>
<a href="{% url 'user_create' request.dealer.slug %}" class="btn btn-sm btn-phoenix-primary me-4"><i class="fa-solid fa-user-tie me-1"></i> {% trans "Add New Staff" %}</a>
<a href="{% url 'group_list' request.dealer.slug %}" class="btn btn-sm btn-phoenix-success"><i class="fa-solid fa-user-group me-1"></i> {% trans "Manage Groups & Permissions" %}</a>
{% else %}
<div class="alert alert-outline-warning d-flex align-items-center" role="alert">
<i class="fa-solid fa-circle-info fs-6"></i>
<p class="mb-0 flex-1">{{ _("No Active Subscription,please activate your subscription.") }}<a href="{% url 'pricing_page' %}" class="ms-3 text-body-primary fs-9">Manage Subscription</a></p>
<p class="mb-0 flex-1">{{ _("No Active Subscription,please activate your subscription.") }}<a href="{% url 'pricing_page' request.dealer.slug %}" class="ms-3 text-body-primary fs-9">Manage Subscription</a></p>
<button class="btn-close" type="button" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endif %}
@ -41,8 +41,8 @@
<tr>
<td class="align-middle white-space-nowrap ps-1">
<div>
<a class="fs-8 fw-bold" href="{% url 'user_detail' user.slug%}">{{ user.arabic_name }}</a>
<a class="fs-8 fw-bold" href="{% url 'user_detail' request.dealer.slug user.slug%}">{{ user.arabic_name }}</a>
{{user.dealer}}
</div>
</td>
<td class="align-middle white-space-nowrap align-items-center">{{ user.email }}</td>
@ -53,7 +53,7 @@
<td class="align-middle white-space-nowrap">
<a class="btn btn-phoenix-success"
href="{% url 'user_detail' user.slug %}">
href="{% url 'user_detail' request.dealer.slug user.slug %}">
<i class="fa-solid fa-eye"></i>
{% trans 'view'|capfirst %}
</a>

View File

@ -11,7 +11,7 @@
<h3 class="">
{{ _("Vendors") |capfirst }}
</h2>
<a href="{% url 'vendor_create' %}"
<a href="{% url 'vendor_create' request.dealer.slug %}"
class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{{ _("Add Vendor") }}</a>
</div>
{% include "partials/search_box.html" %}
@ -92,7 +92,7 @@
{% endif %}
</div>
<div>
<a class="fs-8 fw-bold" href="{% url 'vendor_detail' vendor.slug %}">{{ vendor.arabic_name }}</a>
<a class="fs-8 fw-bold" href="{% url 'vendor_detail' request.dealer.slug vendor.slug %}">{{ vendor.arabic_name }}</a>
<div class="d-flex align-items-center">
<p class="mb-0 text-body-highlight fw-semibold fs-9 me-2">{{ vendor.name }}</p>
<!--<span class="badge badge-phoenix badge-phoenix-primary">{{ vendor.vendor_model.uuid }}</span>-->
@ -121,11 +121,11 @@
<span class="fas fa-ellipsis-h fs-10"></span>
</button>
<div class="dropdown-menu dropdown-menu-end py-2">
<a href="{% url 'vendor_update' vendor.slug %}"
<a href="{% url 'vendor_update' request.dealer.slug vendor.slug %}"
class="dropdown-item text-success-dark">{% trans "Edit" %}</a>
<div class="dropdown-divider"></div>
<button class="delete-btn dropdown-item text-danger"
data-url="{% url 'vendor_delete' vendor.slug %}"
data-url="{% url 'vendor_delete' request.dealer.slug vendor.slug %}"
data-message="{{ _("Are you sure you want to delete this vendor") }}?"
data-bs-toggle="modal"
data-bs-target="#deleteModal">{{ _("Delete") }}</button>

View File

@ -28,12 +28,12 @@
</ul>
</div>
<div class="card-footer d-flex">
<a class="btn btn-sm btn-phoenix-primary me-1" href="{% url 'vendor_update' vendor.slug %}">
<a class="btn btn-sm btn-phoenix-primary me-1" href="{% url 'vendor_update' request.dealer.slug vendor.slug %}">
{% trans "Edit" %}
<i class="fa fa-pencil"></i>
</a>
<button class="btn btn-phoenix-danger btn-sm delete-btn"
data-url="{% url 'vendor_delete' vendor.slug %}"
data-url="{% url 'vendor_delete' request.dealer.slug vendor.slug %}"
data-message="{{ _("Are you sure you want to delete this vendor")}}?"
data-bs-toggle="modal" data-bs-target="#deleteModal">
{{ _("Delete") }}