update
This commit is contained in:
parent
a4433631fb
commit
c92371a9b5
Binary file not shown.
Binary file not shown.
@ -5,7 +5,7 @@ from django.conf import settings
|
|||||||
from django.conf.urls.i18n import i18n_patterns
|
from django.conf.urls.i18n import i18n_patterns
|
||||||
from inventory import views
|
from inventory import views
|
||||||
import debug_toolbar
|
import debug_toolbar
|
||||||
from two_factor.urls import urlpatterns as tf_urls
|
# from two_factor.urls import urlpatterns as tf_urls
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('__debug__/', include(debug_toolbar.urls)),
|
path('__debug__/', include(debug_toolbar.urls)),
|
||||||
@ -26,7 +26,7 @@ urlpatterns += i18n_patterns(
|
|||||||
path("haikalbot/", include("haikalbot.urls")),
|
path("haikalbot/", include("haikalbot.urls")),
|
||||||
path('appointment/', include('appointment.urls')),
|
path('appointment/', include('appointment.urls')),
|
||||||
path('plans/', include('plans.urls')),
|
path('plans/', include('plans.urls')),
|
||||||
path('', include(tf_urls)),
|
# path('', include(tf_urls)),
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -422,10 +422,12 @@ class CarSelectionTable(tables.Table):
|
|||||||
|
|
||||||
class WizardForm1(forms.Form):
|
class WizardForm1(forms.Form):
|
||||||
email = forms.EmailField(
|
email = forms.EmailField(
|
||||||
|
label=_("Email Address"),
|
||||||
widget=forms.EmailInput(
|
widget=forms.EmailInput(
|
||||||
attrs={
|
attrs={
|
||||||
"class": "form-control",
|
"class": "form-control form-control-sm email",
|
||||||
"placeholder": "Email address",
|
"placeholder": _("Email address"),
|
||||||
|
"name": _("email"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
@ -433,10 +435,12 @@ class WizardForm1(forms.Form):
|
|||||||
"required": _("You must add an email."),
|
"required": _("You must add an email."),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
password = forms.CharField(
|
password = forms.CharField(
|
||||||
|
label=_("Password"),
|
||||||
widget=forms.PasswordInput(
|
widget=forms.PasswordInput(
|
||||||
attrs={
|
attrs={
|
||||||
"class": "form-control",
|
"class": "form-control form-control-sm",
|
||||||
"placeholder": _("Password"),
|
"placeholder": _("Password"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
}
|
}
|
||||||
@ -445,10 +449,12 @@ class WizardForm1(forms.Form):
|
|||||||
"required": _("This field is required."),
|
"required": _("This field is required."),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
confirm_password = forms.CharField(
|
confirm_password = forms.CharField(
|
||||||
|
label=_("Confirm Password"),
|
||||||
widget=forms.PasswordInput(
|
widget=forms.PasswordInput(
|
||||||
attrs={
|
attrs={
|
||||||
"class": "form-control",
|
"class": "form-control form-control-sm",
|
||||||
"placeholder": _("Confirm Password"),
|
"placeholder": _("Confirm Password"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
}
|
}
|
||||||
@ -457,7 +463,9 @@ class WizardForm1(forms.Form):
|
|||||||
"required": _("This field is required."),
|
"required": _("This field is required."),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
terms = forms.BooleanField(
|
terms = forms.BooleanField(
|
||||||
|
label=_("I accept the Terms and Privacy Policy"),
|
||||||
widget=forms.CheckboxInput(
|
widget=forms.CheckboxInput(
|
||||||
attrs={
|
attrs={
|
||||||
"class": "form-check-input",
|
"class": "form-check-input",
|
||||||
@ -472,9 +480,10 @@ class WizardForm1(forms.Form):
|
|||||||
|
|
||||||
class WizardForm2(forms.Form):
|
class WizardForm2(forms.Form):
|
||||||
name = forms.CharField(
|
name = forms.CharField(
|
||||||
|
label=_("Name"),
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
"class": "form-control",
|
"class": "form-control form-control-sm",
|
||||||
"placeholder": _("English Name"),
|
"placeholder": _("English Name"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
}
|
}
|
||||||
@ -483,10 +492,12 @@ class WizardForm2(forms.Form):
|
|||||||
"required": _("Please enter an English Name."),
|
"required": _("Please enter an English Name."),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
arabic_name = forms.CharField(
|
arabic_name = forms.CharField(
|
||||||
|
label=_("Arabic Name"),
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
"class": "form-control",
|
"class": "form-control form-control-sm",
|
||||||
"placeholder": _("Arabic Name"),
|
"placeholder": _("Arabic Name"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
}
|
}
|
||||||
@ -495,12 +506,14 @@ class WizardForm2(forms.Form):
|
|||||||
"required": _("Please enter an Arabic name."),
|
"required": _("Please enter an Arabic name."),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
phone_number = PhoneNumberField(
|
phone_number = PhoneNumberField(
|
||||||
|
label=_("Phone Number"),
|
||||||
min_length=10,
|
min_length=10,
|
||||||
max_length=10,
|
max_length=10,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
"class": "form-control",
|
"class": "form-control form-control-sm",
|
||||||
"placeholder": _("Phone"),
|
"placeholder": _("Phone"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
}
|
}
|
||||||
@ -516,9 +529,10 @@ class WizardForm2(forms.Form):
|
|||||||
class WizardForm3(forms.Form):
|
class WizardForm3(forms.Form):
|
||||||
# CRN field with max length of 10
|
# CRN field with max length of 10
|
||||||
crn = forms.CharField(
|
crn = forms.CharField(
|
||||||
|
label=_("CRN"),
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
"class": "form-control",
|
"class": "form-control form-control-sm",
|
||||||
"placeholder": _("Commercial Registration Number"),
|
"placeholder": _("Commercial Registration Number"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
"maxlength": "10",
|
"maxlength": "10",
|
||||||
@ -526,16 +540,17 @@ class WizardForm3(forms.Form):
|
|||||||
),
|
),
|
||||||
max_length=10,
|
max_length=10,
|
||||||
error_messages={
|
error_messages={
|
||||||
"required": "This field is required.",
|
"required": _("This field is required."),
|
||||||
"max_length": "Commercial Registration Number must be 10 characters.",
|
"max_length": "Commercial Registration Number must be 10 characters.",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
# VRN field with max length of 15
|
# VRN field with max length of 15
|
||||||
vrn = forms.CharField(
|
vrn = forms.CharField(
|
||||||
|
label=_("VRN"),
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
"class": "form-control",
|
"class": "form-control form-control-sm",
|
||||||
"placeholder": _("VAT Registration Number"),
|
"placeholder": _("VAT Registration Number"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
"maxlength": "15",
|
"maxlength": "15",
|
||||||
@ -549,9 +564,10 @@ class WizardForm3(forms.Form):
|
|||||||
)
|
)
|
||||||
|
|
||||||
address = forms.CharField(
|
address = forms.CharField(
|
||||||
|
label=_("Address"),
|
||||||
widget=forms.Textarea(
|
widget=forms.Textarea(
|
||||||
attrs={
|
attrs={
|
||||||
"class": "form-control",
|
"class": "form-control form-control-sm",
|
||||||
"rows": "3",
|
"rows": "3",
|
||||||
"required": "required",
|
"required": "required",
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ urlpatterns = [
|
|||||||
# ),
|
# ),
|
||||||
# path('signup/', allauth_views.SignupView.as_view(template_name='account/signup.html'), name='account_signup'),
|
# path('signup/', allauth_views.SignupView.as_view(template_name='account/signup.html'), name='account_signup'),
|
||||||
path("signup/", views.dealer_signup, name="account_signup"),
|
path("signup/", views.dealer_signup, name="account_signup"),
|
||||||
path("otp", views.OTPView.as_view(), name="otp"),
|
# path("otp", views.OTPView.as_view(), name="otp"),
|
||||||
# path(
|
# path(
|
||||||
# "password/change/", allauth_views.PasswordChangeView.as_view(template_name="account/password_change.html"), name="account_change_password",
|
# "password/change/", allauth_views.PasswordChangeView.as_view(template_name="account/password_change.html"), name="account_change_password",
|
||||||
# ),
|
# ),
|
||||||
|
|||||||
14
inventory/utilities/sa.py
Normal file
14
inventory/utilities/sa.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
from plans.taxation import TaxationPolicy
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
class SaudiTaxationPolicy(TaxationPolicy):
|
||||||
|
def get_default_tax(self):
|
||||||
|
return getattr(settings, 'PLANS_TAX', None)
|
||||||
|
|
||||||
|
def get_issuer_country_code(self):
|
||||||
|
return getattr(settings, 'PLANS_TAX_COUNTRY', None)
|
||||||
|
|
||||||
|
def get_tax_rate(self, tax_id, country_code, request=None):
|
||||||
|
|
||||||
|
return 0, True
|
||||||
@ -26,6 +26,7 @@ from django_ledger.models import (
|
|||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_jwt_token():
|
def get_jwt_token():
|
||||||
url = "https://carapi.app/api/auth/login"
|
url = "https://carapi.app/api/auth/login"
|
||||||
headers = {
|
headers = {
|
||||||
@ -668,4 +669,8 @@ class CarFinanceCalculator:
|
|||||||
"grand_total": totals['grand_total'],
|
"grand_total": totals['grand_total'],
|
||||||
"additionals": self.additional_services,
|
"additionals": self.additional_services,
|
||||||
"vat": self.vat_rate,
|
"vat": self.vat_rate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -73,9 +73,9 @@ from django.urls import reverse, reverse_lazy
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.db.models import Sum, F, Count
|
from django.db.models import Sum, F, Count
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from two_factor.utils import default_device
|
# from two_factor.utils import default_device
|
||||||
|
|
||||||
from two_factor.views import OTPRequiredMixin
|
# from two_factor.views import OTPRequiredMixin
|
||||||
|
|
||||||
from .forms import VendorForm
|
from .forms import VendorForm
|
||||||
from .services import (
|
from .services import (
|
||||||
@ -102,15 +102,13 @@ from .utils import (
|
|||||||
transfer_car,
|
transfer_car,
|
||||||
)
|
)
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from allauth.account import views as allauth_views
|
|
||||||
from django.db.models import Count, F, Value
|
from django.db.models import Count, F, Value
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from pyzbar.pyzbar import decode
|
from pyzbar.pyzbar import decode
|
||||||
from django.core.files.storage import default_storage
|
from django.core.files.storage import default_storage
|
||||||
|
from plans.models import Plan,PlanPricing
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
@ -152,6 +150,7 @@ def switch_language(request):
|
|||||||
return redirect("/")
|
return redirect("/")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def dealer_signup(request, *args, **kwargs):
|
def dealer_signup(request, *args, **kwargs):
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
@ -213,31 +212,29 @@ def dealer_signup(request, *args, **kwargs):
|
|||||||
# class Login(allauth_views.LoginView):
|
# class Login(allauth_views.LoginView):
|
||||||
# template_name = "account/login.html"
|
# template_name = "account/login.html"
|
||||||
# redirect_authenticated_user = True
|
# redirect_authenticated_user = True
|
||||||
class OTPView(View, LoginRequiredMixin):
|
# class OTPView(View, LoginRequiredMixin):
|
||||||
template_name = "account/otp_verification.html"
|
# template_name = "account/otp_verification.html"
|
||||||
|
#
|
||||||
def get(self, request, *args, **kwargs):
|
# def get(self, request, *args, **kwargs):
|
||||||
# device = default_device(request.user)
|
# # device = default_device(request.user)
|
||||||
# device.generate_challenge()
|
# EmailDevice.generate_challenge(self)
|
||||||
return render(request, self.template_name)
|
# return render(request, self.template_name)
|
||||||
|
#
|
||||||
def post(self, request, *args, **kwargs):
|
# def post(self, request, *args, **kwargs):
|
||||||
otp_code = request.POST.get("otp_code")
|
# otp_code = request.POST.get("otp_code")
|
||||||
|
#
|
||||||
if self.verify_otp(otp_code, request.user):
|
# if self.verify_otp(otp_code, request.user):
|
||||||
messages.success(request, _("OTP verified successfully!"))
|
# messages.success(request, _("OTP verified successfully!"))
|
||||||
return redirect("home")
|
# return redirect("home")
|
||||||
|
#
|
||||||
messages.error(request, _("Invalid OTP. Please try again."))
|
# messages.error(request, _("Invalid OTP. Please try again."))
|
||||||
return render(request, self.template_name)
|
# return render(request, self.template_name)
|
||||||
|
#
|
||||||
def verify_otp(self, otp_code, user):
|
# def verify_otp(self, otp_code, user):
|
||||||
device = default_device(user)
|
# device = default_device(user)
|
||||||
if device and device.verify_token(otp_code):
|
# if device and device.verify_token(otp_code):
|
||||||
return True
|
# return True
|
||||||
return False
|
# return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HomeView(TemplateView):
|
class HomeView(TemplateView):
|
||||||
@ -287,8 +284,8 @@ class AccountingDashboard(LoginRequiredMixin, TemplateView):
|
|||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if (
|
if (
|
||||||
# not any(hasattr(request.user, attr) for attr in ["dealer", "subdealer"])
|
# not any(hasattr(request.user, attr) for attr in ["dealer", "subdealer"])
|
||||||
not request.user.is_authenticated
|
not request.user.is_authenticated
|
||||||
):
|
):
|
||||||
# messages.error(request, _("You are not associated with any dealer."))
|
# messages.error(request, _("You are not associated with any dealer."))
|
||||||
return redirect("welcome")
|
return redirect("welcome")
|
||||||
@ -321,11 +318,20 @@ class AccountingDashboard(LoginRequiredMixin, TemplateView):
|
|||||||
class WelcomeView(TemplateView):
|
class WelcomeView(TemplateView):
|
||||||
template_name = "welcome.html"
|
template_name = "welcome.html"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
dealer = get_user_type(self.request)
|
||||||
|
plans = Plan.objects.all()
|
||||||
|
# pricing = PlanPricing.objects.filter(plan=plan).
|
||||||
|
context["plans"] = plans
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class CarCreateView(LoginRequiredMixin, CreateView):
|
class CarCreateView(LoginRequiredMixin, CreateView):
|
||||||
model = models.Car
|
model = models.Car
|
||||||
form_class = forms.CarForm
|
form_class = forms.CarForm
|
||||||
template_name = "inventory/car_form.html"
|
template_name = "inventory/car_form.html"
|
||||||
|
|
||||||
# success_url = reverse_lazy('inventory_stats')
|
# success_url = reverse_lazy('inventory_stats')
|
||||||
|
|
||||||
def get_form(self, form_class=None):
|
def get_form(self, form_class=None):
|
||||||
@ -660,11 +666,11 @@ def inventory_stats_view(request):
|
|||||||
|
|
||||||
trim = car.id_car_trim
|
trim = car.id_car_trim
|
||||||
if (
|
if (
|
||||||
trim
|
trim
|
||||||
and trim.id_car_trim
|
and trim.id_car_trim
|
||||||
not in inventory[make.id_car_make]["models"][model.id_car_model][
|
not in inventory[make.id_car_make]["models"][model.id_car_model][
|
||||||
"trims"
|
"trims"
|
||||||
]
|
]
|
||||||
):
|
):
|
||||||
inventory[make.id_car_make]["models"][model.id_car_model]["trims"][
|
inventory[make.id_car_make]["models"][model.id_car_model]["trims"][
|
||||||
trim.id_car_trim
|
trim.id_car_trim
|
||||||
@ -1077,7 +1083,7 @@ class CustomerListView(LoginRequiredMixin, ListView):
|
|||||||
query = self.request.GET.get("q")
|
query = self.request.GET.get("q")
|
||||||
dealer = get_user_type(self.request)
|
dealer = get_user_type(self.request)
|
||||||
|
|
||||||
customers = dealer.entity.get_customers().filter(active=True,additional_info__type="customer")
|
customers = dealer.entity.get_customers().filter(active=True, additional_info__type="customer")
|
||||||
|
|
||||||
if query:
|
if query:
|
||||||
customers = customers.filter(
|
customers = customers.filter(
|
||||||
@ -1156,11 +1162,11 @@ def CustomerCreateView(request):
|
|||||||
}
|
}
|
||||||
dealer = get_user_type(request)
|
dealer = get_user_type(request)
|
||||||
customer_name = (
|
customer_name = (
|
||||||
customer_dict["first_name"]
|
customer_dict["first_name"]
|
||||||
+ " "
|
+ " "
|
||||||
+ customer_dict["middle_name"]
|
+ customer_dict["middle_name"]
|
||||||
+ " "
|
+ " "
|
||||||
+ customer_dict["last_name"]
|
+ customer_dict["last_name"]
|
||||||
)
|
)
|
||||||
|
|
||||||
instance = dealer.entity.create_customer(
|
instance = dealer.entity.create_customer(
|
||||||
@ -1191,11 +1197,11 @@ def CustomerUpdateView(request, pk):
|
|||||||
}
|
}
|
||||||
dealer = get_user_type(request)
|
dealer = get_user_type(request)
|
||||||
customer_name = (
|
customer_name = (
|
||||||
customer_dict["first_name"]
|
customer_dict["first_name"]
|
||||||
+ " "
|
+ " "
|
||||||
+ customer_dict["middle_name"]
|
+ customer_dict["middle_name"]
|
||||||
+ " "
|
+ " "
|
||||||
+ customer_dict["last_name"]
|
+ customer_dict["last_name"]
|
||||||
)
|
)
|
||||||
|
|
||||||
instance = dealer.entity.get_customers().get(pk=pk)
|
instance = dealer.entity.get_customers().get(pk=pk)
|
||||||
@ -1209,8 +1215,9 @@ def CustomerUpdateView(request, pk):
|
|||||||
instance.save()
|
instance.save()
|
||||||
messages.success(request, _("Customer updated successfully."))
|
messages.success(request, _("Customer updated successfully."))
|
||||||
return redirect("customer_list")
|
return redirect("customer_list")
|
||||||
else:
|
else:
|
||||||
form = forms.CustomerForm(initial=customer.additional_info["customer_info"] if "customer_info" in customer.additional_info else {})
|
form = forms.CustomerForm(
|
||||||
|
initial=customer.additional_info["customer_info"] if "customer_info" in customer.additional_info else {})
|
||||||
return render(request, "customers/customer_form.html", {"form": form})
|
return render(request, "customers/customer_form.html", {"form": form})
|
||||||
|
|
||||||
|
|
||||||
@ -1422,80 +1429,80 @@ def delete_vendor(request, pk):
|
|||||||
# invoice_model.save()
|
# invoice_model.save()
|
||||||
# quotation.save()
|
# quotation.save()
|
||||||
|
|
||||||
# elif status == "approved":
|
# elif status == "approved":
|
||||||
# if qoutation.status == "Approved":
|
# if qoutation.status == "Approved":
|
||||||
# messages.error(request, "Quotation is already approved")
|
# messages.error(request, "Quotation is already approved")
|
||||||
# return redirect("quotation_detail", pk=pk)
|
# return redirect("quotation_detail", pk=pk)
|
||||||
|
|
||||||
# invoice_model = invoice_model.filter(date_in_review=qoutation.date_in_review).first()
|
# invoice_model = invoice_model.filter(date_in_review=qoutation.date_in_review).first()
|
||||||
# if not invoice_model.can_approve():
|
# if not invoice_model.can_approve():
|
||||||
# messages.error(request, "Quotation is not ready for approval")
|
# messages.error(request, "Quotation is not ready for approval")
|
||||||
# return redirect("quotation_detail", pk=pk)
|
# return redirect("quotation_detail", pk=pk)
|
||||||
|
|
||||||
# invoice_model.mark_as_approved(entity_slug=entity.slug, user_model=request.user.dealer.get_root_dealer.user)
|
# invoice_model.mark_as_approved(entity_slug=entity.slug, user_model=request.user.dealer.get_root_dealer.user)
|
||||||
# invoice_model.date_approved = date
|
# invoice_model.date_approved = date
|
||||||
# qoutation.date_approved = date
|
# qoutation.date_approved = date
|
||||||
# invoice_model.save()
|
# invoice_model.save()
|
||||||
# qoutation.status = "Approved"
|
# qoutation.status = "Approved"
|
||||||
# qoutation.save()
|
# qoutation.save()
|
||||||
# messages.success(request, _("Quotation Approved"))
|
# messages.success(request, _("Quotation Approved"))
|
||||||
# ledger = entity.create_ledger(
|
# ledger = entity.create_ledger(
|
||||||
# name=f"Payment Ledger for Invoice {invoice_model}",
|
# name=f"Payment Ledger for Invoice {invoice_model}",
|
||||||
# posted=True
|
# posted=True
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# entity_unit,created = EntityUnitModel.objects.get_or_create(
|
# entity_unit,created = EntityUnitModel.objects.get_or_create(
|
||||||
# name="Sales Department",
|
# name="Sales Department",
|
||||||
# entity=entity,
|
# entity=entity,
|
||||||
# document_prefix="SD"
|
# document_prefix="SD"
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# journal_entry = JournalEntryModel.objects.create(
|
# journal_entry = JournalEntryModel.objects.create(
|
||||||
# entity_unit=entity_unit,
|
# entity_unit=entity_unit,
|
||||||
# posted=False,
|
# posted=False,
|
||||||
# description=f"Payment for Invoice {invoice_model}",
|
# description=f"Payment for Invoice {invoice_model}",
|
||||||
# ledger=ledger,
|
# ledger=ledger,
|
||||||
# locked=False,
|
# locked=False,
|
||||||
# origin="Payment",
|
# origin="Payment",
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# accounts_receivable = coa_qs.first().get_coa_accounts().filter(name="Accounts Receivable").first()
|
# accounts_receivable = coa_qs.first().get_coa_accounts().filter(name="Accounts Receivable").first()
|
||||||
# if not accounts_receivable:
|
# if not accounts_receivable:
|
||||||
# accounts_receivable = entity.create_account(
|
# accounts_receivable = entity.create_account(
|
||||||
# code="AR",
|
# code="AR",
|
||||||
# role="asset",
|
# role="asset",
|
||||||
# name="Accounts Receivable",
|
# name="Accounts Receivable",
|
||||||
# coa_model=coa_qs.first(),
|
# coa_model=coa_qs.first(),
|
||||||
# balance_type="credit"
|
# balance_type="credit"
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# TransactionModel.objects.create(
|
# TransactionModel.objects.create(
|
||||||
# journal_entry=journal_entry,
|
# journal_entry=journal_entry,
|
||||||
# account=cash_account.first(), # Debit Cash
|
# account=cash_account.first(), # Debit Cash
|
||||||
# amount=invoice_model.amount_due, # Payment amount
|
# amount=invoice_model.amount_due, # Payment amount
|
||||||
# tx_type='debit',
|
# tx_type='debit',
|
||||||
# description="Payment Received",
|
# description="Payment Received",
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# TransactionModel.objects.create(
|
# TransactionModel.objects.create(
|
||||||
# journal_entry=journal_entry,
|
# journal_entry=journal_entry,
|
||||||
# account=accounts_receivable, # Credit Accounts Receivable
|
# account=accounts_receivable, # Credit Accounts Receivable
|
||||||
# amount=invoice_model.amount_due, # Payment amount
|
# amount=invoice_model.amount_due, # Payment amount
|
||||||
# tx_type='credit',
|
# tx_type='credit',
|
||||||
# description="Payment Received",
|
# description="Payment Received",
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# invoice_model.mark_as_review()
|
# invoice_model.mark_as_review()
|
||||||
# print("reviewed")
|
# print("reviewed")
|
||||||
# invoice_model.mark_as_approved(entity_slug=entity.slug, user_model=request.user.dealer.get_root_dealer.user)
|
# invoice_model.mark_as_approved(entity_slug=entity.slug, user_model=request.user.dealer.get_root_dealer.user)
|
||||||
# print("approved")
|
# print("approved")
|
||||||
# invoice_model.mark_as_paid(entity_slug=entity.slug, user_model=request.user.dealer.get_root_dealer.user)
|
# invoice_model.mark_as_paid(entity_slug=entity.slug, user_model=request.user.dealer.get_root_dealer.user)
|
||||||
# print("paid")
|
# print("paid")
|
||||||
# invoice_model.save()
|
# invoice_model.save()
|
||||||
# messages.success(request, "Invoice created")
|
# messages.success(request, "Invoice created")
|
||||||
# return redirect("quotation_detail", pk=pk)
|
# return redirect("quotation_detail", pk=pk)
|
||||||
|
|
||||||
# return redirect('django_ledger:invoice-detail', entity_slug=quotation.entity.slug, invoice_pk=invoice.uuid)
|
# return redirect('django_ledger:invoice-detail', entity_slug=quotation.entity.slug, invoice_pk=invoice.uuid)
|
||||||
|
|
||||||
|
|
||||||
# @login_required
|
# @login_required
|
||||||
@ -1527,45 +1534,45 @@ def delete_vendor(request, pk):
|
|||||||
# .first()
|
# .first()
|
||||||
# )
|
# )
|
||||||
# return
|
# return
|
||||||
# if not ledger:
|
# if not ledger:
|
||||||
# ledger = entity.create_ledger(name=f"Payment Ledger for Invoice {invoice_model}",posted=True)
|
# ledger = entity.create_ledger(name=f"Payment Ledger for Invoice {invoice_model}",posted=True)
|
||||||
|
|
||||||
# entity_unit,created = EntityUnitModel.objects.get_or_create(
|
# entity_unit,created = EntityUnitModel.objects.get_or_create(
|
||||||
# name="Sales Department",
|
# name="Sales Department",
|
||||||
# entity=entity,
|
# entity=entity,
|
||||||
# document_prefix="SD"
|
# document_prefix="SD"
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# journal_entry = JournalEntryModel.objects.create(
|
# journal_entry = JournalEntryModel.objects.create(
|
||||||
# entity_unit=entity_unit,
|
# entity_unit=entity_unit,
|
||||||
# posted=False,
|
# posted=False,
|
||||||
# description=f"Payment for Invoice {invoice_model}",
|
# description=f"Payment for Invoice {invoice_model}",
|
||||||
# ledger=ledger,
|
# ledger=ledger,
|
||||||
# locked=False,
|
# locked=False,
|
||||||
# origin="Payment",
|
# origin="Payment",
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# TransactionModel.objects.create(
|
# TransactionModel.objects.create(
|
||||||
# journal_entry=journal_entry,
|
# journal_entry=journal_entry,
|
||||||
# account=cash_account.first(), # Debit Cash
|
# account=cash_account.first(), # Debit Cash
|
||||||
# amount=invoice_model.amount_due, # Payment amount
|
# amount=invoice_model.amount_due, # Payment amount
|
||||||
# tx_type='debit',
|
# tx_type='debit',
|
||||||
# description="Payment Received",
|
# description="Payment Received",
|
||||||
# )
|
# )
|
||||||
|
|
||||||
# TransactionModel.objects.create(
|
# TransactionModel.objects.create(
|
||||||
# journal_entry=journal_entry,
|
# journal_entry=journal_entry,
|
||||||
# account=recivable_account.first(), # Credit Accounts Receivable
|
# account=recivable_account.first(), # Credit Accounts Receivable
|
||||||
# amount=invoice_model.amount_due, # Payment amount
|
# amount=invoice_model.amount_due, # Payment amount
|
||||||
# tx_type='credit',
|
# tx_type='credit',
|
||||||
# description="Payment Received",
|
# description="Payment Received",
|
||||||
# )
|
# )
|
||||||
# journal_entry.posted = True
|
# journal_entry.posted = True
|
||||||
# qoutation.posted = True
|
# qoutation.posted = True
|
||||||
# qoutation.save()
|
# qoutation.save()
|
||||||
# journal_entry.save()
|
# journal_entry.save()
|
||||||
# messages.success(request, "Invoice posted")
|
# messages.success(request, "Invoice posted")
|
||||||
# return redirect("quotation_detail", pk=pk)
|
# return redirect("quotation_detail", pk=pk)
|
||||||
|
|
||||||
|
|
||||||
# @login_required
|
# @login_required
|
||||||
@ -1754,7 +1761,7 @@ class OrganizationListView(LoginRequiredMixin, ListView):
|
|||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
dealer = get_user_type(self.request)
|
dealer = get_user_type(self.request)
|
||||||
return dealer.entity.get_customers().filter(additional_info__type="organization",active=True).all()
|
return dealer.entity.get_customers().filter(additional_info__type="organization", active=True).all()
|
||||||
|
|
||||||
|
|
||||||
class OrganizationDetailView(DetailView):
|
class OrganizationDetailView(DetailView):
|
||||||
@ -1766,16 +1773,16 @@ class OrganizationDetailView(DetailView):
|
|||||||
def OrganizationCreateView(request):
|
def OrganizationCreateView(request):
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = forms.OrganizationForm(request.POST)
|
form = forms.OrganizationForm(request.POST)
|
||||||
|
|
||||||
#upload logo
|
#upload logo
|
||||||
image = request.FILES.get('logo')
|
image = request.FILES.get('logo')
|
||||||
file_name = default_storage.save('images/{}'.format(image.name), image)
|
file_name = default_storage.save('images/{}'.format(image.name), image)
|
||||||
file_url = default_storage.url(file_name)
|
file_url = default_storage.url(file_name)
|
||||||
|
|
||||||
organization_dict = {
|
organization_dict = {
|
||||||
x: request.POST[x] for x in request.POST if x != "csrfmiddlewaretoken"
|
x: request.POST[x] for x in request.POST if x != "csrfmiddlewaretoken"
|
||||||
}
|
}
|
||||||
dealer = get_user_type(request)
|
dealer = get_user_type(request)
|
||||||
|
|
||||||
instance = dealer.entity.create_customer(
|
instance = dealer.entity.create_customer(
|
||||||
customer_model_kwargs={
|
customer_model_kwargs={
|
||||||
@ -1795,25 +1802,24 @@ def OrganizationCreateView(request):
|
|||||||
else:
|
else:
|
||||||
form = forms.OrganizationForm()
|
form = forms.OrganizationForm()
|
||||||
return render(request, "organizations/organization_form.html", {"form": form})
|
return render(request, "organizations/organization_form.html", {"form": form})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def OrganizationUpdateView(request,pk):
|
def OrganizationUpdateView(request, pk):
|
||||||
organization = get_object_or_404(CustomerModel, pk=pk)
|
organization = get_object_or_404(CustomerModel, pk=pk)
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = forms.OrganizationForm(request.POST)
|
form = forms.OrganizationForm(request.POST)
|
||||||
|
|
||||||
organization_dict = {
|
organization_dict = {
|
||||||
x: request.POST[x] for x in request.POST if x != "csrfmiddlewaretoken"
|
x: request.POST[x] for x in request.POST if x != "csrfmiddlewaretoken"
|
||||||
}
|
}
|
||||||
dealer = get_user_type(request)
|
dealer = get_user_type(request)
|
||||||
|
|
||||||
instance = dealer.entity.get_customers().get(pk=organization.additional_info['organization_info']['pk'])
|
instance = dealer.entity.get_customers().get(pk=organization.additional_info['organization_info']['pk'])
|
||||||
instance.customer_name = organization_dict["name"]
|
instance.customer_name = organization_dict["name"]
|
||||||
instance.address_1 = organization_dict["address"]
|
instance.address_1 = organization_dict["address"]
|
||||||
instance.phone = organization_dict["phone_number"]
|
instance.phone = organization_dict["phone_number"]
|
||||||
instance.email = organization_dict["email"]
|
instance.email = organization_dict["email"]
|
||||||
|
|
||||||
organization_dict["logo"] = organization.additional_info['organization_info']['logo']
|
organization_dict["logo"] = organization.additional_info['organization_info']['logo']
|
||||||
organization_dict["pk"] = str(instance.pk)
|
organization_dict["pk"] = str(instance.pk)
|
||||||
instance.additional_info["organization_info"] = organization_dict
|
instance.additional_info["organization_info"] = organization_dict
|
||||||
@ -1825,7 +1831,7 @@ def OrganizationUpdateView(request,pk):
|
|||||||
form = forms.OrganizationForm(initial=organization.additional_info["organization_info"] or {})
|
form = forms.OrganizationForm(initial=organization.additional_info["organization_info"] or {})
|
||||||
form.fields.pop('logo', None)
|
form.fields.pop('logo', None)
|
||||||
return render(request, "organizations/organization_form.html", {"form": form})
|
return render(request, "organizations/organization_form.html", {"form": form})
|
||||||
|
|
||||||
|
|
||||||
class OrganizationDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
|
class OrganizationDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
|
||||||
model = models.Organization
|
model = models.Organization
|
||||||
@ -2333,7 +2339,7 @@ def create_estimate(request):
|
|||||||
"unit_cost": car_instance.finances.selling_price,
|
"unit_cost": car_instance.finances.selling_price,
|
||||||
"unit_revenue": car_instance.finances.selling_price,
|
"unit_revenue": car_instance.finances.selling_price,
|
||||||
"total_amount": (car_instance.finances.total_vat)
|
"total_amount": (car_instance.finances.total_vat)
|
||||||
* int(item.get("quantity")),
|
* int(item.get("quantity")),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -2401,7 +2407,7 @@ def create_estimate(request):
|
|||||||
for x in car_list
|
for x in car_list
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, "sales/estimates/estimate_form.html", context)
|
return render(request, "sales/estimates/estimate_form.html", context)
|
||||||
|
|
||||||
|
|
||||||
@ -2412,9 +2418,9 @@ class EstimateDetailView(LoginRequiredMixin, DetailView):
|
|||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
estimate = kwargs.get("object")
|
estimate = kwargs.get("object")
|
||||||
if estimate.get_itemtxs_data():
|
if estimate.get_itemtxs_data():
|
||||||
calculator = CarFinanceCalculator(estimate)
|
calculator = CarFinanceCalculator(estimate)
|
||||||
finance_data = calculator.get_finance_data()
|
finance_data = calculator.get_finance_data()
|
||||||
kwargs['data'] = finance_data
|
kwargs['data'] = finance_data
|
||||||
print(finance_data)
|
print(finance_data)
|
||||||
kwargs["invoice"] = (
|
kwargs["invoice"] = (
|
||||||
@ -2436,7 +2442,7 @@ def create_sale_order(request, pk):
|
|||||||
estimate.save()
|
estimate.save()
|
||||||
messages.success(request, "Sale Order created successfully")
|
messages.success(request, "Sale Order created successfully")
|
||||||
return redirect("estimate_detail", pk=pk)
|
return redirect("estimate_detail", pk=pk)
|
||||||
|
|
||||||
form = forms.SaleOrderForm()
|
form = forms.SaleOrderForm()
|
||||||
form.fields["estimate"].queryset = EstimateModel.objects.filter(pk=pk)
|
form.fields["estimate"].queryset = EstimateModel.objects.filter(pk=pk)
|
||||||
form.initial['estimate'] = estimate
|
form.initial['estimate'] = estimate
|
||||||
@ -2446,13 +2452,16 @@ def create_sale_order(request, pk):
|
|||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"sales/estimates/sale_order_form.html",
|
"sales/estimates/sale_order_form.html",
|
||||||
{"form": form, "estimate": estimate, "items": items,"data": finance_data},
|
{"form": form, "estimate": estimate, "items": items, "data": finance_data},
|
||||||
)
|
)
|
||||||
|
|
||||||
def preview_sale_order(request,pk):
|
|
||||||
estimate = get_object_or_404(EstimateModel,pk=pk)
|
def preview_sale_order(request, pk):
|
||||||
|
estimate = get_object_or_404(EstimateModel, pk=pk)
|
||||||
data = get_car_finance_data(estimate)
|
data = get_car_finance_data(estimate)
|
||||||
return render(request,'sales/estimates/sale_order_preview.html',{'order':estimate.sale_orders.first(),"data":data,"estimate":estimate})
|
return render(request, 'sales/estimates/sale_order_preview.html',
|
||||||
|
{'order': estimate.sale_orders.first(), "data": data, "estimate": estimate})
|
||||||
|
|
||||||
|
|
||||||
class PaymentRequest(LoginRequiredMixin, DetailView):
|
class PaymentRequest(LoginRequiredMixin, DetailView):
|
||||||
model = EstimateModel
|
model = EstimateModel
|
||||||
@ -2542,10 +2551,10 @@ class InvoiceDetailView(LoginRequiredMixin, DetailView):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
invoice = kwargs.get("object")
|
invoice = kwargs.get("object")
|
||||||
|
|
||||||
if invoice.get_itemtxs_data():
|
if invoice.get_itemtxs_data():
|
||||||
calculator = CarFinanceCalculator(invoice)
|
calculator = CarFinanceCalculator(invoice)
|
||||||
finance_data = calculator.get_finance_data()
|
finance_data = calculator.get_finance_data()
|
||||||
print((finance_data["total_vat_amount"]+finance_data["total_price"]) == finance_data["grand_total"])
|
print((finance_data["total_vat_amount"] + finance_data["total_price"]) == finance_data["grand_total"])
|
||||||
kwargs["data"] = finance_data
|
kwargs["data"] = finance_data
|
||||||
kwargs["payments"] = JournalEntryModel.objects.filter(
|
kwargs["payments"] = JournalEntryModel.objects.filter(
|
||||||
ledger=invoice.ledger
|
ledger=invoice.ledger
|
||||||
@ -2649,8 +2658,8 @@ def invoice_create(request, pk):
|
|||||||
# unit_items = estimate.get_itemtxs_data()[0]
|
# unit_items = estimate.get_itemtxs_data()[0]
|
||||||
# vat = models.VatRate.objects.filter(is_active=True).first()
|
# vat = models.VatRate.objects.filter(is_active=True).first()
|
||||||
calculator = CarFinanceCalculator(estimate)
|
calculator = CarFinanceCalculator(estimate)
|
||||||
finance_data = calculator.get_finance_data()
|
finance_data = calculator.get_finance_data()
|
||||||
|
|
||||||
# total = 0
|
# total = 0
|
||||||
# discount_amount = 0
|
# discount_amount = 0
|
||||||
|
|
||||||
@ -3175,14 +3184,14 @@ class BillDetailView(LoginRequiredMixin, DetailView):
|
|||||||
bill = kwargs.get("object")
|
bill = kwargs.get("object")
|
||||||
if bill.get_itemtxs_data():
|
if bill.get_itemtxs_data():
|
||||||
txs = bill.get_itemtxs_data()[0]
|
txs = bill.get_itemtxs_data()[0]
|
||||||
|
|
||||||
car_and_item_info = [
|
car_and_item_info = [
|
||||||
{
|
{
|
||||||
"car": models.Car.objects.get(vin=x.item_model.name),
|
"car": models.Car.objects.get(vin=x.item_model.name),
|
||||||
"total": models.Car.objects.get(
|
"total": models.Car.objects.get(
|
||||||
vin=x.item_model.name
|
vin=x.item_model.name
|
||||||
).finances.cost_price
|
).finances.cost_price
|
||||||
* Decimal(x.quantity),
|
* Decimal(x.quantity),
|
||||||
"itemmodel": x,
|
"itemmodel": x,
|
||||||
}
|
}
|
||||||
for x in txs
|
for x in txs
|
||||||
@ -3196,7 +3205,6 @@ class BillDetailView(LoginRequiredMixin, DetailView):
|
|||||||
)
|
)
|
||||||
vat = models.VatRate.objects.filter(is_active=True).first()
|
vat = models.VatRate.objects.filter(is_active=True).first()
|
||||||
if vat:
|
if vat:
|
||||||
|
|
||||||
grand_total += round(Decimal(grand_total) * Decimal(vat.rate), 2)
|
grand_total += round(Decimal(grand_total) * Decimal(vat.rate), 2)
|
||||||
kwargs["car_and_item_info"] = car_and_item_info
|
kwargs["car_and_item_info"] = car_and_item_info
|
||||||
kwargs["grand_total"] = grand_total
|
kwargs["grand_total"] = grand_total
|
||||||
@ -3422,7 +3430,7 @@ def bill_create(request):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
car_list = models.Car.objects.filter(
|
car_list = models.Car.objects.filter(
|
||||||
dealer=dealer, finances__selling_price__gt=0,status="available"
|
dealer=dealer, finances__selling_price__gt=0, status="available"
|
||||||
)
|
)
|
||||||
context = {
|
context = {
|
||||||
"form": form,
|
"form": form,
|
||||||
@ -3458,7 +3466,7 @@ class OrderListView(ListView):
|
|||||||
model = models.SaleOrder
|
model = models.SaleOrder
|
||||||
template_name = "sales/orders/order_list.html"
|
template_name = "sales/orders/order_list.html"
|
||||||
context_object_name = "orders"
|
context_object_name = "orders"
|
||||||
|
|
||||||
|
|
||||||
# email
|
# email
|
||||||
def send_email_view(request, pk):
|
def send_email_view(request, pk):
|
||||||
@ -3530,11 +3538,11 @@ def custom_bad_request_view(request, exception=None):
|
|||||||
return render(request, "errors/400.html", {})
|
return render(request, "errors/400.html", {})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# from django_ledger.io.io_core import get_localdate
|
# from django_ledger.io.io_core import get_localdate
|
||||||
# from django_ledger.views.mixins import (DjangoLedgerSecurityMixIn)
|
# from django_ledger.views.mixins import (DjangoLedgerSecurityMixIn)
|
||||||
# from django.views.generic import RedirectView
|
# from django.views.generic import RedirectView
|
||||||
from django_ledger.views.financial_statement import FiscalYearBalanceSheetView,BaseIncomeStatementRedirectView,FiscalYearIncomeStatementView
|
from django_ledger.views.financial_statement import FiscalYearBalanceSheetView, BaseIncomeStatementRedirectView, \
|
||||||
|
FiscalYearIncomeStatementView
|
||||||
from django.views.generic import DetailView, RedirectView
|
from django.views.generic import DetailView, RedirectView
|
||||||
|
|
||||||
from django_ledger.io.io_core import get_localdate
|
from django_ledger.io.io_core import get_localdate
|
||||||
@ -3544,6 +3552,8 @@ from django_ledger.views.mixins import (
|
|||||||
MonthlyReportMixIn, DateReportMixIn, DjangoLedgerSecurityMixIn, EntityUnitMixIn,
|
MonthlyReportMixIn, DateReportMixIn, DjangoLedgerSecurityMixIn, EntityUnitMixIn,
|
||||||
BaseDateNavigationUrlMixIn, PDFReportMixIn
|
BaseDateNavigationUrlMixIn, PDFReportMixIn
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# BALANCE SHEET -----------
|
# BALANCE SHEET -----------
|
||||||
|
|
||||||
class BaseBalanceSheetRedirectView(DjangoLedgerSecurityMixIn, RedirectView):
|
class BaseBalanceSheetRedirectView(DjangoLedgerSecurityMixIn, RedirectView):
|
||||||
@ -3555,14 +3565,18 @@ class BaseBalanceSheetRedirectView(DjangoLedgerSecurityMixIn, RedirectView):
|
|||||||
'entity_slug': self.kwargs['entity_slug'],
|
'entity_slug': self.kwargs['entity_slug'],
|
||||||
'year': year
|
'year': year
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class FiscalYearBalanceSheetViewBase(FiscalYearBalanceSheetView):
|
class FiscalYearBalanceSheetViewBase(FiscalYearBalanceSheetView):
|
||||||
template_name = "ledger/reports/balance_sheet.html"
|
template_name = "ledger/reports/balance_sheet.html"
|
||||||
|
|
||||||
|
|
||||||
class QuarterlyBalanceSheetView(FiscalYearBalanceSheetViewBase, QuarterlyReportMixIn):
|
class QuarterlyBalanceSheetView(FiscalYearBalanceSheetViewBase, QuarterlyReportMixIn):
|
||||||
"""
|
"""
|
||||||
Quarter Balance Sheet View.
|
Quarter Balance Sheet View.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class MonthlyBalanceSheetView(FiscalYearBalanceSheetViewBase, MonthlyReportMixIn):
|
class MonthlyBalanceSheetView(FiscalYearBalanceSheetViewBase, MonthlyReportMixIn):
|
||||||
"""
|
"""
|
||||||
Monthly Balance Sheet View.
|
Monthly Balance Sheet View.
|
||||||
@ -3574,6 +3588,7 @@ class DateBalanceSheetView(FiscalYearBalanceSheetViewBase, DateReportMixIn):
|
|||||||
Date Balance Sheet View.
|
Date Balance Sheet View.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class BaseIncomeStatementRedirectViewBase(BaseIncomeStatementRedirectView):
|
class BaseIncomeStatementRedirectViewBase(BaseIncomeStatementRedirectView):
|
||||||
|
|
||||||
def get_redirect_url(self, *args, **kwargs):
|
def get_redirect_url(self, *args, **kwargs):
|
||||||
@ -3585,9 +3600,11 @@ class BaseIncomeStatementRedirectViewBase(BaseIncomeStatementRedirectView):
|
|||||||
'year': year
|
'year': year
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class FiscalYearIncomeStatementViewBase(FiscalYearIncomeStatementView):
|
class FiscalYearIncomeStatementViewBase(FiscalYearIncomeStatementView):
|
||||||
template_name = "ledger/reports/income_statement.html"
|
template_name = "ledger/reports/income_statement.html"
|
||||||
|
|
||||||
|
|
||||||
class QuarterlyIncomeStatementView(FiscalYearIncomeStatementView, QuarterlyReportMixIn):
|
class QuarterlyIncomeStatementView(FiscalYearIncomeStatementView, QuarterlyReportMixIn):
|
||||||
"""
|
"""
|
||||||
Quarter Income Statement View.
|
Quarter Income Statement View.
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -57,7 +57,6 @@ django-next-url-mixin==0.4.0
|
|||||||
django-nine==0.2.7
|
django-nine==0.2.7
|
||||||
django-nonefield==0.4
|
django-nonefield==0.4
|
||||||
django-ordered-model==3.7.4
|
django-ordered-model==3.7.4
|
||||||
django-otp==1.5.4
|
|
||||||
django-phonenumber-field==8.0.0
|
django-phonenumber-field==8.0.0
|
||||||
django-picklefield==3.2
|
django-picklefield==3.2
|
||||||
django-plans==1.2.0
|
django-plans==1.2.0
|
||||||
@ -70,7 +69,6 @@ django-sms==0.7.0
|
|||||||
django-sslserver==0.22
|
django-sslserver==0.22
|
||||||
django-tables2==2.7.5
|
django-tables2==2.7.5
|
||||||
django-treebeard==4.7.1
|
django-treebeard==4.7.1
|
||||||
django-two-factor-auth==1.17.0
|
|
||||||
django-view-breadcrumbs==2.5.1
|
django-view-breadcrumbs==2.5.1
|
||||||
djangocms-admin-style==3.3.1
|
djangocms-admin-style==3.3.1
|
||||||
djangorestframework==3.15.2
|
djangorestframework==3.15.2
|
||||||
|
|||||||
BIN
static/.DS_Store
vendored
BIN
static/.DS_Store
vendored
Binary file not shown.
BIN
static/images/.DS_Store
vendored
BIN
static/images/.DS_Store
vendored
Binary file not shown.
BIN
static/images/icons/.DS_Store
vendored
Normal file
BIN
static/images/icons/.DS_Store
vendored
Normal file
Binary file not shown.
55
static/images/icons/114292_report.svg
Normal file
55
static/images/icons/114292_report.svg
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 490 490" style="enable-background:new 0 0 490 490;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M480,325h-5V45c0-5.523-4.477-10-10-10H300V10c0-5.523-4.477-10-10-10h-90c-5.523,0-10,4.477-10,10v25H25
|
||||||
|
c-5.523,0-10,4.477-10,10v280h-5c-5.523,0-10,4.477-10,10v35c0,5.523,4.477,10,10,10h152.338l-50.913,84.855l17.149,10.29
|
||||||
|
L185.662,380H235v110h20V380h49.338l57.087,95.145l17.149-10.29L327.662,380H480c5.523,0,10-4.477,10-10v-35
|
||||||
|
C490,329.477,485.523,325,480,325z M210,20h70v15h-70V20z M35,55h420v270H35V55z M470,360H20v-15h450V360z"/>
|
||||||
|
<path d="M170,90c-55.14,0-100,44.86-100,100s44.86,100,100,100s100-44.86,100-100S225.14,90,170,90z M170,270
|
||||||
|
c-44.112,0-80-35.888-80-80c0-40.724,30.593-74.413,70-79.353V190c0,5.523,4.477,10,10,10h79.353
|
||||||
|
C244.413,239.407,210.724,270,170,270z M180,180v-69.353c36.128,4.529,64.824,33.225,69.353,69.353H180z"/>
|
||||||
|
<rect x="345" y="130" width="70" height="20"/>
|
||||||
|
<rect x="345" y="160" width="70" height="20"/>
|
||||||
|
<rect x="345" y="190" width="70" height="20"/>
|
||||||
|
<rect x="345" y="100" width="45" height="20"/>
|
||||||
|
<path d="M324.999,119.999v-20h-45c-2.652,0-5.196,1.054-7.071,2.929l-15,15l14.143,14.143l12.07-12.072H324.999z"/>
|
||||||
|
<rect x="310" y="235" width="115" height="20"/>
|
||||||
|
<rect x="280" y="270" width="145" height="20"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
63
static/images/icons/148542_list.svg
Normal file
63
static/images/icons/148542_list.svg
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 484.507 484.507" style="enable-background:new 0 0 484.507 484.507;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M432.503,237.194h-44.357V10c0-5.522-4.478-10-10-10H52.003c-5.523,0-10,4.478-10,10v464.507c0,5.522,4.477,10,10,10
|
||||||
|
h375.559c8.937,0,14.941-7.99,14.941-19.884V247.194C442.503,241.672,438.026,237.194,432.503,237.194z M368.146,464.507H62.003
|
||||||
|
V20h306.143V464.507z M422.503,464.507h-34.357V257.194h34.357V464.507z"/>
|
||||||
|
<rect x="86.594" y="39.532" width="59.299" height="20"/>
|
||||||
|
<rect x="86.594" y="79.064" width="118.598" height="20"/>
|
||||||
|
<rect x="294.141" y="39.532" width="19.766" height="20"/>
|
||||||
|
<rect x="323.791" y="39.532" width="19.766" height="20"/>
|
||||||
|
<path d="M111.305,202.838c2.369,0,4.742-0.837,6.641-2.527l44.474-39.532l-13.287-14.947L111.706,179.1L98.607,166
|
||||||
|
l-14.142,14.142l19.766,19.767C106.178,201.856,108.738,202.838,111.305,202.838z"/>
|
||||||
|
<rect x="180.485" y="182.838" width="168.013" height="20"/>
|
||||||
|
<rect x="180.485" y="153.188" width="24.708" height="20"/>
|
||||||
|
<rect x="220.018" y="153.188" width="24.708" height="20"/>
|
||||||
|
<path d="M111.305,301.669c2.369,0,4.742-0.837,6.642-2.528l44.474-39.532l-13.287-14.947l-37.426,33.268l-13.099-13.1
|
||||||
|
l-14.143,14.143l19.766,19.767C106.178,300.687,108.738,301.669,111.305,301.669z"/>
|
||||||
|
<rect x="180.485" y="281.669" width="168.013" height="20"/>
|
||||||
|
<rect x="180.485" y="252.02" width="24.708" height="20"/>
|
||||||
|
<rect x="220.018" y="252.02" width="24.708" height="20"/>
|
||||||
|
<path d="M111.305,400.5c2.369,0,4.742-0.837,6.642-2.528l44.474-39.532l-13.287-14.947l-37.426,33.268l-13.099-13.1
|
||||||
|
l-14.143,14.143l19.766,19.767C106.178,399.518,108.738,400.5,111.305,400.5z"/>
|
||||||
|
<rect x="180.485" y="380.5" width="168.013" height="20"/>
|
||||||
|
<rect x="180.485" y="350.851" width="24.708" height="20"/>
|
||||||
|
<rect x="220.018" y="350.851" width="24.708" height="20"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
58
static/images/icons/2281_financial-app.svg
Normal file
58
static/images/icons/2281_financial-app.svg
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="45.451px" height="45.451px" viewBox="0 0 45.451 45.451" style="enable-background:new 0 0 45.451 45.451;"
|
||||||
|
xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M27.828,28.41c-1.102-1.004-1.985-2.243-2.571-3.639H6.723c-1.265,0-2.248-1.021-2.248-2.287V6.4
|
||||||
|
c0-1.266,0.983-2.308,2.248-2.308H32.41c1.267,0,2.33,1.042,2.33,2.308v4.054c0.015,0,0.025,0,0.039,0
|
||||||
|
c1.396,0,2.73,0.28,3.947,0.785V6.4c0-3.514-2.804-6.4-6.316-6.4H6.723C3.209,0,0.381,2.887,0.381,6.4v16.086
|
||||||
|
c0,3.513,2.829,6.379,6.342,6.379h3.81c0.221,1.832,1.824,3.34,3.773,3.34h9.508c0.118-0.17,0.239-0.338,0.365-0.502
|
||||||
|
C25.199,30.369,26.438,29.259,27.828,28.41z"/>
|
||||||
|
<path d="M19.5,22.974c0.565,0,1.023-0.459,1.023-1.024v-1.109c2.369-0.418,3.715-2.007,3.715-3.869
|
||||||
|
c0-1.881-1.013-3.031-3.499-3.91c-1.777-0.668-2.51-1.107-2.51-1.798c0-0.585,0.439-1.171,1.799-1.171
|
||||||
|
c0.791,0,1.432,0.133,1.94,0.292c0.284,0.089,0.592,0.057,0.852-0.087c0.26-0.144,0.448-0.389,0.521-0.676l0.064-0.249
|
||||||
|
c0.146-0.566-0.178-1.146-0.738-1.309c-0.551-0.159-1.176-0.276-2.037-0.313V6.936c0-0.565-0.458-1.024-1.023-1.024
|
||||||
|
c-0.565,0-1.024,0.458-1.024,1.024v0.962c-2.261,0.438-3.543,1.882-3.543,3.722c0,2.028,1.522,3.073,3.759,3.826
|
||||||
|
c1.55,0.524,2.215,1.025,2.215,1.819c0,0.837-0.816,1.296-2.009,1.296c-0.862,0-1.673-0.176-2.375-0.428
|
||||||
|
c-0.287-0.102-0.604-0.081-0.873,0.062c-0.271,0.143-0.467,0.392-0.543,0.688l-0.082,0.324c-0.142,0.544,0.169,1.105,0.701,1.291
|
||||||
|
c0.75,0.26,1.675,0.447,2.643,0.49v0.962C18.476,22.515,18.934,22.974,19.5,22.974z"/>
|
||||||
|
<path d="M44.984,38.447c-0.755-5.635-5.931-9.594-11.565-8.842c-5.636,0.75-9.594,5.928-8.843,11.563l0.047,0.362
|
||||||
|
c0.298,2.234,2.205,3.92,4.459,3.92h11.396c2.255,0,4.162-1.686,4.46-3.92l0.047-0.354C45.095,40.311,45.103,39.355,44.984,38.447
|
||||||
|
z"/>
|
||||||
|
<circle cx="34.779" cy="20.781" r="7.276"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
49
static/images/icons/35420_store.svg
Normal file
49
static/images/icons/35420_store.svg
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 490 490" style="enable-background:new 0 0 490 490;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M75,250c-5.523,0-10,4.478-10,10v150c0,5.522,4.477,10,10,10h190c5.522,0,10-4.478,10-10V260c0-5.522-4.478-10-10-10H75z
|
||||||
|
M160,400H85v-55h75V400z M160,325H85v-55h75V325z M255,400h-75v-55h75V400z M255,325h-75v-55h75V325z"/>
|
||||||
|
<rect x="310" y="205" width="55" height="20"/>
|
||||||
|
<rect x="380" y="205" width="20" height="20"/>
|
||||||
|
<path d="M480,185c5.522,0,10-4.478,10-10V25c0-11.028-8.972-20-20-20H20C8.972,5,0,13.972,0,25v150c0,5.522,4.477,10,10,10h20
|
||||||
|
v280H0v20h490v-20h-30V185H480z M255,25h100v140H255V25z M135,25h100v140H135V25z M20,165V25h95v140H40H20z M405,460H305V270h40
|
||||||
|
v165h20V270h40V460z M440,465h-15V260c0-5.522-4.478-10-10-10H295c-5.522,0-10,4.478-10,10v205H50V225h220v-20H50v-20h390V465z
|
||||||
|
M375,165V25h95v140H375z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@ -1,79 +1,76 @@
|
|||||||
{% extends "account/base_manage_email.html" %}
|
{% extends "base.html" %}
|
||||||
{% load allauth i18n %}
|
{% load crispy_forms_filters %}
|
||||||
|
{% load allauth i18n static %}
|
||||||
{% block head_title %}
|
{% block head_title %}
|
||||||
{% trans "Email Addresses" %}
|
{% trans "Email Addresses" %}
|
||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% element h1 %}
|
<div class="row ">
|
||||||
{% trans "Email Addresses" %}
|
<div class="row flex-center min-vh-50">
|
||||||
{% endelement %}
|
<div class="col-sm-10 col-md-8 col-lg-5 col-xl-5 col-xxl-3">
|
||||||
|
<a class="d-flex flex-center text-decoration-none mb-4" href="{% url 'home' %}">
|
||||||
|
<div class="d-flex align-items-center fw-bolder fs-3 d-inline-block">
|
||||||
|
<div class="d-flex align-items-center fw-bolder fs-3 d-inline-block">
|
||||||
|
<img class="d-dark-none" src="{% static 'images/logos/logo-d.png' %}" alt="{% trans 'home' %}" width="58" />
|
||||||
|
<img class="d-light-none" src="{% static 'images/logos/logo.png' %}" alt="{% trans 'home' %}" width="58" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="text-center">
|
||||||
|
<h3 class="mb-4">{% trans "Email Addresses" %}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if emailaddresses %}
|
{% if emailaddresses %}
|
||||||
{% element p %}
|
<p>
|
||||||
{% trans 'The following email addresses are associated with your account:' %}
|
{% trans 'The following email addresses are associated with your account:' %}
|
||||||
{% endelement %}
|
</p>
|
||||||
{% url 'account_email' as email_url %}
|
{% url 'account_email' as email_url %}
|
||||||
{% element form form=form action=email_url method="post" tags="email,list" %}
|
<form action="{{ email_url }}" method="POST" class="form email list">
|
||||||
{% slot body %}
|
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
<div class="fs-9 fw-bold form-group mb-3 list-group">
|
||||||
{% for radio in emailaddress_radios %}
|
{% for radio in emailaddress_radios %}
|
||||||
{% with emailaddress=radio.emailaddress %}
|
{% with emailaddress=radio.emailaddress %}
|
||||||
{% element field type="radio" checked=radio.checked name="email" value=emailaddress.email id=radio.id %}
|
<label for="{{ radio.id }}">
|
||||||
{% slot label %}
|
<input type="radio" name="email" checked="{{ radio.checked }}" value="{{ emailaddress.email }}" id="{{ radio.id }}" class="form-check-input mb-3" />
|
||||||
{{ emailaddress.email }}
|
{{ emailaddress.email }}
|
||||||
{% if emailaddress.verified %}
|
{% if emailaddress.verified %}
|
||||||
{% element badge tags="success,email,verified" %}
|
<span class="badge badge-phoenix badge-phoenix-success verified">{% translate "Verified" %}</span>
|
||||||
{% translate "Verified" %}
|
|
||||||
{% endelement %}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
{% element badge tags="warning,email,unverified" %}
|
<span class="badge badge-phoenix badge-phoenix-warning unverified">{% translate "Unverified" %}</span>
|
||||||
{% translate "Unverified" %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if emailaddress.primary %}
|
{% if emailaddress.primary %}
|
||||||
{% element badge tags="email,primary" %}
|
<span class="badge badge-phoenix badge-phoenix-primary email">{% translate "Primary" %}</span>
|
||||||
{% translate "Primary" %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endslot %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
</label>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endslot %}
|
</div>
|
||||||
{% slot actions %}
|
<div class="mt-2 mb-6">
|
||||||
{% element button type="submit" name="action_primary" %}
|
<button type="submit" name="action_primary" class="btn btn-sm btn-primary">{% trans 'Make Primary' %}</button>
|
||||||
{% trans 'Make Primary' %}
|
<button type="submit" name="action_send" class="btn btn-sm btn-secondary">{% trans 'Re-send Verification' %}</button>
|
||||||
{% endelement %}
|
<button type="submit" name="action_remove" class="btn btn-sm btn-danger delete">{% trans 'Remove' %}</button>
|
||||||
{% element button tags="secondary" type="submit" name="action_send" %}
|
</div>
|
||||||
{% trans 'Re-send Verification' %}
|
|
||||||
{% endelement %}
|
|
||||||
{% element button tags="danger,delete" type="submit" name="action_remove" %}
|
</form>
|
||||||
{% trans 'Remove' %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endslot %}
|
|
||||||
{% endelement %}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
{% include "account/snippets/warn_no_email.html" %}
|
{% include "account/snippets/warn_no_email.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if can_add_email %}
|
{% if can_add_email %}
|
||||||
{% element h2 %}
|
<p class="fs-8 fw-bold text-start">
|
||||||
{% trans "Add Email Address" %}
|
{% trans "Add Email Address" %}
|
||||||
{% endelement %}
|
</p>
|
||||||
|
|
||||||
{% url 'account_email' as action_url %}
|
{% url 'account_email' as action_url %}
|
||||||
{% element form form=form method="post" action=action_url tags="email,add" %}
|
<form action="{{ action_url }}" method="POST" class="form email add">
|
||||||
{% slot body %}
|
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% element fields form=form %}
|
{{ form|crispy }}
|
||||||
{% endelement %}
|
<button class="btn btn-sn btn-success w-100" type="submit" name="action_add">
|
||||||
{% endslot %}
|
{% trans "Add Email" %}
|
||||||
{% slot actions %}
|
</button>
|
||||||
{% element button name="action_add" type="submit" %}
|
</form>
|
||||||
{% trans "Add Email" %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endslot %}
|
|
||||||
{% endelement %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock content %}
|
|
||||||
{% block extra_body %}
|
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
var message = "{% trans 'Do you really want to remove the selected email address?' %}";
|
var message = "{% trans 'Do you really want to remove the selected email address?' %}";
|
||||||
@ -87,4 +84,7 @@
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
{% endblock extra_body %}
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
|
|||||||
@ -1,39 +1,53 @@
|
|||||||
{% extends "account/base_entrance.html" %}
|
{% extends "base.html" %}
|
||||||
{% load i18n %}
|
{% load i18n static %}
|
||||||
{% load account %}
|
{% load account %}
|
||||||
{% load allauth %}
|
{% load allauth %}
|
||||||
{% block head_title %}
|
{% block head_title %}
|
||||||
{% trans "Confirm Email Address" %}
|
{% trans "Confirm Email Address" %}
|
||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% element h1 %}
|
<div class="row ">
|
||||||
{% trans "Confirm Email Address" %}
|
<div class="row flex-center min-vh-50">
|
||||||
{% endelement %}
|
<div class="col-sm-10 col-md-8 col-lg-5 col-xl-5 col-xxl-3">
|
||||||
|
<a class="d-flex flex-center text-decoration-none mb-4" href="{% url 'home' %}">
|
||||||
|
<div class="d-flex align-items-center fw-bolder fs-3 d-inline-block">
|
||||||
|
<div class="d-flex align-items-center fw-bolder fs-3 d-inline-block">
|
||||||
|
<img class="d-dark-none" src="{% static 'images/logos/logo-d.png' %}" alt="{% trans 'home' %}" width="58" />
|
||||||
|
<img class="d-light-none" src="{% static 'images/logos/logo.png' %}" alt="{% trans 'home' %}" width="58" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="text-center">
|
||||||
|
<h3 class="mb-4">{% trans "Confirm Email Address" %}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if confirmation %}
|
{% if confirmation %}
|
||||||
{% user_display confirmation.email_address.user as user_display %}
|
{% user_display confirmation.email_address.user as user_display %}
|
||||||
{% if can_confirm %}
|
{% if can_confirm %}
|
||||||
{% element p %}
|
<p>
|
||||||
{% blocktrans with confirmation.email_address.email as email %}Please confirm that <a href="mailto:{{ email }}">{{ email }}</a> is an email address for user {{ user_display }}.{% endblocktrans %}
|
{% blocktrans with confirmation.email_address.email as email %}Please confirm that <a href="mailto:{{ email }}">{{ email }}</a> is an email address for user {{ user_display }}.{% endblocktrans %}
|
||||||
{% endelement %}
|
</p>
|
||||||
{% url 'account_confirm_email' confirmation.key as action_url %}
|
{% url 'account_confirm_email' confirmation.key as action_url %}
|
||||||
{% element form method="post" action=action_url %}
|
<form class="form" action="{{ action_url }}" method="post">
|
||||||
{% slot actions %}
|
{% csrf_token %}
|
||||||
{% csrf_token %}
|
|
||||||
{{ redirect_field }}
|
{{ redirect_field }}
|
||||||
{% element button type="submit" %}
|
<button class="btn btn-sm btn-phoenix-primary" type="submit">
|
||||||
{% trans 'Confirm' %}
|
{% trans 'Confirm' %}
|
||||||
{% endelement %}
|
</button>
|
||||||
{% endslot %}
|
</form>
|
||||||
{% endelement %}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
{% element p %}
|
<p>
|
||||||
{% blocktrans %}Unable to confirm {{ email }} because it is already confirmed by a different account.{% endblocktrans %}
|
{% blocktrans %}Unable to confirm {{ email }} because it is already confirmed by a different account.{% endblocktrans %}
|
||||||
{% endelement %}
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% url 'account_email' as email_url %}
|
{% url 'account_email' as email_url %}
|
||||||
{% element p %}
|
<p>
|
||||||
{% blocktrans %}This email confirmation link expired or is invalid. Please <a href="{{ email_url }}">issue a new email confirmation request</a>.{% endblocktrans %}
|
{% blocktrans %}This email confirmation link expired or is invalid. Please <a href="{{ email_url }}">issue a new email confirmation request</a>.{% endblocktrans %}
|
||||||
{% endelement %}
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -19,9 +19,9 @@
|
|||||||
</a>
|
</a>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<h3 class="mb-4">{% trans "Sign In" %}</h3>
|
<h3 class="mb-4">{% trans "Sign In" %}</h3>
|
||||||
{% if not SOCIALACCOUNT_ONLY %}
|
{% if not SOCIALACCOUNT_ONLY %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<form method="post" action="{% url 'account_login' %}" class="form needs-validation" novalidate>
|
<form method="post" action="{% url 'account_login' %}" class="form needs-validation" novalidate>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="mb-3 text-start">
|
<div class="mb-3 text-start">
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
<Button class="btn btn-primary w-100 mb-5" type="submit">
|
<Button class="btn btn-primary w-100 mb-5" type="submit">
|
||||||
{{ _("Verify") }}
|
{{ _("Verify") }}
|
||||||
</Button>
|
</Button>
|
||||||
<a class="fs-9" href="">{{ _("Didn’t receive the code?") }}</a>
|
<a class="fs-9" href="">{{ _("Didn’t receive the code") }}</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -14,23 +14,23 @@
|
|||||||
</a>
|
</a>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<h3 class="text-body-highlight">{% trans 'Sign Up' %}</h3>
|
<h3 class="text-body-highlight">{% trans 'Sign Up' %}</h3>
|
||||||
<p class="text-body-tertiary">{% trans 'Create your account today' %}</p>
|
<p class="text-body-tertiary fs-9">{% trans 'Create your account today' %}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-start">
|
<div class="text-start">
|
||||||
<div class="card theme-wizard" data-theme-wizard="data-theme-wizard">
|
<div class="card theme-wizard" data-theme-wizard="data-theme-wizard">
|
||||||
<div class="card-header pt-3 pb-2 border-bottom-0">
|
<div class="card-header pt-3 pb-2 border-bottom-0">
|
||||||
<ul class="nav justify-content-between nav-wizard nav-wizard-success" role="tablist">
|
<ul class="nav justify-content-between nav-wizard nav-wizard-success" role="tablist">
|
||||||
<li class="nav-item" role="presentation"><a class="nav-link active fw-semibold" href="#bootstrap-wizard-validation-tab1" data-bs-toggle="tab" data-wizard-step="1" aria-selected="true" role="tab">
|
<li class="nav-item" role="presentation"><a class="nav-link active fw-semibold" href="#bootstrap-wizard-validation-tab1" data-bs-toggle="tab" data-wizard-step="1" aria-selected="true" role="tab">
|
||||||
<div class="text-center d-inline-block"><span class="nav-item-circle-parent"><span class="nav-item-circle"><svg class="svg-inline--fa fa-lock" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="lock" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg=""><path fill="currentColor" d="M144 144v48H304V144c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192V144C80 64.5 144.5 0 224 0s144 64.5 144 144v48h16c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V256c0-35.3 28.7-64 64-64H80z"></path></svg></span></span><span class="d-none d-md-block mt-1 fs-9">{% trans 'Access' %}</span></div>
|
<div class="text-center d-inline-block"><span class="nav-item-circle-parent"><span class="nav-item-circle"><span class="fa fa-lock"></span></span></span><span class="d-none d-md-block mt-1 fs-9">{% trans 'Access' %}</span></div>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li class="nav-item" role="presentation"><a class="nav-link fw-semibold" href="#bootstrap-wizard-validation-tab2" data-bs-toggle="tab" data-wizard-step="2" aria-selected="false" tabindex="-1" role="tab">
|
<li class="nav-item" role="presentation"><a class="nav-link fw-semibold" href="#bootstrap-wizard-validation-tab2" data-bs-toggle="tab" data-wizard-step="2" aria-selected="false" tabindex="-1" role="tab">
|
||||||
<div class="text-center d-inline-block"><span class="nav-item-circle-parent"><span class="nav-item-circle"><svg class="svg-inline--fa fa-user" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="user" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg=""><path fill="currentColor" d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z"></path></svg></span></span><span class="d-none d-md-block mt-1 fs-9">{% trans 'Account' %}</span></div>
|
<div class="text-center d-inline-block"><span class="nav-item-circle-parent"><span class="nav-item-circle"><span class="fa fa-user"></span></span></span><span class="d-none d-md-block mt-1 fs-9">{% trans 'Account' %}</span></div>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li class="nav-item" role="presentation"><a class="nav-link fw-semibold" href="#bootstrap-wizard-validation-tab3" data-bs-toggle="tab" data-wizard-step="3" aria-selected="false" tabindex="-1" role="tab">
|
<li class="nav-item" role="presentation"><a class="nav-link fw-semibold" href="#bootstrap-wizard-validation-tab3" data-bs-toggle="tab" data-wizard-step="3" aria-selected="false" tabindex="-1" role="tab">
|
||||||
<div class="text-center d-inline-block"><span class="nav-item-circle-parent"><span class="nav-item-circle"><svg class="svg-inline--fa fa-file-lines" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="file-lines" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" data-fa-i2svg=""><path fill="currentColor" d="M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM112 256H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z"></path></svg></span></span><span class="d-none d-md-block mt-1 fs-9">{% trans 'Extra' %}</span></div>
|
<div class="text-center d-inline-block"><span class="nav-item-circle-parent"><span class="nav-item-circle"><svg class="fa fa-file-lines"></svg></span></span><span class="d-none d-md-block mt-1 fs-9">{% trans 'Extra' %}</span></div>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li class="nav-item" role="presentation"><a class="nav-link fw-semibold" href="#bootstrap-wizard-validation-tab4" data-bs-toggle="tab" data-wizard-step="4" aria-selected="false" tabindex="-1" role="tab">
|
<li class="nav-item" role="presentation"><a class="nav-link fw-semibold" href="#bootstrap-wizard-validation-tab4" data-bs-toggle="tab" data-wizard-step="4" aria-selected="false" tabindex="-1" role="tab">
|
||||||
<div class="text-center d-inline-block"><span class="nav-item-circle-parent"><span class="nav-item-circle"><svg class="svg-inline--fa fa-check" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg=""><path fill="currentColor" d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"></path></svg></span></span><span class="d-none d-md-block mt-1 fs-9">{% trans 'Done' %}</span></div>
|
<div class="text-center d-inline-block"><span class="nav-item-circle-parent"><span class="nav-item-circle"><span class="fa fa-check"></span></span></span><span class="d-none d-md-block mt-1 fs-9">{% trans 'Done' %}</span></div>
|
||||||
</a></li>
|
</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,14 +1,29 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load i18n %}
|
{% load i18n static%}
|
||||||
{% load allauth %}
|
{% load allauth %}
|
||||||
{% block head_title %}
|
{% block head_title %}
|
||||||
{% trans "Verify Your Email Address" %}
|
{% trans "Verify Your Email Address" %}
|
||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% element h1 %}
|
<div class="row">
|
||||||
|
<div class="row flex-center min-vh-50 py-5">
|
||||||
|
<div class="col-sm-10 col-md-8 col-lg-5 col-xxl-4">
|
||||||
|
<a class="d-flex flex-center text-decoration-none mb-4" href="{% url 'home' %}">
|
||||||
|
<div class="d-flex align-items-center fw-bolder fs-3 d-inline-block">
|
||||||
|
<img class="d-dark-none" src="{% static 'images/logos/logo-d.png' %}" alt="{% trans 'home' %}" width="58" />
|
||||||
|
<img class="d-light-none" src="{% static 'images/logos/logo.png' %}" alt="{% trans 'home' %}" width="58" />
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<h3>
|
||||||
{% trans "Verify Your Email Address" %}
|
{% trans "Verify Your Email Address" %}
|
||||||
{% endelement %}
|
</h3>
|
||||||
{% element p %}
|
|
||||||
|
|
||||||
|
<p>
|
||||||
{% blocktrans %}We have sent an email to you for verification. Follow the link provided to finalize the signup process. If you do not see the verification email in your main inbox, check your spam folder. Please contact us if you do not receive the verification email within a few minutes.{% endblocktrans %}
|
{% blocktrans %}We have sent an email to you for verification. Follow the link provided to finalize the signup process. If you do not see the verification email in your main inbox, check your spam folder. Please contact us if you do not receive the verification email within a few minutes.{% endblocktrans %}
|
||||||
{% endelement %}
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -1,14 +1,27 @@
|
|||||||
{% extends "account/base_entrance.html" %}
|
{% extends "base.html" %}
|
||||||
{% load i18n %}
|
{% load i18n static %}
|
||||||
{% load allauth %}
|
{% load allauth %}
|
||||||
{% block head_title %}
|
{% block head_title %}
|
||||||
{% trans "Verify Your Email Address" %}
|
{% trans "Verify Your Email Address" %}
|
||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% element h1 %}
|
<div class="row">
|
||||||
|
<div class="row flex-center min-vh-50 py-5">
|
||||||
|
<div class="col-sm-10 col-md-8 col-lg-5 col-xxl-4">
|
||||||
|
<a class="d-flex flex-center text-decoration-none mb-4" href="{% url 'home' %}">
|
||||||
|
<div class="d-flex align-items-center fw-bolder fs-3 d-inline-block">
|
||||||
|
<img class="d-dark-none" src="{% static 'images/logos/logo-d.png' %}" alt="{% trans 'home' %}" width="58" />
|
||||||
|
<img class="d-light-none" src="{% static 'images/logos/logo.png' %}" alt="{% trans 'home' %}" width="58" />
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<h3>
|
||||||
{% trans "Verify Your Email Address" %}
|
{% trans "Verify Your Email Address" %}
|
||||||
{% endelement %}
|
</h3>
|
||||||
{% element p %}
|
|
||||||
|
<p>
|
||||||
{% blocktrans %}We have sent an email to you for verification. Follow the link provided to finalize the signup process. If you do not see the verification email in your main inbox, check your spam folder. Please contact us if you do not receive the verification email within a few minutes.{% endblocktrans %}
|
{% blocktrans %}We have sent an email to you for verification. Follow the link provided to finalize the signup process. If you do not see the verification email in your main inbox, check your spam folder. Please contact us if you do not receive the verification email within a few minutes.{% endblocktrans %}
|
||||||
{% endelement %}
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -1,25 +1,38 @@
|
|||||||
{% extends "account/base_manage.html" %}
|
{% extends "base.html" %}
|
||||||
{% load i18n %}
|
{% load i18n static%}
|
||||||
{% load allauth %}
|
{% load allauth %}
|
||||||
{% block head_title %}
|
{% block head_title %}
|
||||||
{% trans "Verify Your Email Address" %}
|
{% trans "Verify Your Email Address" %}
|
||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% element h1 %}
|
<div class="row">
|
||||||
|
<div class="row flex-center min-vh-50 py-5">
|
||||||
|
<div class="col-sm-10 col-md-8 col-lg-5 col-xxl-4">
|
||||||
|
<a class="d-flex flex-center text-decoration-none mb-4" href="{% url 'home' %}">
|
||||||
|
<div class="d-flex align-items-center fw-bolder fs-3 d-inline-block">
|
||||||
|
<img class="d-dark-none" src="{% static 'images/logos/logo-d.png' %}" alt="{% trans 'home' %}" width="58" />
|
||||||
|
<img class="d-light-none" src="{% static 'images/logos/logo.png' %}" alt="{% trans 'home' %}" width="58" />
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<h3>
|
||||||
{% trans "Verify Your Email Address" %}
|
{% trans "Verify Your Email Address" %}
|
||||||
{% endelement %}
|
</h3>
|
||||||
|
|
||||||
{% url 'account_email' as email_url %}
|
{% url 'account_email' as email_url %}
|
||||||
{% element p %}
|
<p>
|
||||||
{% blocktrans %}This part of the site requires us to verify that
|
{% blocktrans %}This part of the site requires us to verify that
|
||||||
you are who you claim to be. For this purpose, we require that you
|
you are who you claim to be. For this purpose, we require that you
|
||||||
verify ownership of your email address. {% endblocktrans %}
|
verify ownership of your email address. {% endblocktrans %}
|
||||||
{% endelement %}
|
</p>
|
||||||
{% element p %}
|
<p>
|
||||||
{% blocktrans %}We have sent an email to you for
|
{% blocktrans %}We have sent an email to you for
|
||||||
verification. Please click on the link inside that email. If you do not see the verification email in your main inbox, check your spam folder. Otherwise
|
verification. Please click on the link inside that email. If you do not see the verification email in your main inbox, check your spam folder. Otherwise
|
||||||
contact us if you do not receive it within a few minutes.{% endblocktrans %}
|
contact us if you do not receive it within a few minutes.{% endblocktrans %}
|
||||||
{% endelement %}
|
</p>
|
||||||
{% element p %}
|
<p>
|
||||||
{% blocktrans %}<strong>Note:</strong> you can still <a href="{{ email_url }}">change your email address</a>.{% endblocktrans %}
|
{% blocktrans %}<strong>Note:</strong> you can still <a href="{{ email_url }}">change your email address</a>.{% endblocktrans %}
|
||||||
{% endelement %}
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@ -84,17 +84,27 @@
|
|||||||
<section class="bg-body-emphasis pb-8" id="home">
|
<section class="bg-body-emphasis pb-8" id="home">
|
||||||
<div class="row-small hero-header-row px-lg-7 px-xxl-3">
|
<div class="row-small hero-header-row px-lg-7 px-xxl-3">
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<div class="col-12 col-lg-6 text-lg-start text-center pt-8 pb-6">
|
<div class="container-fluid ps-3"
|
||||||
|
style="
|
||||||
|
background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)), url('{% static 'images/logos/hero_02.png' %}');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
padding: 220px 0 0 0;">
|
||||||
<h1 class="fs-3 fs-lg-2 fs-md-1 fs-xl-1 fw-black mb-4">
|
<h1 class="fs-3 fs-lg-2 fs-md-1 fs-xl-1 fw-black mb-4">
|
||||||
<span class="text-primary me-3">{% trans 'Streamline' %}</span>{% trans 'Your Car Dealership Operations' %}
|
<span class="text-primary me-3">{% trans 'Streamline' %}</span> {% trans 'Your Car Dealership Operations' %}
|
||||||
</h1>
|
</h1>
|
||||||
<p class="mb-5">{% trans 'Manage inventory, sales, transfers, and accounting seamlessly with Haikal.' %}</p>
|
<p class="mb-5">{% trans 'Manage inventory, sales, transfers, and accounting seamlessly with Haikal.' %}</p>
|
||||||
<a class="btn btn-lg btn-primary rounded-pill me-3" href="{% url 'account_signup' %}" role="button">{% trans 'Get Started' %}</a>
|
<a class="btn btn-lg btn-primary rounded-pill me-3" href="{% url 'account_signup' %}" role="button">{% trans 'Get Started' %}</a>
|
||||||
<a class="btn btn-link fs-8 p-0" href="#feature" role="button">{% trans 'Learn More' %}<span class="fa-solid fa-angle-right ms-2 fs-9"></span></a>
|
<a class="btn btn-link fs-8 p-0" href="#feature" role="button">{% trans 'Learn More' %}
|
||||||
</div>
|
{% if LANGUAGE_CODE == 'ar' %}
|
||||||
<div class="col-12 col-lg-6 text-center">
|
<span class="fa-solid fa-angle-left ms-2 fs-9"></span>
|
||||||
<img class="w-100 shadow-lg rounded-2" src="{% static 'images/bg/haikal-dashboard.png' %}" alt="Haikal Dashboard" />
|
{% else %}
|
||||||
|
<span class="fa-solid fa-angle-right ms-2 fs-9"></span>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -107,17 +117,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 text-center">
|
<div class="col-md-4 text-center">
|
||||||
<img src="{% static 'images/icons/inventory.png' %}" alt="Inventory Management" class="mb-3" width="60">
|
<img src="{% static 'images/icons/35420_store.svg' %}" alt="Inventory Management" class="mb-3" width="60">
|
||||||
<h5>{% trans 'Inventory Management' %}</h5>
|
<h5>{% trans 'Inventory Management' %}</h5>
|
||||||
<p>{% trans 'Effortlessly manage your car inventory with real-time updates and intuitive tools.' %}</p>
|
<p>{% trans 'Effortlessly manage your car inventory with real-time updates and intuitive tools.' %}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 text-center">
|
<div class="col-md-4 text-center">
|
||||||
<img src="{% static 'images/icons/accounting.png' %}" alt="Seamless Accounting" class="mb-3" width="60">
|
<img src="{% static 'images/icons/148542_list.svg' %}" alt="Seamless Accounting" class="mb-3" width="60">
|
||||||
<h5>{% trans 'Seamless Accounting' %}</h5>
|
<h5>{% trans 'Seamless Accounting' %}</h5>
|
||||||
<p>{% trans 'Integrated double-entry accounting tailored for car dealers.' %}</p>
|
<p>{% trans 'Integrated double-entry accounting tailored for car dealers.' %}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 text-center">
|
<div class="col-md-4 text-center">
|
||||||
<img src="{% static 'images/icons/analytics.png' %}" alt="Advanced Analytics" class="mb-3" width="60">
|
<img src="{% static 'images/icons/114292_report.svg' %}" alt="Advanced Analytics" class="mb-3" width="60">
|
||||||
<h5>{% trans 'Advanced Analytics' %}</h5>
|
<h5>{% trans 'Advanced Analytics' %}</h5>
|
||||||
<p>{% trans 'Gain insights and make data-driven decisions for your business.' %}</p>
|
<p>{% trans 'Gain insights and make data-driven decisions for your business.' %}</p>
|
||||||
</div>
|
</div>
|
||||||
@ -131,36 +141,20 @@
|
|||||||
<h2 class="mb-3 text-body-emphasis lh-base">{% trans 'Choose the Plan that Fits Your Business' %}</h2>
|
<h2 class="mb-3 text-body-emphasis lh-base">{% trans 'Choose the Plan that Fits Your Business' %}</h2>
|
||||||
<p class="mb-5">{% trans 'Flexible pricing plans designed to meet the unique needs of every dealership.' %}</p>
|
<p class="mb-5">{% trans 'Flexible pricing plans designed to meet the unique needs of every dealership.' %}</p>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
{% for plan in plans %}
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
|
|
||||||
<div class="card shadow-sm">
|
<div class="card shadow-sm">
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">{% trans 'Basic' %}</h5>
|
<h5 class="card-title">{{plan.name }}</h5>
|
||||||
<p class="card-text">{% trans 'Essential tools to get your dealership started.' %}</p>
|
<p class="card-text">{{ plan.description }}</p>
|
||||||
<p class="h4">$29/month</p>
|
<p class="h4">{{ plan.price }}</p>
|
||||||
<a href="{% url 'account_signup' %}" class="btn btn-primary mt-3">{% trans 'Get Started' %}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card shadow-sm">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">{% trans 'Pro' %}</h5>
|
|
||||||
<p class="card-text">{% trans 'Advanced features for growing dealerships.' %}</p>
|
|
||||||
<p class="h4">$59/month</p>
|
|
||||||
<a href="{% url 'account_signup' %}" class="btn btn-primary mt-3">{% trans 'Get Started' %}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card shadow-sm">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">{% trans 'Enterprise' %}</h5>
|
|
||||||
<p class="card-text">{% trans 'Comprehensive solutions for large-scale operations.' %}</p>
|
|
||||||
<p class="h4">$99/month</p>
|
|
||||||
<a href="{% url 'account_signup' %}" class="btn btn-primary mt-3">{% trans 'Get Started' %}</a>
|
<a href="{% url 'account_signup' %}" class="btn btn-primary mt-3">{% trans 'Get Started' %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user