This commit is contained in:
gitea 2025-02-06 08:34:41 +00:00
commit 333f4ce686
50 changed files with 1484 additions and 929 deletions

BIN
inventory/.DS_Store vendored

Binary file not shown.

View File

@ -1,3 +1,9 @@
from django.conf import settings
def currency_context(request):
return {
'CURRENCY': settings.CURRENCY
}
def breadcrumbs(request):

View File

@ -298,7 +298,12 @@ class CustomCardForm(forms.ModelForm):
class CarRegistrationForm(forms.ModelForm):
class Meta:
model = CarRegistration
fields = ["car", "plate_number", "text1", "text2", "text3", "registration_date"]
fields = ["plate_number", "text1", "text2", "text3", "registration_date"]
widgets = {
'registration_date': forms.DateTimeInput(attrs={'type': 'datetime-local'}),
}
# class VendorForm(VendorModelForm):

View File

@ -0,0 +1,19 @@
# Generated by Django 5.1.5 on 2025-02-04 04:37
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='carregistration',
name='car',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='registrations', to='inventory.car', verbose_name='Car'),
),
]

View File

@ -690,7 +690,7 @@ class CarLocation(models.Model):
class CarRegistration(models.Model):
car = models.ForeignKey(
car = models.OneToOneField(
Car,
on_delete=models.CASCADE,
related_name="registrations",
@ -698,8 +698,8 @@ class CarRegistration(models.Model):
)
plate_number = models.IntegerField(verbose_name=_("Plate Number"))
text1 = models.CharField(max_length=1, verbose_name=_("Text 1"))
text2 = models.CharField(max_length=1, verbose_name=_("Text 2"))
text3 = models.CharField(max_length=1, verbose_name=_("Text 3"))
text2 = models.CharField(max_length=1, verbose_name=_("Text 2"), null=True, blank=True)
text3 = models.CharField(max_length=1, verbose_name=_("Text 3"), null=True, blank=True)
registration_date = models.DateTimeField(verbose_name=_("Registration Date"))
class Meta:
@ -707,7 +707,7 @@ class CarRegistration(models.Model):
verbose_name_plural = _("Registrations")
def __str__(self):
return f"{self.plate_number} - {self.text1} {self.text2} {self.text3}"
return f"{self.plate_number}"
# TimestampedModel Abstract Class

BIN
inventory/templatetags/.DS_Store vendored Normal file

Binary file not shown.

View File

View File

@ -3,6 +3,8 @@ from django import template
from calendar import month_abbr
from django.urls import reverse
from django_ledger.io.io_core import get_localdate,validate_activity
from django.conf import settings
from django.utils.translation import get_language
register = template.Library()
@ -230,3 +232,97 @@ def date_picker(context, nav_url=None, date_picker_id=None):
'date_picker_id': date_picker_id,
'date_navigation_url': date_navigation_url
}
@register.simple_tag(name='get_currency')
def get_currency():
return settings.CURRENCY
@register.simple_tag(name='num2words', takes_context=True)
def number_to_words_english(number):
"""Convert a number to words in English."""
units = ["", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
teens = ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen",
"seventeen", "eighteen", "nineteen"]
tens = ["", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy",
"eighty", "ninety"]
scales = ["", "thousand", "million", "billion", "trillion"]
if number == 0:
return "zero"
words = []
scale_index = 0
while number > 0:
chunk = number % 1000
if chunk != 0:
chunk_words = []
if chunk // 100 > 0:
chunk_words.append(units[chunk // 100])
chunk_words.append("hundred")
if chunk % 100 >= 20:
chunk_words.append(tens[(chunk % 100) // 10])
if chunk % 10 > 0:
chunk_words.append(units[chunk % 10])
elif 10 <= chunk % 100 < 20:
chunk_words.append(teens[chunk % 100 - 10])
else:
if chunk % 10 > 0:
chunk_words.append(units[chunk % 10])
if scale_index > 0:
chunk_words.append(scales[scale_index])
words = chunk_words + words
number = number // 1000
scale_index += 1
return ' '.join(words)
def number_to_words_arabic(number):
"""Convert a number to words in Arabic."""
units = ["", "واحد", "اثنان", "ثلاثة", "أربعة", "خمسة", "ستة", "سبعة", "ثمانية", "تسعة"]
teens = ["عشرة", "أحد عشر", "اثنا عشر", "ثلاثة عشر", "أربعة عشر", "خمسة عشر",
"ستة عشر", "سبعة عشر", "ثمانية عشر", "تسعة عشر"]
tens = ["", "عشرة", "عشرون", "ثلاثون", "أربعون", "خمسون", "ستون", "سبعون",
"ثمانون", "تسعون"]
scales = ["", "ألف", "مليون", "مليار", "تريليون"]
if number == 0:
return "صفر"
words = []
scale_index = 0
while number > 0:
chunk = number % 1000
if chunk != 0:
chunk_words = []
if chunk // 100 > 0:
chunk_words.append(units[chunk // 100])
chunk_words.append("مائة")
if chunk % 100 >= 20:
chunk_words.append(tens[(chunk % 100) // 10])
if chunk % 10 > 0:
chunk_words.append(units[chunk % 10])
elif 10 <= chunk % 100 < 20:
chunk_words.append(teens[chunk % 100 - 10])
else:
if chunk % 10 > 0:
chunk_words.append(units[chunk % 10])
if scale_index > 0:
chunk_words.append(scales[scale_index])
words = chunk_words + words
number = number // 1000
scale_index += 1
return ' '.join(words)
@register.filter(name='num2words')
def num2words(number, language='en'):
"""Template filter to convert a number to words in the specified language."""
if language == 'ar':
return number_to_words_arabic(number)
else:
return number_to_words_english(number)

View File

@ -0,0 +1,11 @@
from django import template
from num2words import num2words
register = template.Library()
@register.filter
def num_to_words(value, lang='en'):
try:
return num2words(value, lang=lang)
except:
return value

View File

@ -210,7 +210,7 @@ urlpatterns = [
),
path(
"cars/<int:pk>/location/detail/",
views.CarTransferDetailView,
views.CarTransferDetailView.as_view(),
name="transfer_detail",
),
path(
@ -228,9 +228,13 @@ urlpatterns = [
views.CarTransferPreviewView,
name="transfer_preview",
),
path("cars/inventory/search/", views.SearchCodeView.as_view(), name="car_search"),
path("cars/inventory/search/",
views.SearchCodeView.as_view(),
name="car_search"),
# path('cars/<int:car_pk>/colors/<int:pk>/update/',views.CarColorUpdateView.as_view(),name='color_update'),
path("cars/reserve/<int:car_id>/", views.reserve_car_view, name="reserve_car"),
path("cars/reserve/<int:car_id>/",
views.reserve_car_view,
name="reserve_car"),
path(
"reservations/<int:reservation_id>/",
views.manage_reservation,
@ -241,6 +245,10 @@ urlpatterns = [
views.CustomCardCreateView.as_view(),
name="add_custom_card",
),
path('cars/<int:car_pk>/add-registration/',
views.CarRegistrationCreateView.as_view(),
name='add_registration'),
# Sales URLs quotation_create
# path(
# "sales/quotations/create/",

View File

@ -1,5 +1,8 @@
from plans.taxation import TaxationPolicy
from decimal import Decimal
from django.conf import settings
from plans.taxation import TaxationPolicy
class SaudiTaxationPolicy(TaxationPolicy):
@ -10,5 +13,5 @@ class SaudiTaxationPolicy(TaxationPolicy):
return getattr(settings, 'PLANS_TAX_COUNTRY', None)
def get_tax_rate(self, tax_id, country_code, request=None):
return 0, True
rate = Decimal("15")
return rate

View File

@ -324,9 +324,9 @@ class WelcomeView(TemplateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
dealer = get_user_type(self.request)
plans = Plan.objects.all()
plan_list = Plan.objects.all()
# pricing = PlanPricing.objects.filter(plan=plan).
context["plans"] = plans
context["plan_list"] = plan_list
return context
@ -862,10 +862,15 @@ class CarTransferCreateView(CreateView):
return reverse_lazy("car_detail", kwargs={"pk": self.object.car.pk})
def CarTransferDetailView(request, pk):
transfer = get_object_or_404(models.CarTransfer, pk=pk)
context = {"transfer": transfer}
return render(request, "inventory/transfer_details.html", context)
# def CarTransferDetailView(request, pk):
# transfer = get_object_or_404(models.CarTransfer, pk=pk)
# context = {"transfer": transfer}
# return render(request, "inventory/transfer_details.html", context)
class CarTransferDetailView(LoginRequiredMixin, SuccessMessageMixin, DetailView):
model = models.CarTransfer
template_name = "inventory/transfer_details.html"
context_object_name = "transfer"
def car_transfer_approve(request, car_pk, transfer_pk):
@ -994,6 +999,26 @@ class CustomCardCreateView(LoginRequiredMixin, CreateView):
return reverse_lazy("car_detail", kwargs={"pk": self.kwargs["car_pk"]})
class CarRegistrationCreateView(LoginRequiredMixin, CreateView):
model = models.CarRegistration
form_class = forms.CarRegistrationForm
template_name = 'inventory/car_registration_form.html'
def form_valid(self, form):
car = get_object_or_404(models.Car, pk=self.kwargs["car_pk"])
form.instance.car = car
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["car"] = get_object_or_404(models.Car, pk=self.kwargs["car_pk"])
return context
def get_success_url(self):
messages.success(self.request, _("Registration added successfully."))
return reverse_lazy("car_detail", kwargs={"pk": self.kwargs["car_pk"]})
@login_required()
def reserve_car_view(request, car_id):
if request.method == "POST":

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -74,6 +74,7 @@ djangocms-admin-style==3.3.1
djangorestframework==3.15.2
djangorestframework_simplejwt==5.4.0
djangoviz==0.1.1
docopt==0.6.2
docutils==0.21.2
easy-thumbnails==2.10
emoji==2.14.1
@ -126,6 +127,7 @@ mypy-extensions==1.0.0
networkx==3.4.2
newrelic==10.4.0
nltk==3.9.1
num2words==0.5.14
numpy==2.2.2
oauthlib==3.2.2
ofxtools==0.9.5

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

View File

@ -91,7 +91,7 @@ function notify(tag,msg){
<div class="content">
{% include "plans/expiration_messages.html" %}
{% block period_navigation %}
{% endblock period_navigation %}

View File

@ -41,10 +41,13 @@
<div class="col-sm-6 col-md-4 col-xl-3 col-xxl-4 align-content-center">
<div class="card h-75">
<div class="card-body">
<div class="d-flex d-sm-block justify-content-between">
<div class="border-translucent mb-sm-4">
<div class="d-flex align-items-center">
<div class="d-flex align-items-center icon-wrapper-sm shadow-primary-100" style="transform: rotate(-7.45deg);"><span class="fa-solid fa-phone-alt text-primary fs-7 z-1 ms-2"></span></div>
<div class="d-flex align-items-center icon-wrapper-sm shadow-primary-100" style="transform: rotate(-7.45deg);">
<div class="icon icon-shape bg-gradient-info text-white rounded-circle shadow">MMMMMMMMMMMMMMM</div>
</div>
<p class="text-body-tertiary fs-9 mb-0 ms-2 mt-3">Outgoing call</p>
</div>
<p class="text-primary mt-2 fs-6 fw-bold mb-0 mb-sm-4">3 <span class="fs-8 text-body lh-lg">Leads Today</span></p>

View File

@ -4,6 +4,17 @@
<form method="post" id="customCardForm" action="{% url 'add_custom_card' car.pk %}">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-sm btn-success">{% trans 'Save' %}</button>
<button type="button" class="btn btn-sm btn-danger" data-bs-dismiss="modal">{% trans 'Cancel' %}</button>
<div class="d-flex gap-1">
<button type="button"
class="btn btn-sm btn-danger w-50"
data-bs-dismiss="modal"
aria-label="Cancel and close modal">
<i class="fas fa-times"></i> {% trans 'Cancel' %}
</button>
<button type="submit"
class="btn btn-sm btn-success w-50"
aria-label="Save changes">
<i class="fas fa-check"></i> {% trans 'Save' %}
</button>
</div>
</form>

View File

@ -58,7 +58,7 @@
{% if car.vendor %}
<tr>
<th>{% trans "Vendor"|capfirst %}</th>
<td>{{ car.vendor.get_local_name }}</td>
<td>{{ car.vendor.vendor_name }}</td>
</tr>
{% endif %}
<tr>
@ -92,6 +92,28 @@
</td>
</tr>
{% endif %}
{% if car.registrations %}
<tr>
<th>{% trans "Registration"|capfirst %}</th>
<td>{{ car.registrations.plate_number }} | {{ car.registrations.text1 }} {{ car.registrations.text2 }} {{ car.registrations.text3 }}
</td>
</tr>
<tr>
<th>{% trans "Registration Date"|capfirst %}</th>
<td>{{ car.registrations.registration_date|date }}</td>
</tr>
{% else %}
<tr>
<th>{% trans "Registration" %}</th>
<td>
<button type="button" class="btn btn-sm btn-phoenix-success" data-bs-toggle="modal" data-bs-target="#registrationModal">
{% trans 'Add' %}
</button>
</td>
</tr>
{% endif %}
<tr>
<th>{% trans 'Location'|capfirst %}</th>
@ -313,7 +335,7 @@
{% endif %}
</td>
<td>
<a class="btn btn-sm btn-phoenix-success" href="{% url 'transfer_detail' car.get_transfer.pk %}?action=cancel">Cancel</a>
<a class="btn btn-sm btn-phoenix-success" href="{% url 'transfer_detail' car.get_transfer.pk %}?action=cancel">Cancel</a>
</td>
</tr>
</tbody>
@ -325,12 +347,13 @@
</div>
</div>
</div>
<!-- Custom Card Modal -->
<div class="modal fade" id="customCardModal" tabindex="-1" aria-labelledby="customCardModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header bg-primary">
<h5 class="modal-title text-light" id="customCardModalLabel">{% trans 'Custom Card' %}</h5>
<div class="modal-header">
<h5 class="modal-title" id="customCardModalLabel">{% trans 'Custom Card' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
@ -339,26 +362,54 @@
</div>
</div>
</div>
<!-- Registration Modal -->
<div class="modal fade" id="registrationModal" tabindex="-1" aria-labelledby="cregistrationModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="registrationModalLabel">{% trans 'Registration' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- Content will be loaded here via AJAX -->
</div>
</div>
</div>
</div>
<!-- Reservation Modal -->
<div class="modal fade" id="reserveModal" tabindex="-1" aria-labelledby="reserveModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header bg-primary">
<h5 class="modal-title text-light" id="reserveModalLabel">{% trans 'Car Reservation' %}</h5>
<div class="modal-header">
<h5 class="modal-title" id="reserveModalLabel">{% trans 'Car Reservation' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{% trans 'Are you sure you want to reserve this car?' %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-phoenix-danger" data-bs-dismiss="modal">
{% trans 'No' %}
</button>
<form method="POST" action="{% url 'reserve_car' car.id %}" class="d-inline">
<form method="POST" action="{% url 'reserve_car' car.id %}" class="form ">
{% csrf_token %}
<button type="submit" class="btn btn-phoenix-success btn-sm">{% trans "Yes" %}</button>
</form>
</div>
<div class="p-1">
<div class="d-flex gap-1">
<button type="button"
class="btn btn-sm btn-danger w-50"
data-bs-dismiss="modal"
aria-label="Cancel and close modal">
<i class="fas fa-times"></i> {% trans 'No' %}
</button>
<button type="submit"
class="btn btn-sm btn-success w-50"
aria-label="Save changes">
<i class="fas fa-check"></i> {% trans 'Yes' %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
@ -371,10 +422,7 @@
<button class="btn btn-close p-1" type="button" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="specificationsContent"></div>
</div>
<div class="modal-footer">
<button class="btn btn-phoenix-primary" type="button" data-bs-dismiss="modal">{% trans 'Close' %}</button>
<div class="list-inline" id="specificationsContent"></div>
</div>
</div>
</div>
@ -382,29 +430,16 @@
<script>
document.addEventListener("DOMContentLoaded", function () {
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== "") {
const cookies = document.cookie.split(";");
for (let cookie of cookies) {
cookie = cookie.trim();
if (cookie.substring(0, name.length + 1) === name + "=") {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrfToken = getCookie("csrftoken");
const csrftoken = getCookie("csrftoken");
const ajaxUrl = "{% url 'ajax_handler' %}";
const modal = document.getElementById("customCardModal");
const modalBody = modal.querySelector(".modal-body");
const customCardModal = document.getElementById("customCardModal");
const modalBody = customCardModal.querySelector(".modal-body");
// When the modal is triggered, load the form
modal.addEventListener("show.bs.modal", function () {
customCardModal.addEventListener("show.bs.modal", function () {
const url = "{% url 'add_custom_card' car.pk %}";
fetch(url)
@ -418,10 +453,32 @@
});
});
modal.addEventListener("hidden.bs.modal", function () {
customCardModal.addEventListener("hidden.bs.modal", function () {
modalBody.innerHTML = "";
});
const registrationModal = document.getElementById("registrationModal");
const modalBody_r = registrationModal.querySelector(".modal-body");
// When the modal is triggered, load the form
registrationModal.addEventListener("show.bs.modal", function () {
const url = "{% url 'add_registration' car.pk %}";
fetch(url)
.then((response) => response.text())
.then((html) => {
modalBody_r.innerHTML = html;
})
.catch((error) => {
modalBody_r.innerHTML = '<p class="text-danger">{{_("Error loading form. Please try again later")}}.</p>';
console.error("Error loading form:", error);
});
});
registrationModal.addEventListener("hidden.bs.modal", function () {
modalBody_r.innerHTML = "";
});
const showSpecificationButton = document.getElementById("specification-btn");
const specificationsContent = document.getElementById("specificationsContent");
@ -430,7 +487,7 @@
fetch(`${ajaxUrl}?action=get_specifications&trim_id={{ car.id_car_trim.id_car_trim }}`, {
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": csrfToken,
"X-CSRFToken": csrftoken,
},
})
.then((response) => response.json())

View File

@ -185,10 +185,10 @@
<div class="card h-100">
<div class="card-body">
<div class="form-floating">
<label for="{{ form.remarks.id_for_label }}">
{{ form.remarks|add_class:"form-control form-control-sm" }}
<label for="{{ form.remarks.id_for_label }}">
{% trans 'Remarks'|capfirst %}:
</label>
{{ form.remarks|add_class:"form-control form-control-sm" }}
</div>
</div>
</div>

View File

@ -2,7 +2,7 @@
{% load i18n static %}
{% block title %}
{% trans 'inventory'|capfirst %}
{% trans "inventory"|capfirst %}
{% endblock %}

View File

@ -0,0 +1,22 @@
{% load i18n %}
{% load crispy_forms_filters %}
<div class="w-100 g-3">
<form method="post" id="registrationForm" action="{% url 'add_registration' car.pk %}">
{% csrf_token %}
{{ form|crispy }}
<div class="d-flex gap-1">
<button type="button"
class="btn btn-sm btn-danger w-50"
data-bs-dismiss="modal"
aria-label="Cancel and close modal">
<i class="fas fa-times"></i> {% trans 'Cancel' %}
</button>
<button type="submit"
class="btn btn-sm btn-success w-50"
aria-label="Save changes">
<i class="fas fa-check"></i> {% trans 'Save' %}
</button>
</div>
</form>
</div>

View File

@ -1,16 +1,31 @@
{% extends "base.html" %}
{% load i18n %}
{% load i18n static %}
{% block title %}
{% trans "Inventory Statistics" %}
{% trans "inventory"|capfirst %}
{% endblock %}
{% block content %}
<div class="row mt-4">
<div class="row justify-content-between">
<div class="col-sm-12 ">
<div class="card border h-100 w-100 p-lg-10">
<div class="bg-holder d-block bg-card" style="background-image:url({% static 'images/spot-illustrations/32.png' %});background-position: top right;">
</div>
<div class="d-dark-none me-5">
<div class="bg-holder d-none d-sm-block d-xl-none d-xxl-block bg-card" style="background-image:url({% static 'images/spot-illustrations/dark_21.png' %}); background-position: bottom right; background-size: auto;">
</div>
</div>
<div class="d-light-none me-5">
<div class="bg-holder d-none d-sm-block d-xl-none d-xxl-block bg-card" style="background-image:url({% static 'images/spot-illustrations/21.png' %}); background-position: bottom right; background-size: auto;">
</div>
</div>
</div>
</div>
</div>
<!-- Total Cars -->
<div class="row justify-content-center">
<div class="col-sm-12">
<!-- Inventory by Makes -->
<div class="accordion" id="makesAccordion">
{% for make in inventory.makes %}
@ -72,4 +87,6 @@
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View File

@ -2,6 +2,7 @@
{% load crispy_forms_filters %}
{% load i18n %}
{% load custom_filters %}
{% load num2words_tags %}
{% block title %}
{% trans 'Car Transfer Details' %}
@ -34,36 +35,81 @@
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header bg-primary">
<h5 class="modal-title text-light" id="cancelModalLabel">{% trans 'Car Transfer Cancel' %}</h5>
<h5 class="modal-title text-light" id="cancelModalLabel">{% trans 'Cancel Transfer' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{% trans 'Are you sure?' %}
{% trans 'Are you sure' %}?
</div>
<div class="p-1">
<div class="d-flex gap-1">
<button type="button" class="btn btn-sm btn-danger" data-bs-dismiss="modal">{% trans 'No' %}</button>
<a href="{% url 'transfer_confirm' transfer.car.pk transfer.pk %}?action=cancel" type="button" type="submit" class="btn btn-success btn-sm">{% trans 'Yes' %}</a>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-phoenix-danger" data-bs-dismiss="modal">{% trans 'No' %}</button>
<a href="{% url 'transfer_confirm' transfer.car.pk transfer.pk %}?action=cancel" type="button" type="submit" class="btn btn-phoenix-success btn-sm">{% trans 'Confirm' %}</a>
</div>
</div>
</div>
</div>
<div class="row p-4">
<div class="row g-1">
<div class="col-lg-4 col-xl-12"></div>
</div>
<div class="row g-1">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-phoenix-success" data-bs-toggle="modal" data-bs-target="#approveCardModal">
{% trans 'Approve' %}
</button>
<button type="button" class="btn btn-sm btn-phoenix-warning" data-bs-toggle="modal" data-bs-target="#cancelCardModal">
{% trans 'Cancel Transfer' %}
</button>
<a href="{{ request.META.HTTP_REFERER }}" class="btn btn-sm btn-info">{% trans 'Return' %}</a>
<div class="row g-3">
<div class="col-12">
<h3 class="my-3">{% trans 'Transfer Details' %}</h3>
<div class="transfer-details">
<p><strong>{% trans "Date" %} :</strong> {{transfer.created_at}}</p>
<p><strong>{% trans "From" %} :</strong> {{transfer.from_dealer}}</p>
<p><strong>{% trans "To" %} :</strong> {{transfer.to_dealer}}</p>
</div>
<!-- Items Table -->
<div class="table table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>{% trans "VIN" %}</th>
<th>{% trans "Car" %}</th>
<th class="text-center">{% trans "Price" %}</th>
<th class="text-center">{% trans "VAT" %}</th>
<th class="text-center">{% trans "Total" %}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ transfer.car.vin }}</td>
<td>{{ transfer.car }}</td>
<td class="text-center">{{ transfer.car.finances.selling_price }}&nbsp;{{ CURRENCY }}</td>
<td class="text-center">{{ transfer.car.finances.vat_amount }}&nbsp;{{ CURRENCY }}</td>
<td class="text-center">{{ transfer.total_price }}&nbsp;{{ CURRENCY }}</td>
</tr>
</tbody>
</table>
</div>
<!-- Total -->
<div class="transfer-total">
<p><strong>{%trans "Total Amount" %}:</strong> <span class="text-danger-darker fw-bold fs-8">{{transfer.total_price}}&nbsp;{{ CURRENCY }}</span></p>
<p><strong>{%trans "Total Amount written" %}:</strong> <span>{{ transfer.total_price|num_to_words:"ar" }}&nbsp;{{ CURRENCY }} {{ _("only") }}</span></p>
</div>
</div>
<div class="col-12">
</div>
</div>
</div>
<div class="row g-1">
<div class="col-12">
<div class="d-flex gap-1">
<button type="button" class="btn btn-sm btn-success w-100" data-bs-toggle="modal" data-bs-target="#approveCardModal">
{% trans 'Approve' %}
</button>
<button type="button" class="btn btn-sm btn-warning w-100" data-bs-toggle="modal" data-bs-target="#cancelCardModal">
{% trans 'Cancel Transfer' %}
</button>
</div>
</div>
</div>
<!-- JavaScript Section -->
{% endblock %}

View File

@ -151,49 +151,7 @@
navbarVertical.setAttribute('data-navbar-appearance', 'darker');
}
</script>
<div class="support-chat-row">
<div class="row-fluid support-chat">
<div class="card bg-body-emphasis">
<div class="card-header d-flex flex-between-center px-4 py-3 border-bottom border-translucent">
<h5 class="mb-0 d-flex align-items-center gap-2">Demo widget<span class="fa-solid fa-circle text-success fs-11"></span></h5>
<div class="btn-reveal-trigger">
<button class="btn btn-link p-0 dropdown-toggle dropdown-caret-none transition-none d-flex" type="button" id="support-chat-dropdown" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h text-body"></span></button>
<div class="dropdown-menu dropdown-menu-end py-2" aria-labelledby="support-chat-dropdown"><a class="dropdown-item" href="#!">Request a callback</a><a class="dropdown-item" href="#!">Search in chat</a><a class="dropdown-item" href="#!">Show history</a><a class="dropdown-item" href="#!">Report to Admin</a><a class="dropdown-item btn-support-chat" href="#!">Close Support</a></div>
</div>
</div>
<div class="card-body chat p-0">
<div class="d-flex flex-column-reverse scrollbar h-100 p-3">
<div class="text-end mt-6"><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3" href="#!">
<p class="mb-0 fw-semibold fs-9">I need help with something</p><span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3" href="#!">
<p class="mb-0 fw-semibold fs-9">I cant reorder a product I previously ordered</p><span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
</a><a class="mb-2 d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3" href="#!">
<p class="mb-0 fw-semibold fs-9">How do I place an order?</p><span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
</a><a class="false d-inline-flex align-items-center text-decoration-none text-body-emphasis bg-body-hover rounded-pill border border-primary py-2 ps-4 pe-3" href="#!">
<p class="mb-0 fw-semibold fs-9">My payment method not working</p><span class="fa-solid fa-paper-plane text-primary fs-9 ms-3"></span>
</a>
</div>
<div class="text-center mt-auto">
<div class="avatar avatar-3xl status-online"><img class="rounded-circle border border-3 border-light-subtle" src="../../assets/img/team/30.webp" alt="" /></div>
<h5 class="mt-2 mb-3">Eric</h5>
<p class="text-center text-body-emphasis mb-0">Ask us anything well get back to you here or by email within 24 hours.</p>
</div>
</div>
</div>
<div class="card-footer d-flex align-items-center gap-2 border-top border-translucent ps-3 pe-4 py-3">
<div class="d-flex align-items-center flex-1 gap-3 border border-translucent rounded-pill px-4">
<input class="form-control outline-none border-0 flex-1 fs-9 px-0" type="text" placeholder="Write message" />
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0" for="supportChatPhotos"><span class="fa-solid fa-image"></span></label>
<input class="d-none" type="file" accept="image/*" id="supportChatPhotos" />
<label class="btn btn-link d-flex p-0 text-body-quaternary fs-9 border-0" for="supportChatAttachment"> <span class="fa-solid fa-paperclip"></span></label>
<input class="d-none" type="file" id="supportChatAttachment" />
</div>
<button class="btn p-0 border-0 send-btn"><span class="fa-solid fa-paper-plane fs-9"></span></button>
</div>
</div>
</div>
<button class="btn btn-support-chat p-0 border border-translucent"><span class="fs-8 btn-text text-primary text-nowrap">Chat demo</span><span class="ping-icon-wrapper mt-n4 ms-n6 mt-sm-0 ms-sm-2 position-absolute position-sm-relative"><span class="ping-icon-bg"></span><span class="fa-solid fa-circle ping-icon"></span></span><span class="fa-solid fa-headset text-primary fs-8 d-sm-none"></span><span class="fa-solid fa-chevron-down text-primary fs-7"></span></button>
</div>
</main>
{% else%}
<div class="button-row">

View File

@ -36,7 +36,7 @@
{% if page_obj.object_list %}
<div class="table-responsive px-1 scrollbar">
<table class="table fs-9 mb-0 border-top border-translucent">
<table class="table align-items-center table-flush">
<thead>
<tr class="bg-body-highlight">

153
templates/login_test.html Normal file
View File

@ -0,0 +1,153 @@
<div class="card">
<div class="card-body">
<div class="places-buttons">
<div class="row">
<div class="col-md-6 ml-auto mr-auto text-center">
<h4 class="card-title">
Notifications Places
<p class="category">Click to view notifications</p>
</h4>
</div>
</div>
<div class="row">
<div class="col-lg-8 ml-auto mr-auto">
<div class="row">
<div class="col-md-4">
<button class="btn btn-primary btn-block" onclick="demo.showNotification('top','left')">Top Left</button>
</div>
<div class="col-md-4">
<button class="btn btn-primary btn-block" onclick="demo.showNotification('top','center')">Top Center</button>
</div>
<div class="col-md-4">
<button class="btn btn-primary btn-block" onclick="demo.showNotification('top','right')">Top Right</button>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 ml-auto mr-auto">
<div class="row">
<div class="col-md-4">
<button class="btn btn-primary btn-block" onclick="demo.showNotification('bottom','left')">Bottom Left</button>
</div>
<div class="col-md-4">
<button class="btn btn-primary btn-block" onclick="demo.showNotification('bottom','center')">Bottom Center</button>
</div>
<div class="col-md-4">
<button class="btn btn-primary btn-block" onclick="demo.showNotification('bottom','right')">Bottom Right</button>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 text-center">
<div class="card-header">
<h4 class="card-title">Modal</h4>
</div>
<button class="btn btn-primary" data-toggle="modal" data-target="#myModal">
Classic modal
</button>
<button class="btn btn-info" data-toggle="modal" data-target="#noticeModal">
Notice modal
</button>
<button class="btn" data-toggle="modal" data-target="#myModal10">
Small alert modal
</button>
<!-- Classic Modal -->
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="myModalLabel" style="display: none;" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header justify-content-center">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
<i class="now-ui-icons ui-1_simple-remove"></i>
</button>
<h4 class="title title-up">Modal title</h4>
</div>
<div class="modal-body">
<p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. A small river named Duden flows by their place and supplies it with the necessary regelialia. It is a paradisematic country, in which roasted parts of sentences fly into your mouth.
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default">Nice Button</button>
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- End Modal -->
<!-- notice modal -->
<div class="modal fade" id="noticeModal" tabindex="-1" aria-labelledby="myModalLabel" style="display: none;" aria-hidden="true">
<div class="modal-dialog modal-notice">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
<i class="now-ui-icons ui-1_simple-remove"></i>
</button>
<h5 class="modal-title" id="myModalLabel">How Do You Become an Affiliate?</h5>
</div>
<div class="modal-body">
<div class="instruction">
<div class="row">
<div class="col-md-8">
<strong>1. Register</strong>
<p class="description">The first step is to create an account at <a href="http://www.creative-tim.com/">Creative Tim</a>. You can choose a social network or go for the classic version, whatever works best for you.</p>
</div>
<div class="col-md-4">
<div class="picture">
<img src="../../assets/img/bg1.jpg" alt="Thumbnail Image" class="rounded img-raised">
</div>
</div>
</div>
</div>
<div class="instruction">
<div class="row">
<div class="col-md-8">
<strong>2. Apply</strong>
<p class="description">The first step is to create an account at <a href="http://www.creative-tim.com/">Creative Tim</a>. You can choose a social network or go for the classic version, whatever works best for you.</p>
</div>
<div class="col-md-4">
<div class="picture">
<img src="../../assets/img/bg3.jpg" alt="Thumbnail Image" class="rounded img-raised">
</div>
</div>
</div>
</div>
<p>If you have more questions, don't hesitate to contact us or send us a tweet @creativetim. We're here to help!</p>
</div>
<div class="modal-footer justify-content-center">
<button type="button" class="btn btn-info btn-round" data-dismiss="modal">Sounds good!</button>
</div>
</div>
</div>
</div>
<!-- end notice modal -->
<!-- small modal -->
<div class="modal fade modal-mini modal-primary show" id="myModal10" tabindex="-1" aria-labelledby="myModalLabel" style="display: block;" aria-modal="true" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header justify-content-center">
<div class="modal-profile">
<i class="now-ui-icons users_circle-08"></i>
</div>
</div>
<div class="modal-body">
<p>Always have an access to your profile</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-link btn-neutral">Back</button>
<button type="button" class="btn btn-link btn-neutral" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- end small modal -->
</div>
</div>
</div>
</div>

View File

@ -3,7 +3,7 @@
{% block body %}
<h1>{% if SUCCESSFUL %}{% trans "Activation successful" %}{% else %}{% trans "Activation failed" %}{% endif %}</h1>
<h3>{% if SUCCESSFUL %}{% trans "Activation successful" %}{% else %}{% trans "Activation failed" %}{% endif %}</h3>
{% if SUCCESSFUL %}
{# {% include "messages.html" %}#}

View File

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
{% block extra_js %}
{% endblock %}
</head>
<body>
<h1>django-plans</h1>
{% include "plans/expiration_messages.html" %}
{% block body %}
{% endblock %}
</body>
</html>

View File

@ -2,21 +2,20 @@
{% load i18n crispy_forms_filters %}
{% block body %}
<div class="row">
{% block content %}
<div class="row mb-3">
<div class="col-sm-6">
<form action="{% block "action_url" %}{% url 'billing_info' %}{% endblock %}{% if request.GET.next %}?next={{ request.GET.next }}{% endif %}" method="post" class="form">
{% block "form-content" %}
<legend>{% trans "Provide billing data" %}</legend>
<form action="{% url 'billing_info' %}{% if request.GET.next %}?next={{ request.GET.next }}{% endif %}" method="post" class="form">
<legend>{% trans "Provide billing data"|upper %}</legend>
{% csrf_token %}
{{ form|crispy }}
{% if object %}
<a class="btn btn-sm btn-phoenix-danger" href="{% url 'billing_info_delete' %}">{{ _("Delete") }}</a>
<a class="btn btn-sm btn-phoenix-danger" href="{% url 'billing_info_delete' %}"><!--<span class="far fa-trash-alt"></span>--> {{ _("Delete") }}</a>
{% endif %}
<button type="submit" class="btn btn-sm btn-phoenix-primary">
{{ _("Save") }}
</button>
{% endblock %}
</form>
</div>
</div>

View File

@ -1,15 +1,17 @@
{% extends 'base.html' %}
{% load i18n %}
{% block body %}
<h1>Billing data</h1>
{% block content %}
<div class="row mb-3">
<div class="col-sm-6">
<h3>{{ _("Billing data")}}</h3>
<form method="post" action="{% url 'billing_info_delete' %}">
{% csrf_token %}
{% trans "Are you sure to delete billing info?" %}
<p>
<button type="submit" class="btn btn-danger">
<span class="glyphicon glyphicon-trash"></span> Confirm delete
</button>
</form>
<form method="post" action="{% url 'billing_info_delete' %}">
{% csrf_token %}
{% trans "Are you sure to delete billing info?" %}
<p>
<button type="submit" class="btn btn-sm btn-danger">{{ _("Confirm")}}</button>
</form>
</div>
</div>
{% endblock %}

View File

@ -1,7 +1,7 @@
{% extends 'base.html' %}
{% load i18n crispy_forms_filters%}
{% block body %}
{% block content %}
<h3>{% trans "Confirm order" %}</h3>
{% if FREE_ORDER %}
{# Free order is when user downgrades a plan and there is no additional payment it is handle by special a view. #}
@ -63,11 +63,7 @@
{% endif %}
{% endwith %}
<p>
<input type="submit" class="btn btn-primary" value="{% trans "Continue" %}">
<input type="submit" class="btn btn-sm btn-primary" value="{% trans "Continue" %}">
{{ form|crispy }}
{% csrf_token %}
</form>

View File

@ -1,5 +1,5 @@
{% extends 'base.html' %}
{% load i18n %}
{% load i18n custom_filters%}
{% block content %}

View File

@ -5,19 +5,19 @@
{% block extra_js %}
<script>
$(function(){
$('.pricing').click(function(){
$('#pricing_form input#id_plan_pricing').val($(this).attr('pricing_pk'));
$('#pricing_form').submit();
});
$('.pricing').click(function(){
$('#pricing_form input#id_plan_pricing').val($(this).attr('pricing_pk'));
$('#pricing_form').submit();
});
});
</script>
{% endblock %}
{% block body %}
{% block content %}
<form method="post" action="{% url 'order_plan' %}" id="pricing_form">
{% csrf_token %}
{{ form.as_p }}
</form>
{% if userplan.plan.available %}
<ul>
@ -56,5 +56,5 @@
{% endblocktrans %}
{% endif %}
</form>
{% endblock %}

View File

@ -1,4 +1,4 @@
{% load i18n %}
{% load i18n%}
<div class="table-responsive mt-4">
<table class="plan_table table border-top border-translucent fs-9 mb-4">
<thead class="">
@ -48,7 +48,7 @@
<tr>
<th scope="col"></th>
{% for plan in plan_list %}
<th class="planpricing_footer text-center {% if forloop.counter0 == current_userplan_index %}current bg-body-highlight{% endif %}">
<th class="planpricing_footer text-center fw-bold {% if forloop.counter0 == current_userplan_index %}current bg-body-highlight{% endif %}">
{% if plan != userplan.plan and not userplan.is_expired and not userplan.plan.is_free %}
<a href="{% url 'create_order_plan_change' pk=plan.id %}" class="change_plan btn btn-sm btn-outline-primary">{% trans "Change" %}</a>
{% endif %}
@ -68,11 +68,11 @@
<li class="mb-2">
{% if plan_pricing.pricing.url %}<a href="{{ plan_pricing.pricing.url }}" class="info_link pricing text-decoration-none">{% endif %}
<span class="plan_pricing_name font-weight-bold">{{ plan_pricing.pricing.name }}</span>
<small class="plan_pricing_period d-block text-muted">({{ plan_pricing.pricing.period }} {% trans "days" %})</small>
<small class="plan_pricing_period d-block text-muted">({{ plan_pricing.pricing.period }} {% trans "day" %})</small>
{% if plan_pricing.pricing.url %}</a>{% endif %}
<span class="plan_pricing_price d-block font-weight-bold">{{ plan_pricing.price }}&nbsp;{{ CURRENCY }}</span>
{% if plan_pricing.plan == userplan.plan or userplan.is_expired or userplan.plan.is_free %}
<a href="{% url 'create_order_plan' pk=plan_pricing.pk %}" class="buy btn btn-sm btn-phoenix-success">{% trans "Buy" %}</a>
<a href="{% url 'create_order_plan' pk=plan_pricing.pk %}" class="buy btn btn-sm btn-success">{% trans "Buy" %}</a>
{% endif %}
</li>
{% endif %}
@ -109,4 +109,3 @@
</tfoot>
</table>
</div>
<p class="text-right fs-9 text-muted mt-3">* {% trans "Net prices" %}</p>

View File

@ -1,4 +1,4 @@
{% load static %} {% load i18n %}
{% load i18n static custom_filters %}
<!DOCTYPE html>
{% get_current_language as LANGUAGE_CODE %}
<html lang="{{ LANGUAGE_CODE }}"
@ -93,6 +93,7 @@
<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>&nbsp;{% trans 'Your Car Dealership Operations' %}
</h1>
<p class="fs-5 fs-lg-4 fs-xl-4 fw-normal mb-3">{{ _("Because Inventory Needs Order") }}.</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-link fs-8 p-0" href="#feature" role="button">{% trans 'Learn More' %}
@ -138,37 +139,12 @@
<section class="bg-body-emphasis pt-lg-0 pt-xl-8" id="pricing">
<div class="row-small position-relative px-lg-7 px-xxl-3 text-center">
<h4 class="text-primary fw-bolder mb-4">{% trans 'Subscriptions' %}</h4>
<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>
<h2 class="mb-3 text-body-emphasis lh-base">{% trans 'Choose the Plan that Fits Your Needs' %}</h2>
<p class="mb-5">{% trans 'Flexible plans designed to meet the unique needs of every dealership.' %}</p>
<div class="row">
{% for plan in plans %}
<div class="col-md-4">
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title fw-bold">{{plan.name }}</h5>
<p class="card-text fs-9">{{ plan.description }}</p>
{% for plan_pricing in plan.planpricing_set.all %}
{% if plan_pricing.visible %}
<li class="mb-2">
{% if plan_pricing.pricing.url %}<a href="{{ plan_pricing.pricing.url }}" class="info_link pricing text-decoration-none">{% endif %}
<span class="plan_pricing_name fw-bold">{{ plan_pricing.pricing.name }}</span>
<small class="plan_pricing_period d-block text-muted">({{ plan_pricing.pricing.period }} {% trans "days" %})</small>
{% if plan_pricing.pricing.url %}</a>{% endif %}
<span class="plan_pricing_price d-block font-weight-bold">{{ plan_pricing.price }}&nbsp;{{ CURRENCY }}</span>
{% if plan_pricing.plan == userplan.plan or userplan.is_expired or userplan.plan.is_free %}
<a href="{% url 'create_order_plan' pk=plan_pricing.pk %}" class="buy btn btn-sm btn-phoenix-success">{% trans "Buy" %}</a>
{% endif %}
</li>
{% endif %}
{% endfor %}
<a href="{% url 'account_signup' %}" class="btn btn-primary mt-3">{% trans 'Get Started' %}</a>
</div>
</div>
</div>
{% endfor %}
{% include "plans/plan_table.html" %}
</div>
</div>
</section>