This commit is contained in:
Faheedkhan 2025-07-03 14:40:27 +03:00
parent a3e10e02ff
commit 747690a1b6
14 changed files with 188 additions and 66 deletions

View File

@ -2183,7 +2183,7 @@ class CustomerDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView
model = models.Customer model = models.Customer
template_name = "customers/view_customer.html" template_name = "customers/view_customer.html"
context_object_name = "customer" context_object_name = "customer"
permission_required = ["django_ledger.view_customermodel"] permission_required = ["inventory.view_customer"]
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
dealer = get_user_type(self.request) dealer = get_user_type(self.request)
@ -2292,7 +2292,7 @@ class CustomerCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView
model = models.Customer model = models.Customer
form_class = forms.CustomerForm form_class = forms.CustomerForm
permission_required = ["django_ledger.add_customermodel"] permission_required = ["inventory.add_customer"]
template_name = "customers/customer_form.html" template_name = "customers/customer_form.html"
success_url = reverse_lazy("customer_list") success_url = reverse_lazy("customer_list")
success_message = "Customer created successfully" success_message = "Customer created successfully"
@ -2359,7 +2359,7 @@ class CustomerUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView
model = models.Customer model = models.Customer
form_class = forms.CustomerForm form_class = forms.CustomerForm
permission_required = ["django_ledger.change_customermodel"] permission_required = ["inventory.change_customer"]
template_name = "customers/customer_form.html" template_name = "customers/customer_form.html"
success_url = reverse_lazy("customer_list") success_url = reverse_lazy("customer_list")
success_message = "Customer updated successfully" success_message = "Customer updated successfully"
@ -2371,6 +2371,7 @@ class CustomerUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView
def get_success_url(self): def get_success_url(self):
return reverse_lazy("customer_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]}) return reverse_lazy("customer_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]})
@permission_required('inventory.delete_customer',raise_exception=True)
@login_required @login_required
def delete_customer(request, dealer_slug ,slug): def delete_customer(request, dealer_slug ,slug):
""" """
@ -2425,6 +2426,7 @@ class VendorListView(LoginRequiredMixin, ListView):
context_object_name = "vendors" context_object_name = "vendors"
paginate_by = 30 paginate_by = 30
template_name = "vendors/vendors_list.html" template_name = "vendors/vendors_list.html"
permission_required='django_ledger.view_vendormodel'
def get_queryset(self): def get_queryset(self):
query = self.request.GET.get("q") query = self.request.GET.get("q")
@ -2436,6 +2438,7 @@ class VendorListView(LoginRequiredMixin, ListView):
@login_required @login_required
@permission_required('django_ledger.view_vendormodel',raise_exception=True)
def vendorDetailView(request, dealer_slug,slug): def vendorDetailView(request, dealer_slug,slug):
""" """
Fetches and renders the detail view for a specific vendor. Fetches and renders the detail view for a specific vendor.
@ -2485,6 +2488,7 @@ class VendorCreateView(
form_class = forms.VendorForm form_class = forms.VendorForm
template_name = "vendors/vendor_form.html" template_name = "vendors/vendor_form.html"
success_message = _("Vendor created successfully") success_message = _("Vendor created successfully")
permission_required='django_ledger.add_vendormodel'
def form_valid(self, form): def form_valid(self, form):
if vendor := models.Vendor.objects.filter(email=form.instance.email).first(): if vendor := models.Vendor.objects.filter(email=form.instance.email).first():
@ -2536,6 +2540,7 @@ class VendorUpdateView(
form_class = forms.VendorForm form_class = forms.VendorForm
template_name = "vendors/vendor_form.html" template_name = "vendors/vendor_form.html"
success_message = _("Vendor updated successfully") success_message = _("Vendor updated successfully")
permission_required='django_ledger.change_vendormodel'
# def get_initial(self): # def get_initial(self):
# initial = super().get_initial() # initial = super().get_initial()
@ -2560,6 +2565,7 @@ class VendorUpdateView(
return reverse_lazy("vendor_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]}) return reverse_lazy("vendor_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]})
@login_required @login_required
@permission_required('django_ledger.delete_vendormodel',raise_exception=True)
def delete_vendor(request, dealer_slug,slug): def delete_vendor(request, dealer_slug,slug):
""" """
Deletes an existing vendor record from the database. Deletes an existing vendor record from the database.
@ -3318,6 +3324,7 @@ class OrganizationListView(LoginRequiredMixin, ListView):
template_name = "organizations/organization_list.html" template_name = "organizations/organization_list.html"
context_object_name = "organizations" context_object_name = "organizations"
paginate_by = 20 paginate_by = 20
permission_required='inventory.view_organization'
def get_queryset(self): def get_queryset(self):
query = self.request.GET.get("q") query = self.request.GET.get("q")
@ -3349,6 +3356,7 @@ class OrganizationDetailView(LoginRequiredMixin, DetailView):
model = models.Organization model = models.Organization
template_name = "organizations/organization_detail.html" template_name = "organizations/organization_detail.html"
context_object_name = "organization" context_object_name = "organization"
permission_required='inventory.view_organization'
class OrganizationCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView): class OrganizationCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
""" """
@ -3368,7 +3376,7 @@ class OrganizationCreateView(LoginRequiredMixin, PermissionRequiredMixin, Create
model = models.Organization model = models.Organization
form_class = forms.OrganizationForm form_class = forms.OrganizationForm
permission_required = ["django_ledger.add_customermodel"] permission_required='inventory.add_organization'
template_name = "organizations/organization_form.html" template_name = "organizations/organization_form.html"
success_url = reverse_lazy("organization_list") success_url = reverse_lazy("organization_list")
success_message = "Organization created successfully" success_message = "Organization created successfully"
@ -3422,7 +3430,7 @@ class OrganizationUpdateView(LoginRequiredMixin, PermissionRequiredMixin, Update
model = models.Organization model = models.Organization
form_class = forms.OrganizationForm form_class = forms.OrganizationForm
permission_required = ["django_ledger.change_customermodel"] permission_required='inventory.change_organization'
template_name = "organizations/organization_form.html" template_name = "organizations/organization_form.html"
success_url = reverse_lazy("organization_list") success_url = reverse_lazy("organization_list")
success_message = "Organization updated successfully" success_message = "Organization updated successfully"
@ -3436,6 +3444,7 @@ class OrganizationUpdateView(LoginRequiredMixin, PermissionRequiredMixin, Update
return reverse_lazy("organization_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]}) return reverse_lazy("organization_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"]})
@login_required @login_required
@permission_required('inventory.delete_organization',raise_exception=True)
def OrganizationDeleteView(request,dealer_slug, slug): def OrganizationDeleteView(request,dealer_slug, slug):
""" """
Handles the deletion of an organization based on the provided primary key (pk). Looks up Handles the deletion of an organization based on the provided primary key (pk). Looks up
@ -3678,7 +3687,7 @@ class BankAccountCreateView(
form_class = BankAccountCreateForm form_class = BankAccountCreateForm
template_name = "ledger/bank_accounts/bank_account_form.html" template_name = "ledger/bank_accounts/bank_account_form.html"
success_message = _("Bank account created successfully") success_message = _("Bank account created successfully")
permission_required = ["inventory.view_carfinance"] permission_required = ["django_ledger.add_bankaccountmodel"]
def form_valid(self, form): def form_valid(self, form):
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"]) dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
@ -3732,7 +3741,7 @@ class BankAccountDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailV
model = BankAccountModel model = BankAccountModel
template_name = "ledger/bank_accounts/bank_account_detail.html" template_name = "ledger/bank_accounts/bank_account_detail.html"
context_object_name = "bank_account" context_object_name = "bank_account"
permission_required = ["inventory.view_carfinance"] permission_required = ["django_ledger.view_bankaccountmodel"]
class BankAccountUpdateView( class BankAccountUpdateView(
@ -3765,7 +3774,7 @@ class BankAccountUpdateView(
form_class = BankAccountUpdateForm form_class = BankAccountUpdateForm
template_name = "ledger/bank_accounts/bank_account_form.html" template_name = "ledger/bank_accounts/bank_account_form.html"
success_message = _("Bank account updated successfully") success_message = _("Bank account updated successfully")
permission_required = ["inventory.view_carfinance"] permission_required = ["django_ledger.change_bankaccountmodel"]
def get_form_kwargs(self): def get_form_kwargs(self):
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"]) dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
@ -3794,6 +3803,7 @@ class BankAccountUpdateView(
@login_required @login_required
@permission_required("django_ledger.delete_bankaccountmodel",raise_exception=True)
def bank_account_delete(request, dealer_slug, pk): def bank_account_delete(request, dealer_slug, pk):
""" """
Delete a bank account entry from the database. Delete a bank account entry from the database.
@ -3852,8 +3862,7 @@ class AccountListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
model = AccountModel model = AccountModel
template_name = "ledger/coa_accounts/account_list.html" template_name = "ledger/coa_accounts/account_list.html"
context_object_name = "accounts" context_object_name = "accounts"
permission_required = ["django_ledger.view_accountmodel"]
permission_required = ["inventory.view_carfinance"]
def get_queryset(self): def get_queryset(self):
query = self.request.GET.get("q") query = self.request.GET.get("q")
@ -3901,7 +3910,7 @@ class AccountCreateView(
form_class = AccountModelCreateForm form_class = AccountModelCreateForm
template_name = "ledger/coa_accounts/account_form.html" template_name = "ledger/coa_accounts/account_form.html"
success_message = _("Account created successfully") success_message = _("Account created successfully")
permission_required = ["inventory.view_carfinance"] permission_required = ["django_ledger.add_accountmodel"]
def form_valid(self, form): def form_valid(self, form):
dealer = get_user_type(self.request) dealer = get_user_type(self.request)
@ -3959,7 +3968,7 @@ class AccountDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView)
context_object_name = "account" context_object_name = "account"
slug_field = "uuid" slug_field = "uuid"
DEFAULT_TXS_DAYS = 30 DEFAULT_TXS_DAYS = 30
permission_required = ["inventory.view_carfinance"] permission_required = ["django_ledger.view_accountmodel"]
extra_context = { extra_context = {
"DEFAULT_TXS_DAYS": DEFAULT_TXS_DAYS, "DEFAULT_TXS_DAYS": DEFAULT_TXS_DAYS,
"header_subtitle_icon": "ic:round-account-tree", "header_subtitle_icon": "ic:round-account-tree",
@ -4019,7 +4028,7 @@ class AccountUpdateView(
form_class = AccountModelUpdateForm form_class = AccountModelUpdateForm
template_name = "ledger/coa_accounts/account_form.html" template_name = "ledger/coa_accounts/account_form.html"
success_message = _("Account updated successfully") success_message = _("Account updated successfully")
permission_required = ["inventory.view_carfinance"] permission_required = ["django_ledger.change_accountmodel"]
def get_form(self, form_class=None): def get_form(self, form_class=None):
form = super().get_form(form_class) form = super().get_form(form_class)
@ -4034,7 +4043,7 @@ class AccountUpdateView(
@login_required @login_required
@permission_required("inventory.view_carfinance") @permission_required("django_ledger.view_accountmodel",raise_exception=True)
def account_delete(request, dealer_slug, pk): def account_delete(request, dealer_slug, pk):
""" """
Handles the deletion of an account object identified by its primary key (pk). Ensures Handles the deletion of an account object identified by its primary key (pk). Ensures
@ -4092,6 +4101,7 @@ class SaleOrderDetailView(LoginRequiredMixin, DetailView):
model = models.SaleOrder model = models.SaleOrder
template_name = "sales/saleorder_detail.html" template_name = "sales/saleorder_detail.html"
context_object_name = "sale_order" context_object_name = "sale_order"
permission_required='inventory.view_saleorder'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
@ -4524,6 +4534,7 @@ class SaleOrderDetail(DetailView):
model = models.SaleOrder model = models.SaleOrder
template_name = "sales/orders/order_details.html" template_name = "sales/orders/order_details.html"
context_object_name = "saleorder" context_object_name = "saleorder"
permission_required='inventory.view_saleorder'
def get_object(self, queryset=None): def get_object(self, queryset=None):
order_pk = self.kwargs.get("order_pk") order_pk = self.kwargs.get("order_pk")
@ -4542,6 +4553,7 @@ class SaleOrderDetail(DetailView):
@login_required @login_required
@permission_required("inventory.view_saleorder",raise_exception=True)
def preview_sale_order(request, dealer_slug, pk): def preview_sale_order(request, dealer_slug, pk):
""" """
Handles rendering of the sale order preview page for a specific estimate. Handles rendering of the sale order preview page for a specific estimate.
@ -4829,7 +4841,7 @@ class DraftInvoiceModelUpdateFormView(
form_class = DraftInvoiceModelUpdateForm form_class = DraftInvoiceModelUpdateForm
template_name = "sales/invoices/draft_invoice_update.html" template_name = "sales/invoices/draft_invoice_update.html"
success_url = reverse_lazy("invoice_list") success_url = reverse_lazy("invoice_list")
permission_required = ["django_ledger.view_invoicemodel"] permission_required = ["django_ledger.change_invoicemodel"]
def get_form_kwargs(self): def get_form_kwargs(self):
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
@ -4871,7 +4883,7 @@ class ApprovedInvoiceModelUpdateFormView(
form_class = ApprovedInvoiceModelUpdateForm form_class = ApprovedInvoiceModelUpdateForm
template_name = "sales/invoices/approved_invoice_update.html" template_name = "sales/invoices/approved_invoice_update.html"
success_url = reverse_lazy("invoice_list") success_url = reverse_lazy("invoice_list")
permission_required = ["django_ledger.view_invoicemodel"] permission_required = ["django_ledger.change_invoicemodel"]
def get_form_kwargs(self): def get_form_kwargs(self):
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
@ -4919,7 +4931,7 @@ class PaidInvoiceModelUpdateFormView(
form_class = PaidInvoiceModelUpdateForm form_class = PaidInvoiceModelUpdateForm
template_name = "sales/invoices/paid_invoice_update.html" template_name = "sales/invoices/paid_invoice_update.html"
success_url = reverse_lazy("invoice_list") success_url = reverse_lazy("invoice_list")
permission_required = ["django_ledger.view_invoicemodel"] permission_required = ["django_ledger.change_invoicemodel"]
def get_form_kwargs(self): def get_form_kwargs(self):
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
@ -5101,7 +5113,7 @@ class InvoicePreviewView(LoginRequiredMixin, PermissionRequiredMixin, DetailView
@login_required @login_required
@permission_required("django_ledger.add_journalentrymodel", raise_exception=True) @permission_required("inventory.add_payment", raise_exception=True)
def PaymentCreateView(request, dealer_slug, pk): def PaymentCreateView(request, dealer_slug, pk):
""" """
Handles the creation of a payment entry associated with an invoice or bill. Validates Handles the creation of a payment entry associated with an invoice or bill. Validates
@ -5176,7 +5188,7 @@ def PaymentCreateView(request, dealer_slug, pk):
@login_required @login_required
@permission_required("django_ledger.view_journalentrymodel", raise_exception=True) @permission_required("inventory.view_payment", raise_exception=True)
def PaymentListView(request, dealer_slug): def PaymentListView(request, dealer_slug):
""" """
Handles the view for listing payment information associated with the journals of a specific Handles the view for listing payment information associated with the journals of a specific
@ -5206,7 +5218,7 @@ def PaymentListView(request, dealer_slug):
@login_required @login_required
@permission_required("django_ledger.view_journalentrymodel", raise_exception=True) @permission_required("inventory.view_payment", raise_exception=True)
def PaymentDetailView(request, dealer_slug, pk): def PaymentDetailView(request, dealer_slug, pk):
""" """
This function handles the detail view for a payment by fetching a journal entry This function handles the detail view for a payment by fetching a journal entry
@ -5236,7 +5248,7 @@ def PaymentDetailView(request, dealer_slug, pk):
@login_required @login_required
@permission_required("django_ledger.change_journalentrymodel", raise_exception=True) @permission_required("inventory.change_payment", raise_exception=True)
def payment_mark_as_paid(request, dealer_slug, pk): def payment_mark_as_paid(request, dealer_slug, pk):
""" """
Marks an invoice as paid if it meets the conditions of being fully paid and eligible Marks an invoice as paid if it meets the conditions of being fully paid and eligible
@ -5567,6 +5579,7 @@ def lead_tracking(request,dealer_slug):
# @require_POST # @require_POST
@permission_required("inventory.change_lead", raise_exception=True)
def update_lead_actions(request,dealer_slug): def update_lead_actions(request,dealer_slug):
try: try:
lead_id = request.POST.get("lead_id") lead_id = request.POST.get("lead_id")
@ -5682,6 +5695,7 @@ def LeadDeleteView(request,dealer_slug, slug):
@login_required @login_required
@permission_required("inventory.change_lead", raise_exception=True)
def add_note_to_lead(request,dealer_slug, slug): def add_note_to_lead(request,dealer_slug, slug):
""" """
Adds a note to a specific lead. This view is accessible only to authenticated Adds a note to a specific lead. This view is accessible only to authenticated
@ -5714,6 +5728,7 @@ def add_note_to_lead(request,dealer_slug, slug):
@login_required @login_required
@permission_required("inventory.change_opportunity", raise_exception=True)
def add_note_to_opportunity(request,dealer_slug, slug): def add_note_to_opportunity(request,dealer_slug, slug):
""" """
Add a note to a specific opportunity identified by its primary key. Add a note to a specific opportunity identified by its primary key.
@ -6090,6 +6105,7 @@ class OpportunityCreateView(CreateView, SuccessMessageMixin, LoginRequiredMixin)
form_class = forms.OpportunityForm form_class = forms.OpportunityForm
template_name = "crm/opportunities/opportunity_form.html" template_name = "crm/opportunities/opportunity_form.html"
success_message = "Opportunity created successfully." success_message = "Opportunity created successfully."
permission_required='inventory.add_opportunity'
def get_initial(self): def get_initial(self):
initial = super().get_initial() initial = super().get_initial()
@ -6141,6 +6157,7 @@ class OpportunityUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView)
form_class = forms.OpportunityForm form_class = forms.OpportunityForm
template_name = "crm/opportunities/opportunity_form.html" template_name = "crm/opportunities/opportunity_form.html"
success_message = "Opportunity updated successfully." success_message = "Opportunity updated successfully."
permission_required='inventory.change_opportunity'
def get_success_url(self): def get_success_url(self):
return reverse_lazy("opportunity_detail", kwargs={"dealer_slug":self.kwargs.get("dealer_slug"),"slug": self.object.slug}) return reverse_lazy("opportunity_detail", kwargs={"dealer_slug":self.kwargs.get("dealer_slug"),"slug": self.object.slug})
@ -6166,6 +6183,7 @@ class OpportunityDetailView(LoginRequiredMixin, DetailView):
model = models.Opportunity model = models.Opportunity
template_name = "crm/opportunities/opportunity_detail.html" template_name = "crm/opportunities/opportunity_detail.html"
context_object_name = "opportunity" context_object_name = "opportunity"
permission_required='inventory.view_opportunity'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
@ -6265,6 +6283,7 @@ class OpportunityListView(LoginRequiredMixin, ListView):
@login_required @login_required
@permission_required('inventory.delete_opportunity',raise_exception=True)
def delete_opportunity(request,dealer_slug, pk): def delete_opportunity(request,dealer_slug, pk):
""" """
Deletes an opportunity object from the database and redirects to the opportunity Deletes an opportunity object from the database and redirects to the opportunity
@ -6436,7 +6455,7 @@ class ItemServiceCreateView(
template_name = "items/service/service_create.html" template_name = "items/service/service_create.html"
success_message = _("Service created successfully") success_message = _("Service created successfully")
context_object_name = "service" context_object_name = "service"
permission_required = ["django_ledger.add_itemmodel"] permission_required = ["inventory.add_additionalservices"]
def form_valid(self, form): def form_valid(self, form):
vat = models.VatRate.objects.get(is_active=True) vat = models.VatRate.objects.get(is_active=True)
@ -6482,7 +6501,8 @@ class ItemServiceUpdateView(
template_name = "items/service/service_create.html" template_name = "items/service/service_create.html"
success_message = _("Service updated successfully") success_message = _("Service updated successfully")
context_object_name = "service" context_object_name = "service"
permission_required = ["django_ledger.change_itemmodel"] permission_required = ["inventory.change_additionalservices"]
def form_valid(self, form): def form_valid(self, form):
vat = models.VatRate.objects.get(is_active=True) vat = models.VatRate.objects.get(is_active=True)
@ -6520,7 +6540,8 @@ class ItemServiceListView(LoginRequiredMixin, PermissionRequiredMixin, ListView)
template_name = "items/service/service_list.html" template_name = "items/service/service_list.html"
context_object_name = "services" context_object_name = "services"
paginate_by = 30 paginate_by = 30
permission_required = ["django_ledger.view_itemmodel"] permission_required = ["inventory.view_additionalservices"]
def get_queryset(self): def get_queryset(self):
dealer = get_user_type(self.request) dealer = get_user_type(self.request)
@ -7031,6 +7052,7 @@ def bill_mark_as_paid(request, pk):
class BillModelCreateView(CreateView): class BillModelCreateView(CreateView):
template_name = "bill/bill_create.html" template_name = "bill/bill_create.html"
PAGE_TITLE = _("Create Bill") PAGE_TITLE = _("Create Bill")
permission_required = ["django_ledger.add_billmodel"]
extra_context = { extra_context = {
"page_title": PAGE_TITLE, "page_title": PAGE_TITLE,
"header_title": PAGE_TITLE, "header_title": PAGE_TITLE,
@ -7213,6 +7235,7 @@ class BillModelCreateView(CreateView):
class BillModelDetailViewView(BillModelDetailView): class BillModelDetailViewView(BillModelDetailView):
template_name = "bill/bill_detail.html" template_name = "bill/bill_detail.html"
permission_required = ["django_ledger.view_billmodel"]
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(BillModelDetailViewView, self).get_context_data(**kwargs) context = super(BillModelDetailViewView, self).get_context_data(**kwargs)
@ -7222,6 +7245,8 @@ class BillModelDetailViewView(BillModelDetailView):
class BillModelUpdateViewView(BillModelUpdateView): class BillModelUpdateViewView(BillModelUpdateView):
template_name = "bill/bill_update.html" template_name = "bill/bill_update.html"
permission_required = ["django_ledger.change_billmodel"]
def post(self, request, dealer_slug, entity_slug, bill_pk, *args, **kwargs): def post(self, request, dealer_slug, entity_slug, bill_pk, *args, **kwargs):
if self.action_update_items: if self.action_update_items:
@ -7492,7 +7517,7 @@ class OrderListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
# email # email
@login_required @login_required
@permission_required("django_ledger.view_estimatemodel", raise_exception=True) @permission_required("django_ledger.change_estimatemodel", raise_exception=True)
def send_email_view(request, dealer_slug, pk): def send_email_view(request, dealer_slug, pk):
""" """
View function to send an email for an estimate. This function allows authenticated and View function to send an email for an estimate. This function allows authenticated and
@ -8578,6 +8603,7 @@ class LedgerModelListView(LoginRequiredMixin, ListView, ArchiveIndexView):
model = LedgerModel model = LedgerModel
context_object_name = "ledgers" context_object_name = "ledgers"
template_name = "ledger/ledger/ledger_list.html" template_name = "ledger/ledger/ledger_list.html"
permission_required = ["django_ledger.view_ledgermodel"]
date_field = "created" date_field = "created"
ordering = "-created" ordering = "-created"
show_all = False show_all = False
@ -8629,6 +8655,7 @@ class LedgerModelDetailView(LoginRequiredMixin, DetailView):
model = LedgerModel model = LedgerModel
context_object_name = "ledger" context_object_name = "ledger"
template_name = "ledger/ledger/ledger_detail.html" template_name = "ledger/ledger/ledger_detail.html"
permission_required = ["django_ledger.view_ledgermodel"]
class LedgerModelCreateView(LedgerModelCreateViewBase): class LedgerModelCreateView(LedgerModelCreateViewBase):
@ -8646,6 +8673,7 @@ class LedgerModelCreateView(LedgerModelCreateViewBase):
""" """
template_name = "ledger/ledger/ledger_form.html" template_name = "ledger/ledger/ledger_form.html"
permission_required = ["django_ledger.add_ledgermodel"]
def get_form(self, form_class=None): def get_form(self, form_class=None):
dealer = get_user_type(self.request) dealer = get_user_type(self.request)
@ -8701,6 +8729,7 @@ class LedgerModelDeleteView(LedgerModelDeleteViewBase, SuccessMessageMixin):
template_name = "ledger/ledger/ledger_delete.html" template_name = "ledger/ledger/ledger_delete.html"
success_message = "Ledger deleted" success_message = "Ledger deleted"
permission_required = ["django_ledger.delete_ledgermodel"]
def get_success_url(self): def get_success_url(self):
return reverse("ledger_list", args=[self.kwargs["dealer_slug"]]) return reverse("ledger_list", args=[self.kwargs["dealer_slug"]])
@ -8749,6 +8778,7 @@ class JournalEntryListView(LoginRequiredMixin, ListView):
model = JournalEntryModel model = JournalEntryModel
context_object_name = "journal_entries" context_object_name = "journal_entries"
template_name = "ledger/journal_entry/journal_entry_list.html" template_name = "ledger/journal_entry/journal_entry_list.html"
permission_required = ["django_ledger.view_journalentrymodel"]
ordering = ["-timestamp"] ordering = ["-timestamp"]
def get_queryset(self): def get_queryset(self):
@ -8786,6 +8816,7 @@ class JournalEntryCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView
model = JournalEntryModel model = JournalEntryModel
template_name = "ledger/journal_entry/journal_entry_form.html" template_name = "ledger/journal_entry/journal_entry_form.html"
permission_required = ["django_ledger.add_journalentrymodel"]
form_class = forms.JournalEntryModelCreateForm form_class = forms.JournalEntryModelCreateForm
ledger_model = None ledger_model = None
success_message = _("Journal Entry created") success_message = _("Journal Entry created")
@ -8808,7 +8839,7 @@ class JournalEntryCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView
ledger = LedgerModel.objects.filter(pk=self.kwargs["pk"]).first() ledger = LedgerModel.objects.filter(pk=self.kwargs["pk"]).first()
return reverse("journalentry_list", kwargs={"dealer_slug":self.kwargs["dealer_slug"],"pk": ledger.pk}) return reverse("journalentry_list", kwargs={"dealer_slug":self.kwargs["dealer_slug"],"pk": ledger.pk})
@permission_required("django_ledger.view_journalentrymodel",raise_exception=True)
def JournalEntryDeleteView(request, pk): def JournalEntryDeleteView(request, pk):
""" """
Handles the deletion of a specific journal entry. This view facilitates Handles the deletion of a specific journal entry. This view facilitates
@ -9458,10 +9489,11 @@ def permenant_delete_account(request,dealer_slug, content_type, slug):
##################################################################### #####################################################################
@permission_required("django_ledger.add_purchaseordermodel",raise_exception=True)
def PurchaseOrderCreateView(request, dealer_slug,entity_slug): def PurchaseOrderCreateView(request, dealer_slug,entity_slug):
dealer = get_object_or_404(models.Dealer, slug=dealer_slug) dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
entity = dealer.entity entity = dealer.entity
if request.method == "POST": if request.method == "POST":
try: try:
po = entity.create_purchase_order(po_title=request.POST.get("po_title")) po = entity.create_purchase_order(po_title=request.POST.get("po_title"))
@ -9479,7 +9511,7 @@ def PurchaseOrderCreateView(request, dealer_slug,entity_slug):
) )
return render(request, "purchase_orders/po_form.html", {"form": form}) return render(request, "purchase_orders/po_form.html", {"form": form})
@permission_required("inventory.add_car",raise_exception=True)
def InventoryItemCreateView(request, dealer_slug): def InventoryItemCreateView(request, dealer_slug):
dealer = get_object_or_404(models.Dealer, slug=dealer_slug) dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
for_po = request.GET.get("for_po") for_po = request.GET.get("for_po")
@ -9592,8 +9624,9 @@ def inventory_items_filter(request, dealer_slug):
class PurchaseOrderDetailView(PurchaseOrderModelDetailViewBase): class PurchaseOrderDetailView(PurchaseOrderModelDetailViewBase):
template_name = "purchase_orders/po_detail.html" template_name = "purchase_orders/po_detail.html"
context_object_name = "po_model" context_object_name = "po_model"
permission_required = ["inventory.view_carfinance"] permission_required=["django_ledger.view_purchaseordermodel"]
def get_queryset(self): def get_queryset(self):
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"]) dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
self.queryset = dealer.entity.get_purchase_orders().select_related("entity", "ce_model") self.queryset = dealer.entity.get_purchase_orders().select_related("entity", "ce_model")
@ -9611,7 +9644,8 @@ class PurchaseOrderListView(LoginRequiredMixin, PermissionRequiredMixin, ListVie
context_object_name = "purchase_orders" context_object_name = "purchase_orders"
paginate_by = 20 paginate_by = 20
template_name = "purchase_orders/po_list.html" template_name = "purchase_orders/po_list.html"
permission_required = ["inventory.view_carfinance"] permission_required=["django_ledger.view_purchaseordermodel"]
def get_queryset(self): def get_queryset(self):
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"]) dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
@ -9695,6 +9729,8 @@ class PurchaseOrderListView(LoginRequiredMixin, PermissionRequiredMixin, ListVie
class PurchaseOrderUpdateView(PurchaseOrderModelUpdateViewBase): class PurchaseOrderUpdateView(PurchaseOrderModelUpdateViewBase):
template_name = "purchase_orders/po_update.html" template_name = "purchase_orders/po_update.html"
context_object_name = "po_model" context_object_name = "po_model"
permission_required=["django_ledger.change_purchaseordermodel"]
def get_context_data(self, itemtxs_formset=None, **kwargs): def get_context_data(self, itemtxs_formset=None, **kwargs):
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"]) dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
@ -9868,6 +9904,8 @@ class BasePurchaseOrderActionActionView(BasePurchaseOrderActionActionViewBase):
class PurchaseOrderModelDeleteView(PurchaseOrderModelDeleteViewBase): class PurchaseOrderModelDeleteView(PurchaseOrderModelDeleteViewBase):
template_name = "purchase_orders/po_delete.html" template_name = "purchase_orders/po_delete.html"
permission_required=["django_ledger.delete_purchaseordermodel"]
def get_success_url(self): def get_success_url(self):
messages.add_message( messages.add_message(
@ -10129,6 +10167,7 @@ def bulk_update_car_price(request):
class InventoryListView(InventoryListViewBase): class InventoryListView(InventoryListViewBase):
template_name = "inventory/list.html" template_name = "inventory/list.html"
permission_required=['inventory.view_car']
def get_queryset(self): def get_queryset(self):
dealer = get_user_type(self.request) dealer = get_user_type(self.request)

View File

@ -172,6 +172,7 @@
<li class="nav-item text-nowrap me-2" role="presentation"><a class="nav-link" id="notes-tab" data-bs-toggle="tab" href="#tab-notes" role="tab" aria-controls="tab-notes" aria-selected="false" tabindex="-1"> <span class="fa-solid fa-clipboard me-2 tab-icon-color fs-8"></span>{{ _("Notes") }}</a></li> <li class="nav-item text-nowrap me-2" role="presentation"><a class="nav-link" id="notes-tab" data-bs-toggle="tab" href="#tab-notes" role="tab" aria-controls="tab-notes" aria-selected="false" tabindex="-1"> <span class="fa-solid fa-clipboard me-2 tab-icon-color fs-8"></span>{{ _("Notes") }}</a></li>
<li class="nav-item text-nowrap me-2" role="presentation"><a class="nav-link" id="emails-tab" data-bs-toggle="tab" href="#tab-emails" role="tab" aria-controls="tab-emails" aria-selected="true"> <span class="fa-solid fa-envelope me-2 tab-icon-color fs-8"></span>{{ _("Emails") }}</a></li> <li class="nav-item text-nowrap me-2" role="presentation"><a class="nav-link" id="emails-tab" data-bs-toggle="tab" href="#tab-emails" role="tab" aria-controls="tab-emails" aria-selected="true"> <span class="fa-solid fa-envelope me-2 tab-icon-color fs-8"></span>{{ _("Emails") }}</a></li>
<li class="nav-item text-nowrap me-2" role="presentation"><a class="nav-link" id="tasks-tab" data-bs-toggle="tab" href="#tab-tasks" role="tab" aria-controls="tab-tasks" aria-selected="true"> <span class="fa-solid fa-envelope me-2 tab-icon-color fs-8"></span>{{ _("Tasks") }}</a></li> <li class="nav-item text-nowrap me-2" role="presentation"><a class="nav-link" id="tasks-tab" data-bs-toggle="tab" href="#tab-tasks" role="tab" aria-controls="tab-tasks" aria-selected="true"> <span class="fa-solid fa-envelope me-2 tab-icon-color fs-8"></span>{{ _("Tasks") }}</a></li>
{% if perms.inventory.change_lead%}
<li class="nav-item text-nowrap ml-auto" role="presentation"> <li class="nav-item text-nowrap ml-auto" role="presentation">
<button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#exampleModal"> <i class="fa-solid fa-user-plus me-2"></i> Reassign Lead</button> <button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#exampleModal"> <i class="fa-solid fa-user-plus me-2"></i> Reassign Lead</button>
<button class="btn btn-phoenix-primary btn-sm" onclick="openActionModal('{{ lead.id }}', '{{ lead.action }}', '{{ lead.next_action }}', '{{ lead.next_action_date|date:"Y-m-d\TH:i" }}')"> <button class="btn btn-phoenix-primary btn-sm" onclick="openActionModal('{{ lead.id }}', '{{ lead.action }}', '{{ lead.next_action }}', '{{ lead.next_action_date|date:"Y-m-d\TH:i" }}')">
@ -199,12 +200,15 @@
</div> </div>
</div> </div>
</li> </li>
{% endif %}
</ul> </ul>
<div class="tab-content" id="myTabContent"> <div class="tab-content" id="myTabContent">
<div class="tab-pane fade" id="tab-activity" role="tabpanel" aria-labelledby="activity-tab"> <div class="tab-pane fade" id="tab-activity" role="tabpanel" aria-labelledby="activity-tab">
<div class="mb-1 d-flex justify-content-between align-items-center"> <div class="mb-1 d-flex justify-content-between align-items-center">
<h3 class="mb-4" id="s crollspyTask">{{ _("Activities") }} <span class="fw-light fs-7">({{ activities.count}})</span></h3> <h3 class="mb-4" id="s crollspyTask">{{ _("Activities") }} <span class="fw-light fs-7">({{ activities.count}})</span></h3>
{% if perms.inventory.change_lead%}
<button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#activityModal"><span class="fas fa-plus me-1"></span>{{ _("Add Activity") }}</button> <button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#activityModal"><span class="fas fa-plus me-1"></span>{{ _("Add Activity") }}</button>
{% endif %}
</div> </div>
<div class="row justify-content-between align-items-md-center hover-actions-trigger btn-reveal-trigger border-translucent py-3 gx-0 border-top"> <div class="row justify-content-between align-items-md-center hover-actions-trigger btn-reveal-trigger border-translucent py-3 gx-0 border-top">
<div class="col-12 col-lg-auto"> <div class="col-12 col-lg-auto">
@ -252,7 +256,9 @@
<div class="tab-pane fade active show" id="tab-opportunity" role="tabpanel" aria-labelledby="opportunity-tab"> <div class="tab-pane fade active show" id="tab-opportunity" role="tabpanel" aria-labelledby="opportunity-tab">
<div class="mb-1 d-flex justify-content-between align-items-center"> <div class="mb-1 d-flex justify-content-between align-items-center">
<h3 class="mb-4" id="scrollspyTask">{{ _("Opportunities") }} <span class="fw-light fs-7">({{ lead.get_opportunities.count}})</span></h3> <h3 class="mb-4" id="scrollspyTask">{{ _("Opportunities") }} <span class="fw-light fs-7">({{ lead.get_opportunities.count}})</span></h3>
{% if perms.inventory.add_opportunity%}
<a href="{% url 'lead_opportunity_create' request.dealer.slug lead.slug %}" class="btn btn-phoenix-primary btn-sm" type="button"> <i class="fa-solid fa-plus me-2"></i>{{ _("Add Opportunity") }}</a> <a href="{% url 'lead_opportunity_create' request.dealer.slug lead.slug %}" class="btn btn-phoenix-primary btn-sm" type="button"> <i class="fa-solid fa-plus me-2"></i>{{ _("Add Opportunity") }}</a>
{% endif%}
</div> </div>
<div class="border-top border-bottom border-translucent" id="leadDetailsTable"> <div class="border-top border-bottom border-translucent" id="leadDetailsTable">
@ -284,7 +290,9 @@
<div class="tab-pane fade" id="tab-notes" role="tabpanel" aria-labelledby="notes-tab"> <div class="tab-pane fade" id="tab-notes" role="tabpanel" aria-labelledby="notes-tab">
<div class="mb-1 d-flex align-items-center justify-content-between"> <div class="mb-1 d-flex align-items-center justify-content-between">
<h3 class="mb-4" id="scrollspyNotes">{{ _("Notes") }}</h3> <h3 class="mb-4" id="scrollspyNotes">{{ _("Notes") }}</h3>
{% if perms.inventory.change_lead%}
<button class="btn btn-phoenix-primary btn-sm" type="button" onclick="reset_form()" data-bs-toggle="modal" data-bs-target="#noteModal"><span class="fas fa-plus me-1"></span>{{ _("Add Note") }}</button> <button class="btn btn-phoenix-primary btn-sm" type="button" onclick="reset_form()" data-bs-toggle="modal" data-bs-target="#noteModal"><span class="fas fa-plus me-1"></span>{{ _("Add Note") }}</button>
{% endif %}
</div> </div>
<div class="border-top border-bottom border-translucent" id="leadDetailsTable"> <div class="border-top border-bottom border-translucent" id="leadDetailsTable">
@ -340,12 +348,14 @@
<div class="tab-pane fade" id="tab-emails" role="tabpanel" aria-labelledby="emails-tab"> <div class="tab-pane fade" id="tab-emails" role="tabpanel" aria-labelledby="emails-tab">
<div class="mb-1 d-flex justify-content-between align-items-center"> <div class="mb-1 d-flex justify-content-between align-items-center">
<h3 class="mb-0" id="scrollspyEmails">{{ _("Emails") }}</h3> <h3 class="mb-0" id="scrollspyEmails">{{ _("Emails") }}</h3>
{% if perms.inventory.change_lead%}
<a href="{% url 'send_lead_email' request.dealer.slug lead.slug %}"> <a href="{% url 'send_lead_email' request.dealer.slug lead.slug %}">
<button type="button" class="btn btn-sm btn-phoenix-primary"> <button type="button" class="btn btn-sm btn-phoenix-primary">
<span class="fas fa-plus me-1"></span> <span class="fas fa-plus me-1"></span>
{% trans 'Send Email' %} {% trans 'Send Email' %}
</button> </button>
</a> </a>
{% endif %}
</div> </div>
<div> <div>
<div class="scrollbar"> <div class="scrollbar">
@ -462,7 +472,9 @@
<div class="tab-pane fade" id="tab-tasks" role="tabpanel" aria-labelledby="tasks-tab"> <div class="tab-pane fade" id="tab-tasks" role="tabpanel" aria-labelledby="tasks-tab">
<div class="mb-1 d-flex justify-content-between align-items-center"> <div class="mb-1 d-flex justify-content-between align-items-center">
<h3 class="mb-0" id="scrollspyEmails">{{ _("Tasks") }}</h3> <h3 class="mb-0" id="scrollspyEmails">{{ _("Tasks") }}</h3>
{% if perms.inventory.change_lead%}
<button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#taskModal"><span class="fas fa-plus me-1"></span>{{ _("Add Task") }}</button> <button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#taskModal"><span class="fas fa-plus me-1"></span>{{ _("Add Task") }}</button>
{% endif %}
</div> </div>
<div> <div>

View File

@ -212,18 +212,23 @@
{% if perms.inventory.change_lead %} {% if perms.inventory.change_lead %}
<a href="{% url 'lead_update' request.dealer.slug lead.slug %}" class="dropdown-item text-success-dark">{% trans "Edit" %}</a> <a href="{% url 'lead_update' request.dealer.slug lead.slug %}" class="dropdown-item text-success-dark">{% trans "Edit" %}</a>
{% endif %} {% endif %}
{% if perms.inventory.change_lead%}
<button class="dropdown-item text-primary" onclick="openActionModal('{{ lead.pk }}', '{{ lead.action }}', '{{ lead.next_action }}', '{{ lead.next_action_date|date:"Y-m-d\TH:i" }}')"> <button class="dropdown-item text-primary" onclick="openActionModal('{{ lead.pk }}', '{{ lead.action }}', '{{ lead.next_action }}', '{{ lead.next_action_date|date:"Y-m-d\TH:i" }}')">
{% trans "Update Actions" %} {% trans "Update Actions" %}
</button> </button>
<a href="{% url 'send_lead_email' request.dealer.slug lead.slug %}" class="dropdown-item text-success-dark">{% trans "Send Email" %}</a> <a href="{% url 'send_lead_email' request.dealer.slug lead.slug %}" class="dropdown-item text-success-dark">{% trans "Send Email" %}</a>
<a href="{% url 'schedule_lead' request.dealer.slug lead.slug %}" class="dropdown-item text-success-dark">{% trans "Schedule Event" %}</a> <a href="{% url 'schedule_lead' request.dealer.slug lead.slug %}" class="dropdown-item text-success-dark">{% trans "Schedule Event" %}</a>
{% endif %}
{% if not lead.opportunity %} {% if not lead.opportunity %}
{% if perms.inventory.add_opportunity%}
<a href="{% url 'lead_opportunity_create' request.dealer.slug lead.slug %}" class="dropdown-item text-success-dark">{% trans "Convert to Opportunity" %}</a> <a href="{% url 'lead_opportunity_create' request.dealer.slug lead.slug %}" class="dropdown-item text-success-dark">{% trans "Convert to Opportunity" %}</a>
{% endif %}
{% endif %} {% endif %}
<div class="dropdown-divider"></div>
{% if perms.inventory.delete_lead %} {% if perms.inventory.delete_lead %}
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">{% trans "Delete" %}</button> <button class="dropdown-item text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">{% trans "Delete" %}</button>
{% endif %} {%endif%}
</div> </div>
</div> </div>
{% endif %} {% endif %}

View File

@ -13,14 +13,22 @@
<ul class="dropdown-menu dropdown-menu-end p-0" style="z-index: 9999;"> <ul class="dropdown-menu dropdown-menu-end p-0" style="z-index: 9999;">
<li> <li>
{% if opportunity.estimate %} {% if opportunity.estimate %}
{% if perms.django_ledger.view_estimatemodel%}
<a class="dropdown-item" href="{% url 'estimate_detail' request.dealer.slug opportunity.estimate.pk %}">{{ _("View Quotation")}}</a> <a class="dropdown-item" href="{% url 'estimate_detail' request.dealer.slug opportunity.estimate.pk %}">{{ _("View Quotation")}}</a>
{% endif %}
{% else %} {% else %}
{%if perms.django_ledger.add_estimatemodel%}
<a class="dropdown-item" href="{% url 'estimate_create_from_opportunity' request.dealer.slug opportunity.slug %}">{{ _("Create Quotation")}}</a> <a class="dropdown-item" href="{% url 'estimate_create_from_opportunity' request.dealer.slug opportunity.slug %}">{{ _("Create Quotation")}}</a>
{% endif %}
{% endif %} {% endif %}
</li> </li>
{% if perms.inventory.change_opportunity%}
<li><a class="dropdown-item" href="{% url 'update_opportunity' request.dealer.slug opportunity.slug %}">Update Opportunity</a></li> <li><a class="dropdown-item" href="{% url 'update_opportunity' request.dealer.slug opportunity.slug %}">Update Opportunity</a></li>
<li><a class="dropdown-item" href="{% url 'update_opportunity' request.dealer.slug opportunity.slug %}">Update Stage</a></li> <li><a class="dropdown-item" href="{% url 'update_opportunity' request.dealer.slug opportunity.slug %}">Update Stage</a></li>
{% endif %}
{% if perms.inventory.delete_opportunity%}
<li><a class="dropdown-item text-danger" href="">Delete Opportunity</a></li> <li><a class="dropdown-item text-danger" href="">Delete Opportunity</a></li>
{% endif %}
</ul> </ul>
</div> </div>
</div> </div>
@ -348,9 +356,11 @@
</form> </form>
</div> </div>
</div> </div>
{%if perms.inventory.change_opportunity%}
<div class="col-auto"> <div class="col-auto">
<button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#activityModal"><span class="fas fa-plus me-1"></span>{{ _("Add Activity") }}</button> <button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#activityModal"><span class="fas fa-plus me-1"></span>{{ _("Add Activity") }}</button>
</div> </div>
{% endif %}
</div> </div>
{% for activity in opportunity.get_activities %} {% for activity in opportunity.get_activities %}
<div class="border-bottom border-translucent py-4"> <div class="border-bottom border-translucent py-4">
@ -392,11 +402,13 @@
</div> </div>
<div class="tab-pane fade" id="tab-notes" role="tabpanel" aria-labelledby="notes-tab"> <div class="tab-pane fade" id="tab-notes" role="tabpanel" aria-labelledby="notes-tab">
<h2 class="mb-4">Notes</h2> <h2 class="mb-4">Notes</h2>
{%if perms.inventory.change_opportunity%}
<form action="{% url 'add_note_to_opportunity' request.dealer.slug opportunity.slug %}" method="post"> <form action="{% url 'add_note_to_opportunity' request.dealer.slug opportunity.slug %}" method="post">
{% csrf_token %} {% csrf_token %}
<textarea class="form-control mb-3" id="notes" rows="4" name="notes" required> </textarea> <textarea class="form-control mb-3" id="notes" rows="4" name="notes" required> </textarea>
<button type="submit" class="btn btn-phoenix-primary mb-3">Add Note</button> <button type="submit" class="btn btn-phoenix-primary mb-3">Add Note</button>
</form> </form>
{% endif %}
<div class="row gy-4 note-list"> <div class="row gy-4 note-list">
<div class="col-12 col-xl-auto flex-1"> <div class="col-12 col-xl-auto flex-1">
{% for note in opportunity.get_notes %} {% for note in opportunity.get_notes %}
@ -427,9 +439,11 @@
<p class="mb-0 fs-9 text-body-tertiary fw-bold"><span class="fas fa-filter me-1 fw-extra-bold fs-10"></span>23 tasks</p> <p class="mb-0 fs-9 text-body-tertiary fw-bold"><span class="fas fa-filter me-1 fw-extra-bold fs-10"></span>23 tasks</p>
<button class="btn btn-link p-0 ms-3 fs-9 text-primary fw-bold text-decoration-none"><span class="fas fa-sort me-1 fw-extra-bold fs-10"></span>Sorting</button> <button class="btn btn-link p-0 ms-3 fs-9 text-primary fw-bold text-decoration-none"><span class="fas fa-sort me-1 fw-extra-bold fs-10"></span>Sorting</button>
</div> </div>
{% if perms.inventory.change_opportunity%}
<div class="col-auto"> <div class="col-auto">
<a href="{% url 'schedule_lead' request.dealer.slug opportunity.lead.slug %}" class="btn btn-phoenix-primary"><span class="fa-solid fa-plus me-2"></span>Add Meeting </a> <a href="{% url 'schedule_lead' request.dealer.slug opportunity.lead.slug %}" class="btn btn-phoenix-primary"><span class="fa-solid fa-plus me-2"></span>Add Meeting </a>
</div> </div>
{% endif %}
</div> </div>
<div class="row g-3"> <div class="row g-3">
{% for metting in opportunity.lead.get_meetings %} {% for metting in opportunity.lead.get_meetings %}
@ -454,10 +468,12 @@
<div class="col-auto d-flex flex-1"> <div class="col-auto d-flex flex-1">
<h2 class="mb-0">Call</h2> <h2 class="mb-0">Call</h2>
</div> </div>
{% if perms.inventory.change_opportunity%}
<div class="col-auto"> <div class="col-auto">
<a href="{% url 'schedule_lead' request.dealer.slug opportunity.lead.slug %}" class="btn btn-phoenix-primary"><span class="fa-solid fa-plus me-2"></span>Add Call</a> <a href="{% url 'schedule_lead' request.dealer.slug opportunity.lead.slug %}" class="btn btn-phoenix-primary"><span class="fa-solid fa-plus me-2"></span>Add Call</a>
</div> </div>
{% endif %}
</div> </div>
<pre>{{opportunity.get_all_notes}}</pre> <pre>{{opportunity.get_all_notes}}</pre>
<div class="border-top border-bottom border-translucent" id="leadDetailsTable" data-list='{"valueNames":["name","description","create_date","create_by","last_activity"],"page":5,"pagination":true}'> <div class="border-top border-bottom border-translucent" id="leadDetailsTable" data-list='{"valueNames":["name","description","create_date","create_by","last_activity"],"page":5,"pagination":true}'>
@ -503,6 +519,7 @@
</div> </div>
<div class="tab-pane fade" id="tab-emails" role="tabpanel" aria-labelledby="emails-tab"> <div class="tab-pane fade" id="tab-emails" role="tabpanel" aria-labelledby="emails-tab">
<h2 class="mb-4">Emails</h2> <h2 class="mb-4">Emails</h2>
{% if perms.inventory.change_opportunity%}
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
<a href="{% url 'send_lead_email' request.dealer.slug opportunity.lead.slug %}"> <a href="{% url 'send_lead_email' request.dealer.slug opportunity.lead.slug %}">
<button type="button" class="btn btn-sm btn-phoenix-primary"> <button type="button" class="btn btn-sm btn-phoenix-primary">
@ -511,6 +528,7 @@
</button> </button>
</a> </a>
</div> </div>
{% endif %}
<div> <div>
<div class="scrollbar"> <div class="scrollbar">
<ul class="nav nav-underline fs-9 flex-nowrap mb-1" id="emailTab" role="tablist"> <ul class="nav nav-underline fs-9 flex-nowrap mb-1" id="emailTab" role="tablist">
@ -580,7 +598,9 @@
<div class="tab-pane fade" id="tab-tasks" role="tabpanel" aria-labelledby="tasks-tab"> <div class="tab-pane fade" id="tab-tasks" role="tabpanel" aria-labelledby="tasks-tab">
<div class="mb-1 d-flex justify-content-between align-items-center"> <div class="mb-1 d-flex justify-content-between align-items-center">
<h3 class="mb-0" id="scrollspyEmails">{{ _("Tasks") }}</h3> <h3 class="mb-0" id="scrollspyEmails">{{ _("Tasks") }}</h3>
{% if perms.inventory.change_opportunity%}
<button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#taskModal"><span class="fas fa-plus me-1"></span>{{ _("Add Task") }}</button> <button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#taskModal"><span class="fas fa-plus me-1"></span>{{ _("Add Task") }}</button>
{% endif %}
</div> </div>
<div> <div>

View File

@ -119,12 +119,16 @@
</div> </div>
<div class="d-flex gap-2"> <div class="d-flex gap-2">
{% if perms.inventory.view_opportunity%}
<a class="btn btn-sm btn-phoenix-primary" href="{% url 'opportunity_detail' request.dealer.slug opportunity.slug %}"> <a class="btn btn-sm btn-phoenix-primary" href="{% url 'opportunity_detail' request.dealer.slug opportunity.slug %}">
<i class="fa-solid fa-eye ms-2"></i>{{ _("View") }} <i class="fa-solid fa-eye ms-2"></i>{{ _("View") }}
</a> </a>
{% endif %}
{%if perms.inventory.change_opportunity%}
<a class="btn btn-sm btn-phoenix-success" href="{% url 'update_opportunity' request.dealer.slug opportunity.slug %}"> <a class="btn btn-sm btn-phoenix-success" href="{% url 'update_opportunity' request.dealer.slug opportunity.slug %}">
<i class="fa-solid fa-pen ms-2"></i> {{ _("Update") }} <i class="fa-solid fa-pen ms-2"></i> {{ _("Update") }}
</a> </a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -10,7 +10,7 @@
<div class="row g-3 justify-content-between mb-4"> <div class="row g-3 justify-content-between mb-4">
<div class="col-auto"> <div class="col-auto">
<div class="d-md-flex justify-content-between"> <div class="d-md-flex justify-content-between">
{% if perms.django_ledger.add_customermodel %} {% if perms.inventory.add_customer %}
<div> <div>
<a href="{% url 'customer_create' request.dealer.slug %}" class="btn btn-sm btn-phoenix-primary me-4"><span class="fas fa-plus me-2"></span>{{ _("Add Customer") }}</a> <a href="{% url 'customer_create' request.dealer.slug %}" class="btn btn-sm btn-phoenix-primary me-4"><span class="fas fa-plus me-2"></span>{{ _("Add Customer") }}</a>
</div> </div>
@ -68,6 +68,7 @@
<td> <td>
</td> </td>
{% if perms.inventory.view_customer%}
<td class="name align-middle white-space-nowrap ps-0"> <td class="name align-middle white-space-nowrap ps-0">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<div><a class="fs-8 fw-bold" href="{% url 'customer_detail' request.dealer.slug customer.slug %}">{{ customer.full_name }}</a> <div><a class="fs-8 fw-bold" href="{% url 'customer_detail' request.dealer.slug customer.slug %}">{{ customer.full_name }}</a>
@ -76,6 +77,7 @@
</div> </div>
</div> </div>
</td> </td>
{% endif %}
<td class="email align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent"><a class="text-body-highlight" href="">{{ customer.email }}</a></td> <td class="email align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent"><a class="text-body-highlight" href="">{{ customer.email }}</a></td>
<td class="phone align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent"><a class="text-body-highlight" href="tel:{{ customer.phone }}">{{ customer.phone_number }}</a></td> <td class="phone align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent"><a class="text-body-highlight" href="tel:{{ customer.phone }}">{{ customer.phone_number }}</a></td>
<td class="contact align-middle white-space-nowrap ps-4 border-end border-translucent fw-semibold text-body-highlight">{{ customer.national_id }}</td> <td class="contact align-middle white-space-nowrap ps-4 border-end border-translucent fw-semibold text-body-highlight">{{ customer.national_id }}</td>
@ -90,12 +92,12 @@
</td> </td>
<td class="date align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 text-body-tertiary">{{ customer.created|date }}</td> <td class="date align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 text-body-tertiary">{{ customer.created|date }}</td>
<td class="align-middle white-space-nowrap text-end pe-0 ps-4"> <td class="align-middle white-space-nowrap text-end pe-0 ps-4">
{% if perms.django_ledger.change_customermodel %} {% if perms.inventory.change_customer %}
<a href="{% url 'customer_update' request.dealer.slug customer.slug %}" class="btn btn-sm btn-phoenix-primary me-2" data-url="{% url 'customer_update' request.dealer.slug customer.slug %}"> <a href="{% url 'customer_update' request.dealer.slug customer.slug %}" class="btn btn-sm btn-phoenix-primary me-2" data-url="{% url 'customer_update' request.dealer.slug customer.slug %}">
<i class="fas fa-pen"></i> <i class="fas fa-pen"></i>
</a> </a>
{% endif %} {% endif %}
{% if perms.django_ledger.delete_customermodel %} {% if perms.inventory.delete_customer %}
<button class="btn btn-phoenix-danger btn-sm delete-btn" <button class="btn btn-phoenix-danger btn-sm delete-btn"
data-url="{% url 'customer_delete' request.dealer.slug customer.slug %}" data-url="{% url 'customer_delete' request.dealer.slug customer.slug %}"
data-message="{{ _("Are you sure you want to delete this customer")}}" data-message="{{ _("Are you sure you want to delete this customer")}}"

View File

@ -14,22 +14,25 @@
</div> </div>
<div class="col-auto"> <div class="col-auto">
<div class="row g-3"> <div class="row g-3">
<div class="col-auto">
{% if perms.inventory.change_customer %}
<a href="{% url 'customer_update' request.dealer.slug customer.slug %}" class="btn btn-sm btn-phoenix-primary"><span class="fa-solid fa-pen-to-square me-2"></span>{{_("Update")}}</a>
{% endif %}
</div>
{% if perms.inventory.delete_customer%}
<div class="col-auto"> <div class="col-auto">
{% if perms.django_ledger.delete_customermodel %}
<button class="btn btn-phoenix-danger btn-sm delete-btn" <button class="btn btn-phoenix-danger btn-sm delete-btn"
data-url="{% url 'customer_delete' request.dealer.slug customer.slug %}" data-url="{% url 'customer_delete' request.dealer.slug customer.slug %}"
data-message="Are you sure you want to delete this customer?" data-message="Are you sure you want to delete this customer?"
data-bs-toggle="modal" data-bs-target="#deleteModal"> data-bs-toggle="modal" data-bs-target="#deleteModal">
<i class="fas fa-trash me-1"> </i>{{ _("Delete") }} <i class="fas fa-trash me-1"> </i>{{ _("Delete") }}
</button> </button>
{% endif %}
</div> </div>
{% endif %}
<div class="col-auto">
{% if perms.django_ledger.change_customermodel %}
<a href="{% url 'customer_update' request.dealer.slug customer.slug %}" class="btn btn-sm btn-phoenix-primary"><span class="fa-solid fa-pen-to-square me-2"></span>{{_("Update")}}</a>
{% endif %}
</div>
</div> </div>
</div> </div>
</div> </div>
@ -84,16 +87,14 @@
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
{% if perms.inventory.change_customer%}
<div class="d-flex align-items-center justify-content-end"> <div class="d-flex align-items-center justify-content-end">
<a id="addBtn" href="#" class="btn btn-sm btn-phoenix-primary mb-3" data-url="{% url 'add_note_to_customer' request.dealer.slug customer.slug %}" data-bs-toggle="modal" data-bs-target="#noteModal" data-note-title="{{ _("Add") }}<i class='fa fa-plus-circle text-success ms-2'></i>"> <a id="addBtn" href="#" class="btn btn-sm btn-phoenix-primary mb-3" data-url="{% url 'add_note_to_customer' request.dealer.slug customer.slug %}" data-bs-toggle="modal" data-bs-target="#noteModal" data-note-title="{{ _("Add") }}<i class='fa fa-plus-circle text-success ms-2'></i>">
<span class="fas fa-plus me-1"></span> <span class="fas fa-plus me-1"></span>
{% trans 'Add Note' %} {% trans 'Add Note' %}
</a> </a>
{% comment %} <a id="addBtn" class="btn btn-sm btn-phoenix-primary mb-3" hx-get="{% url 'add_note_to_customer' request.dealer.slug customer.slug %}" hx-target=".modal-body" hx-swap="innerHTML" hx-push-url="false" data-bs-toggle="modal" data-bs-target="#noteModal">
<span class="fas fa-plus me-1"></span>
{% trans 'Add Note' %}
</a> {% endcomment %}
</div> </div>
{% endif %}
<table class="table fs-9 mb-0 table-responsive"> <table class="table fs-9 mb-0 table-responsive">
<tr> <tr>
<th class="align-middle pe-6 text-start" scope="col">{{ _("Note") }}</th> <th class="align-middle pe-6 text-start" scope="col">{{ _("Note") }}</th>

View File

@ -16,7 +16,7 @@
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div> <div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div>
<span class="nav-link-icon"><span class="fas fa-warehouse"></span></span><span class="nav-link-text">{% trans "Inventory"|capfirst %}</span> <span class="nav-link-icon"><span class="fas fa-warehouse"></span></span><span class="nav-link-text">{% trans "Inventory"|capfirst %}</span>
</div> </div>
</a> </a>
<div class="parent-wrapper label-1"> <div class="parent-wrapper label-1">
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-inventory"> <ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-inventory">
<li class="collapsed-nav-item-title d-none">{% trans "Inventory"|capfirst %}</li> <li class="collapsed-nav-item-title d-none">{% trans "Inventory"|capfirst %}</li>
@ -61,7 +61,7 @@
</div> </div>
</div> </div>
{% if perms.inventory.view_lead or perms.django_ledger.view_invoicemodel %} {% if perms.django_ledger.view_estimatemodel %}
<div class="nav-item-wrapper"> <div class="nav-item-wrapper">
<a class="nav-link dropdown-indicator label-1" href="#nv-sales" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-sales"> <a class="nav-link dropdown-indicator label-1" href="#nv-sales" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-sales">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
@ -90,7 +90,7 @@
</a> </a>
</li> </li>
{% endif %} {% endif %}
{%if perms.inventory.view_saleorder%}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{% url 'sales_list' request.dealer.slug %}"> <a class="nav-link" href="{% url 'sales_list' request.dealer.slug %}">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
@ -98,6 +98,7 @@
</div> </div>
</a> </a>
</li> </li>
{% endif %}
{% if perms.django_ledger.view_invoicemodel %} {% if perms.django_ledger.view_invoicemodel %}
<li class="nav-item"> <li class="nav-item">
@ -108,7 +109,7 @@
</a> </a>
</li> </li>
{% endif %} {% endif %}
{% if perms.django_ledger.view_journalentrymodel %} {% if perms.inventory.view_payment %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{% url 'payment_list' request.dealer.slug %}"> <a class="nav-link" href="{% url 'payment_list' request.dealer.slug %}">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
@ -123,7 +124,7 @@
</div> </div>
{% endif %} {% endif %}
{% if perms.inventory.view_lead %} {% if perms.inventory.view_lead or perms.inventory.view_oportunity or perms.inventory.view_customer or perms.inventory.view_organization %}
<div class="nav-item-wrapper"> <div class="nav-item-wrapper">
<a class="nav-link dropdown-indicator label-1" href="#nv-crm" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-crm"> <a class="nav-link dropdown-indicator label-1" href="#nv-crm" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-crm">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
@ -222,11 +223,12 @@
<a class="nav-link" href="{% url 'bank_account_list' request.dealer.slug %}"> <a class="nav-link" href="{% url 'bank_account_list' request.dealer.slug %}">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<span class="nav-link-icon"><span data-feather="credit-card"></span></span><span class="nav-link-text">{% trans 'Bank Accounts'|capfirst %}</span> <span class="nav-link-icon"><span data-feather="credit-card"></span></span><span class="nav-link-text">{% trans 'Bank Accounts'|capfirst %}</span>
</div> </div>
</a> </a>
</li> </li>
{% endif %} {% endif %}
{% if perms.django_ledger.view_itemmodel %}
{% if perms.django_ledger.view_journalentrymodel %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{% url 'ledger_list' request.dealer.slug %}"> <a class="nav-link" href="{% url 'ledger_list' request.dealer.slug %}">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
@ -235,6 +237,8 @@
</a> </a>
</li> </li>
{% endif %} {% endif %}
{% if perms.inventory.view_additionalservices %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{% url 'item_service_list' request.dealer.slug %}"> <a class="nav-link" href="{% url 'item_service_list' request.dealer.slug %}">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
@ -242,6 +246,8 @@
</div> </div>
</a> </a>
</li> </li>
{% endif %}
{% if perms.django_ledger.view_itemmodel %} {% if perms.django_ledger.view_itemmodel %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{% url 'item_expense_list' request.dealer.slug %}"> <a class="nav-link" href="{% url 'item_expense_list' request.dealer.slug %}">
@ -270,6 +276,7 @@
</li> </li>
{% endif %} {% endif %}
{% if perms.django_ledger.view_purchaseordermodel %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{% url 'purchase_order_list' request.dealer.slug request.dealer.entity.slug %}"> <a class="nav-link" href="{% url 'purchase_order_list' request.dealer.slug request.dealer.entity.slug %}">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
@ -277,6 +284,7 @@
</div> </div>
</a> </a>
</li> </li>
{% endif %}
</ul> </ul>
</div> </div>

View File

@ -11,13 +11,17 @@
<li class="list-group-item"><strong>{% trans "Address" %}:</strong> {{ organization.address }}</li> <li class="list-group-item"><strong>{% trans "Address" %}:</strong> {{ organization.address }}</li>
</ul> </ul>
<div class="d-flex"> <div class="d-flex">
{% if perms.inventory.change_organization%}
<a href="{% url 'organization_update' request.dealer.slug organization.slug %}" class="btn btn-sm btn-phoenix-primary me-2"><span class="fas fa-edit me-1"></span>{% trans "Edit" %}</a> <a href="{% url 'organization_update' request.dealer.slug organization.slug %}" class="btn btn-sm btn-phoenix-primary me-2"><span class="fas fa-edit me-1"></span>{% trans "Edit" %}</a>
{% endif %}
{% if perms.inventory.delete_organization%}
<button class="btn btn-phoenix-danger btn-sm delete-btn" <button class="btn btn-phoenix-danger btn-sm delete-btn"
data-url="{% url 'organization_delete' request.dealer.slug organization.slug %}" data-url="{% url 'organization_delete' request.dealer.slug organization.slug %}"
data-message="Are you sure you want to delete this organization?" data-message="Are you sure you want to delete this organization?"
data-bs-toggle="modal" data-bs-target="#deleteModal"> data-bs-toggle="modal" data-bs-target="#deleteModal">
<i class="fas fa-trash me-1"></i> {% trans 'Delete' %} <i class="fas fa-trash me-1"></i> {% trans 'Delete' %}
</button> </button>
{% endif %}
</div> </div>
</div> </div>
{% include 'modal/delete_modal.html' %} {% include 'modal/delete_modal.html' %}

View File

@ -16,7 +16,7 @@
<div class="row g-3 justify-content-between mb-4"> <div class="row g-3 justify-content-between mb-4">
<div class="col-auto"> <div class="col-auto">
<div class="d-md-flex justify-content-between"> <div class="d-md-flex justify-content-between">
{% if perms.django_ledger.add_customermodel %} {% if perms.inventory.add_organization%}
<div> <div>
<a href="{% url 'organization_create' request.dealer.slug %}" class="btn btn-sm btn-phoenix-primary"><span class="fas fa-plus me-2"></span>{% trans 'add organization'|capfirst %}</a> <a href="{% url 'organization_create' request.dealer.slug %}" class="btn btn-sm btn-phoenix-primary"><span class="fas fa-plus me-2"></span>{% trans 'add organization'|capfirst %}</a>
</div> </div>
@ -106,17 +106,20 @@
<td class="company align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 border-end border-translucent fw-semibold text-body-highlight">{{ org.address }}</td> <td class="company align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 border-end border-translucent fw-semibold text-body-highlight">{{ org.address }}</td>
<td class="date align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 text-body-tertiary">{{ org.created|date }}</td> <td class="date align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 text-body-tertiary">{{ org.created|date }}</td>
<td class="align-middle white-space-nowrap text-end pe-0 ps-4"> <td class="align-middle white-space-nowrap text-end pe-0 ps-4">
{% if perms.django_ledger.change_customermodel %} {% if perms.inventory.change_organization or perms.inventory.delete_organization%}
<div class="btn-reveal-trigger position-static"> <div class="btn-reveal-trigger position-static">
<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> <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"> <div class="dropdown-menu dropdown-menu-end py-2">
{% if perms.inventory.change_organization %}
<a href="{% url 'organization_update' request.dealer.slug org.slug %}" class="dropdown-item text-success-dark">{% trans 'Edit' %}</a> <a href="{% url 'organization_update' request.dealer.slug org.slug %}" class="dropdown-item text-success-dark">{% trans 'Edit' %}</a>
{% if perms.django_ledger.delete_customermodel %} {% endif %}
{% if perms.inventory.delete_organization %}
<div class="dropdown-divider"></div><button class="dropdown-item text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">{% trans 'Delete' %}</button> <div class="dropdown-divider"></div><button class="dropdown-item text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">{% trans 'Delete' %}</button>
{% endif %} {% endif %}
</div> </div>
</div> </div>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -161,7 +161,9 @@
</div> </div>
<div class="card-footer bg-light"> <div class="card-footer bg-light">
{% if perms.django_ledger.change_purchaseordermodel%}
<div class="d-flex flex-wrap gap-2 justify-content-between"> <div class="d-flex flex-wrap gap-2 justify-content-between">
<a href="{% url 'purchase_order_update' dealer_slug=request.dealer.slug entity_slug=entity_slug po_pk=po_model.pk %}" <a href="{% url 'purchase_order_update' dealer_slug=request.dealer.slug entity_slug=entity_slug po_pk=po_model.pk %}"
class="btn btn-phoenix-primary"> class="btn btn-phoenix-primary">
<i class="fas fa-edit me-2"></i>{% trans 'Update' %} <i class="fas fa-edit me-2"></i>{% trans 'Update' %}
@ -200,10 +202,12 @@
{# Danger Action Buttons #} {# Danger Action Buttons #}
{% if po_model.can_delete %} {% if po_model.can_delete %}
{% if perms.django_ledger.delete_purchaseordermodel%}
<button class="btn btn-outline-danger" <button class="btn btn-outline-danger"
onclick="showPOModal('Delete PO', '{% url 'po-delete' request.dealer.slug entity_slug po_model.pk %}', 'Delete')"> onclick="showPOModal('Delete PO', '{% url 'po-delete' request.dealer.slug entity_slug po_model.pk %}', 'Delete')">
<i class="fas fa-ban me-2"></i>{% trans 'Delete' %} <i class="fas fa-ban me-2"></i>{% trans 'Delete' %}
</button> </button>
{% endif %}
{% endif %} {% endif %}
{% if po_model.can_void %} {% if po_model.can_void %}
@ -222,10 +226,12 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
{% endif %}
</div> </div>
</div> </div>
{% endif %} {% endif %}
{% else %} {% else %}
{% if perms.django_ledger.add_purchaseordermodel%}
<div class="card border-0 shadow-sm text-center py-5"> <div class="card border-0 shadow-sm text-center py-5">
<div class="card-body"> <div class="card-body">
<a href="{% url 'purchase_order_create' request.dealer.slug request.dealer.entity.slug %}" class="text-decoration-none"> <a href="{% url 'purchase_order_create' request.dealer.slug request.dealer.entity.slug %}" class="text-decoration-none">
@ -234,4 +240,5 @@
</a> </a>
</div> </div>
</div> </div>
{% endif %}
{% endif %} {% endif %}

View File

@ -21,6 +21,7 @@
<th style="min-width: 600px;" class="d-flex justify-content-between align-items-center"> <th style="min-width: 600px;" class="d-flex justify-content-between align-items-center">
{% trans 'Item' %} {% trans 'Item' %}
{% if po_model.is_draft %} {% if po_model.is_draft %}
<button type="button" <button type="button"
class="btn btn-sm btn-phoenix-success" class="btn btn-sm btn-phoenix-success"
data-bs-toggle="modal" data-bs-toggle="modal"
@ -65,18 +66,23 @@
<span class="currency">{{CURRENCY}}</span>{{ f.instance.po_total_amount | currency_format }}</td> <span class="currency">{{CURRENCY}}</span>{{ f.instance.po_total_amount | currency_format }}</td>
<td>{{ f.po_item_status|add_class:"form-control" }}</td> <td>{{ f.po_item_status|add_class:"form-control" }}</td>
{% if itemtxs_formset.can_delete %} {% if itemtxs_formset.can_delete %}
<td class="text-center"> <td class="text-center">
{{ f.DELETE|add_class:"form-check-input" }} {{ f.DELETE|add_class:"form-check-input" }}
</td> </td>
{% endif %} {% endif %}
<td class="text-center"> <td class="text-center">
{% if f.instance.can_create_bill %} {% if f.instance.can_create_bill %}
{% if perms.djagno_ledger.add_billmodel%}
{{ f.create_bill|add_class:"form-check-input" }} {{ f.create_bill|add_class:"form-check-input" }}
{% endif %}
{% elif f.instance.bill_model %} {% elif f.instance.bill_model %}
{% if perms.djagno_ledger.view_billmodel%}
<a class="btn btn-sm btn-phoenix-secondary" <a class="btn btn-sm btn-phoenix-secondary"
href="{% url 'bill-detail' dealer_slug=dealer_slug entity_slug=entity_slug bill_pk=f.instance.bill_model_id %}"> href="{% url 'bill-detail' dealer_slug=dealer_slug entity_slug=entity_slug bill_pk=f.instance.bill_model_id %}">
{% trans 'View Bill' %} {% trans 'View Bill' %}
</a> </a>
{% endif %}
{% endif %} {% endif %}
</td> </td>
<td class="text-center"> <td class="text-center">

View File

@ -18,10 +18,12 @@
<h3 class=""> <h3 class="">
{{ _("Purchase Orders") |capfirst }} {{ _("Purchase Orders") |capfirst }}
</h2> </h2>
{% if perms.django_ledger.add_purchaseordermodel%}
<div> <div>
<a href="{% url 'purchase_order_create' request.dealer.slug request.dealer.entity.slug %}" <a href="{% url 'purchase_order_create' request.dealer.slug request.dealer.entity.slug %}"
class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{{ _("Create New PO") }}</a> class="btn btn-md btn-phoenix-primary"><i class="fa fa-plus me-2"></i>{{ _("Create New PO") }}</a>
</div> </div>
{% endif %}
</div> </div>
{% include "partials/search_box.html" %} {% include "partials/search_box.html" %}
@ -67,7 +69,9 @@
<div class="dropdown-menu dropdown-menu-end py-2"> <div class="dropdown-menu dropdown-menu-end py-2">
<a href="{% url 'purchase_order_detail' request.dealer.slug request.dealer.entity.slug po.pk %}" class="dropdown-item text-success-dark">{% trans 'Purchase Order Detail' %}</a> <a href="{% url 'purchase_order_detail' request.dealer.slug request.dealer.entity.slug po.pk %}" class="dropdown-item text-success-dark">{% trans 'Purchase Order Detail' %}</a>
{% if po.po_status == 'fulfilled' %} {% if po.po_status == 'fulfilled' %}
{% if perms.inventory.add_car %}
<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 'Add Inventory Items' %}</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 'Add Inventory Items' %}</a>
{% endif %}
{% else %} {% 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> <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 %} {% endif %}

View File

@ -84,26 +84,33 @@
{% if perms.django_ledger.can_approve_estimatemodel %} {% if perms.django_ledger.can_approve_estimatemodel %}
<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> <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>
{% endif %} {% endif %}
{% elif estimate.status == 'approved' %} {% elif estimate.status == 'approved' %}
<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> {% if perms.django_ledger.change_estimatemodel %}
<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>
{% endif %}
{% if estimate.sale_orders.first %} {% if estimate.sale_orders.first %}
<!--if sale order exist--> <!--if sale order exist-->
{% if perms.djagno_ledger.add_invoice %} {% if perms.djagno_ledger.add_invoice %}
<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 '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>
{% endif %} {% endif %}
{% if perms.inventory.view_saleorder%}
<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 '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>
{% endif %}
{% else %} {% else %}
{% if perms.inventory.add_saleorder%}
<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> <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 %}
{% endif %} {% endif %}
{% elif estimate.status == 'completed' %} {% elif estimate.status == 'completed' %}
{% if perms.inventory.view_saleorder%}
<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 '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>
{% endif %}
{% if perms.django_ledger.view_invoicemodel %}
<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> <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> {{ _("View Invoice")}}</a>
{% endif %}
{% endif %} {% endif %}
{% if estimate.can_cancel %} {% if estimate.can_cancel %}