453 lines
27 KiB
HTML
453 lines
27 KiB
HTML
{% load i18n static custom_filters django_ledger %}
|
|
{% block content %}
|
|
<div class="row justify-content-between">
|
|
<div class="col-12 col-lg-6">
|
|
<div class="row g-2">
|
|
<h3 class="fs-4 fs-md-4 fs-xl-4 fw-black mb-4">
|
|
<span class="text-gradient-info me-3">{{ staff }}</span>
|
|
</h3>
|
|
<div class="card mb-3">
|
|
<div class="bg-holder"
|
|
style="background-image:url({% static 'images/bg/38.png' %});
|
|
background-position:left bottom;
|
|
background-size:auto"></div>
|
|
<div class="card-body d-flex justify-content-between position-relative">
|
|
<div class="col-sm-7 col-md-8 col-xxl-8 mb-md-3 mb-lg-0">
|
|
<h3 class="mb-3">{{ _("Inventory by Status") }}</h3>
|
|
<div class="row g-0">
|
|
<div class="col-6 col-xl-4">
|
|
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100 border-1 border-bottom border-end border-translucent">
|
|
<div class="d-flex align-items-center mb-1">
|
|
<span class="fa-solid fa-square fs-11 me-2 text-success"
|
|
data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Available") }}</span>
|
|
</div>
|
|
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ available_cars }}</h3>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-xl-4">
|
|
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100 border-1 border-bottom border-end-md-0 border-end-xl border-translucent">
|
|
<div class="d-flex align-items-center mb-1">
|
|
<span class="fa-solid fa-square fs-11 me-2 text-warning"
|
|
data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Sold") }}</span>
|
|
</div>
|
|
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ sold_cars }}</h3>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-xl-4">
|
|
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100 border-1 border-bottom border-end border-end-md border-end-xl-0 border-translucent">
|
|
<div class="d-flex align-items-center mb-1">
|
|
<span class="fa-solid fa-square fs-11 me-2 text-danger"
|
|
data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Reserved") }}</span>
|
|
</div>
|
|
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ reserved_cars }}</h3>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-xl-4">
|
|
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100 border-1 border-end-xl border-bottom border-bottom-xl-0 border-translucent">
|
|
<div class="d-flex align-items-center mb-1">
|
|
<span class="fa-solid fa-square fs-11 me-2 text-primary"
|
|
data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Transfer") }}</span>
|
|
</div>
|
|
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ transfer_cars }}</h3>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-xl-4">
|
|
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100 border-1 border-end border-translucent">
|
|
<div class="d-flex align-items-center mb-1">
|
|
<span class="fa-solid fa-square fs-11 me-2 text-warning-light"
|
|
data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Hold") }}</span>
|
|
</div>
|
|
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ hold_cars }}</h3>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-xl-4">
|
|
<div class="d-flex flex-column flex-center align-items-sm-start flex-md-row justify-content-md-between flex-xxl-column p-3 ps-sm-3 ps-md-4 p-md-3 h-100">
|
|
<div class="d-flex align-items-center mb-1">
|
|
<span class="fa-solid fa-square fs-11 me-2 text-secondary-dark"
|
|
data-fa-transform="up-2"></span><span class="mb-0 fs-9 text-body">{{ _("Damaged") }}</span>
|
|
</div>
|
|
<h3 class="fw-semibold ms-xl-3 ms-xxl-0 pe-md-2 pe-xxl-0 mb-0 mb-sm-3">{{ damaged_cars }}</h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-5 col-md-4 col-xxl-4 my-3 my-sm-0">
|
|
<div class="position-relative d-flex flex-center mb-sm-4 mb-xl-0 echart-cars-by-status-container mt-sm-7 mt-lg-4 mt-xl-0">
|
|
<div id="echart-cars-by-status" style="min-height:245px;width:100%"></div>
|
|
<div class="position-absolute rounded-circle bg-primary-subtle top-50 start-50 translate-middle d-flex flex-center"
|
|
style="height:100px;
|
|
width:100px">
|
|
<h3 class="mb-0 text-primary-dark fw-bolder" data-label="data-label"></h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row g-2">
|
|
<div class="col-12 mb-8">
|
|
<div class="mb-3">
|
|
<h3>{{ _("New Leads and Customers") }}</h3>
|
|
<p class="text-body-tertiary mb-0">{{ _("Payment received across all channels") }}</p>
|
|
</div>
|
|
<div class="row g-6">
|
|
<div class="col-xl-6 mb-2 mb-sm-0">
|
|
<div class="d-flex align-items-center">
|
|
<span class="me-2 text-info"
|
|
data-feather="users"
|
|
style="min-height:24px;
|
|
width:24px"></span>
|
|
<h4 class="text-body-tertiary mb-0">
|
|
{{ _("New Customers") }} :
|
|
<span class="text-body-emphasis">42</span>
|
|
</h4>
|
|
<span class="badge badge-phoenix fs-10 badge-phoenix-success d-inline-flex align-items-center ms-2">
|
|
<span class="badge-label d-inline-block lh-base">+24.5%</span>
|
|
<span class="ms-1 fa-solid fa-caret-up d-inline-block lh-1"></span>
|
|
</span>
|
|
</div>
|
|
<div class="pb-0 pt-4">
|
|
<div class="echarts-new-users" style="min-height:110px;width:100%;"></div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="d-flex align-items-center">
|
|
<span class="me-2 text-primary"
|
|
data-feather="zap"
|
|
style="height:24px;
|
|
width:24px"></span>
|
|
<h4 class="text-body-tertiary mb-0">
|
|
{{ _("New Leads") }} :<span class="text-body-emphasis">45</span>
|
|
</h4>
|
|
<span class="badge badge-phoenix fs-10 badge-phoenix-success d-inline-flex align-items-center ms-2">
|
|
<span class="badge-label d-inline-block lh-base">+30.5%</span>
|
|
<span class="ms-1 fa-solid fa-caret-up d-inline-block lh-1"></span>
|
|
</span>
|
|
</div>
|
|
<div class="pb-0 pt-4">
|
|
<div class="echarts-new-leads" style="min-height:110px;width:100%;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-lg-6">
|
|
<div class="row g-3 pe-xxl-3">
|
|
<div class="col-12 col-xl-6 col-xxl-12">
|
|
<div class="row">
|
|
<div class="col-6 col-xl-12 col-xxl-6 border-bottom border-end border-end-xl-0 border-end-xxl pb-4 pt-4 pt-xl-0 pt-xxl-4 pe-4 pe-sm-5 pe-xl-0 pe-xxl-5">
|
|
<h4 class="text-body mb-4">{% trans 'inventory'|upper %}</h4>
|
|
<div class="d-md-flex flex-between-center">
|
|
<div id="car-chart-by-make"
|
|
class="order-sm-0 order-md-1"
|
|
style="height:64px;
|
|
width: 128px"></div>
|
|
<div class="mt-4 mt-md-0">
|
|
<h1 class="text-body-highlight mb-2">{{ total_cars }}</h1>
|
|
<span class="badge badge-phoenix badge-phoenix-primary me-2 fs-10"> <span class="fs-10 text-body-secondary me-1">{{ _("As of") }}</span>{% now "SHORT_DATETIME_FORMAT" %}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-xl-12 col-xxl-6 border-bottom py-4 ps-4 ps-sm-5 ps-xl-0 ps-xxl-5">
|
|
<h4 class="text-body mb-4">{% trans 'inventory value'|upper %}</h4>
|
|
<div class="d-md-flex flex-between-center">
|
|
<div class="d-md-flex align-items-center gap-2 order-sm-0 order-md-1 fa-2x align-items-center">
|
|
<i class="fas fa-money-check-alt fs-4 text-success-light dark__text-opacity-75"></i>
|
|
<div class="d-flex d-md-block gap-2 align-items-center mt-1 mt-md-0">
|
|
<p class="fs-9 mb-0 mb-md-2 text-body-tertiary text-nowrap"></p>
|
|
<h4 class="text-body-highlight mb-0"></h4>
|
|
</div>
|
|
</div>
|
|
<div class="mt-3 mt-md-0">
|
|
<h3 class="text-body-highlight mb-2">
|
|
{{ total_selling_price|currency_format }} <span class="icon-saudi_riyal"></span>
|
|
</h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-xl-12 col-xxl-6 border-bottom-xl border-bottom-xxl-0 border-end border-end-xl-0 border-end-xxl py-4 pe-4 pe-sm-5 pe-xl-0 pe-xxl-5">
|
|
<h4 class="text-body mb-4">{% trans "Profits"|upper %}</h4>
|
|
<div class="d-md-flex flex-between-center">
|
|
<div class="d-md-flex align-items-center gap-2 order-sm-0 order-md-1">
|
|
<span class="fa-solid fa-money-bill-trend-up fs-4 text-warning-light dark__text-opacity-75"
|
|
data-bs-theme="light"></span>
|
|
<div class="d-flex d-md-block gap-2 align-items-center mt-1 mt-md-0">
|
|
<p class="fs-9 mb-0 mb-md-2 text-body-tertiary text-nowrap"></p>
|
|
<h4 class="text-body-highlight mb-0"></h4>
|
|
</div>
|
|
</div>
|
|
<div class="mt-3 mt-md-0">
|
|
<h3 class="text-body-highlight mb-2">
|
|
{{ total_profit|currency_format }} <span class="icon-saudi_riyal"></span>
|
|
</h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-xl-12 col-xxl-6 py-4 ps-4 ps-sm-5 ps-xl-0 ps-xxl-5">
|
|
<h5 class="text-body mb-4">{{ _("Canceled Invoices") }}</h5>
|
|
<div class="d-md-flex flex-between-center">
|
|
<div class="chart-cancel-booking order-sm-0 order-md-1"
|
|
style="height:54px;
|
|
width:78px"></div>
|
|
<div class="mt-3 mt-md-0">
|
|
<h3 class="text-body-highlight mb-2">120.00</h3>
|
|
<span class="badge badge-phoenix badge-phoenix-danger me-2 fs-10"> <span class="fa-solid fa-plus me-1"></span>5.76%</span>
|
|
<span class="fs-9 text-body-secondary d-block d-sm-inline mt-1">{{ _("From last month") }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-xl-6 col-xxl-12 mb-3">
|
|
<div class="card h-100">
|
|
<div class="card-header pb-3">
|
|
<div class="row justify-content-between g-3">
|
|
<div class="col-auto">
|
|
<h3 class="text-body-highlight">{{ _("Gross Profit") }}</h3>
|
|
<p class="mb-0">Annual income according to the board</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row align-items-center h-100 gy-5">
|
|
<div class="col-12 col-md-auto col-xl-12 col-xxl-auto order-md-1 order-xl-0 order-xxl-1 px-md-8 px-xl-6">
|
|
<div class="echart-gross-profit mx-auto mt-3 mt-md-0 mt-xl-3 mt-xxl-0"
|
|
style="width: 250px;
|
|
height: 250px"></div>
|
|
</div>
|
|
<div class="col-12 col-md-auto col-xl-12 col-xxl-auto flex-1 h-md-100">
|
|
<div class="d-flex flex-column justify-content-between h-md-100 h-xl-auto h-xxl-100">
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<div class="d-flex gap-2">
|
|
<div class="bullet-item bg-primary-light" data-bs-theme="light"></div>
|
|
<div>
|
|
<h6 class="mb-0 text-body fw-semibold mb-2">Flight</h6>
|
|
<h5 class="mb-0 text-body">$162,791,400</h5>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex align-items-center gap-2 text-primary">
|
|
<span class="fw-bold"
|
|
data-feather="trending-up"
|
|
style="width: 24px;
|
|
height: 24px"></span>
|
|
<p class="mb-0 fw-bold">15.50%</p>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<div class="d-flex gap-2">
|
|
<div class="bullet-item bg-info-light" data-bs-theme="light"></div>
|
|
<div>
|
|
<h6 class="mb-0 text-body fw-semibold mb-2">Flight (Package)</h6>
|
|
<h5 class="mb-0 text-body">$135,659,500</h5>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex align-items-center gap-2 text-danger">
|
|
<span class="fw-bold"
|
|
data-feather="trending-down"
|
|
style="width: 24px;
|
|
height: 24px"></span>
|
|
<p class="mb-0 fw-bold">11.09%</p>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<div class="d-flex gap-2">
|
|
<div class="bullet-item bg-warning-light" data-bs-theme="light"></div>
|
|
<div>
|
|
<h6 class="mb-0 text-body fw-semibold mb-2">Hotel</h6>
|
|
<h5 class="mb-0 text-body">$271,319,000</h5>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex align-items-center gap-2 text-warning">
|
|
<span class="fw-bold"
|
|
data-feather="trending-up"
|
|
style="width: 24px;
|
|
height: 24px"></span>
|
|
<p class="mb-0 fw-bold">29.98%</p>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<div class="d-flex align-items-center justify-content-between">
|
|
<div class="d-flex gap-2">
|
|
<div class="bullet-item bg-success-light" data-bs-theme="light"></div>
|
|
<div>
|
|
<h6 class="mb-0 text-body fw-semibold mb-2">Hotel (Package)</h6>
|
|
<h5 class="mb-0 text-body">$162,791,400</h5>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex align-items-center gap-2 text-success">
|
|
<span class="fw-bold"
|
|
data-feather="trending-up"
|
|
style="width: 24px;
|
|
height: 24px"></span>
|
|
<p class="mb-0 fw-bold">03.90%</p>
|
|
</div>
|
|
</div>
|
|
<hr class="d-none" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
/* Car Chart By Make */
|
|
const getColor = (name, dom = document.documentElement) => {
|
|
return getComputedStyle(dom).getPropertyValue(`--phoenix-${name}`).trim();
|
|
};
|
|
const handleTooltipPosition = ([pos, , dom, , size]) => {
|
|
// only for mobile device
|
|
if (window.innerWidth <= 540) {
|
|
const tooltipHeight = dom.offsetHeight;
|
|
const obj = {top: pos[1] - tooltipHeight - 20};
|
|
obj[pos[0] < size.viewSize[0] / 2 ? 'left' : 'right'] = 5;
|
|
return obj;
|
|
}
|
|
return null; // else default behaviour
|
|
};
|
|
|
|
|
|
const carData = {{ car|safe }}
|
|
const carNames = carData.map(item => item.id_car_make__name);
|
|
const carCounts = carData.map(item => item.count);
|
|
|
|
const car_chart = echarts.init(document.getElementById('car-chart-by-make'));
|
|
option = {
|
|
color: getColor("danger"),
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
position: (...params) => handleTooltipPosition(params),
|
|
padding: [7, 10],
|
|
axisPointer: {
|
|
type: 'none'
|
|
},
|
|
},
|
|
extraCssText: 'z-index: 1000',
|
|
responsive: true,
|
|
xAxis: [
|
|
{
|
|
type: 'category',
|
|
boundaryGap: false,
|
|
data: carNames,
|
|
axisLine: {
|
|
show: true,
|
|
lineStyle: {color: getColor('secondary-bg')}
|
|
},
|
|
axisTick: {
|
|
show: false
|
|
},
|
|
}
|
|
],
|
|
yAxis: [
|
|
{
|
|
show: false,
|
|
type: 'value',
|
|
}
|
|
],
|
|
series: [
|
|
{
|
|
type: 'bar',
|
|
barWidth: 3,
|
|
backgroundStyle: {
|
|
borderRadius: [0.5, 0.5, 0, 0],
|
|
},
|
|
data: carCounts
|
|
},
|
|
],
|
|
grid: {
|
|
bottom: 0,
|
|
top: 0,
|
|
left: 10,
|
|
right: 10,
|
|
containLabel: false
|
|
}
|
|
};
|
|
|
|
car_chart.setOption(option);
|
|
|
|
/* Car Status Chart */
|
|
const chartElContainer = document.querySelector('.echart-cars-by-status-container');
|
|
const car_status = echarts.init(document.getElementById('echart-cars-by-status'));
|
|
const chartLabel = chartElContainer.querySelector('[data-label]');
|
|
const data = [
|
|
{value: {{available_cars}}, name: '{{ _("Available") }}'},
|
|
{value: {{sold_cars}}, name: '{{ _("Sold")}}'},
|
|
{value: {{reserved_cars}}, name: '{{ _("Reserved") }}'},
|
|
{value: {{transfer_cars}}, name: '{{ _("Transfer") }}'},
|
|
{value: {{hold_cars}}, name: '{{ _("Hold") }}'},
|
|
{value: {{damaged_cars}}, name: '{{ _("Damaged") }}'}
|
|
];
|
|
const totalCars = data.reduce((acc, val) => val.value + acc, 0);
|
|
if (chartLabel) {
|
|
chartLabel.innerHTML = totalCars;
|
|
}
|
|
option = {
|
|
color: [
|
|
getColor('success'),
|
|
getColor('warning'),
|
|
getColor('danger'),
|
|
getColor('primary'),
|
|
getColor('warning-lighter'),
|
|
getColor('secondary-dark')
|
|
],
|
|
tooltip: {
|
|
trigger: 'item',
|
|
padding: [7, 10],
|
|
backgroundColor: getColor('body-highlight-bg'),
|
|
borderColor: getColor('border-color'),
|
|
textStyle: {color: getColor('light-text-emphasis')},
|
|
borderWidth: 1,
|
|
transitionDuration: 0,
|
|
extraCssText: 'z-index: 1000'
|
|
},
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
|
|
series: [
|
|
{
|
|
name: '',
|
|
type: 'pie',
|
|
radius: ['55%', '90%'],
|
|
startAngle: 90,
|
|
avoidLabelOverlap: false,
|
|
itemStyle: {
|
|
borderColor: getColor('body-bg'),
|
|
borderWidth: 3
|
|
},
|
|
|
|
label: {
|
|
show: false
|
|
},
|
|
emphasis: {
|
|
label: {
|
|
show: false
|
|
}
|
|
},
|
|
labelLine: {
|
|
show: false
|
|
},
|
|
data
|
|
}
|
|
],
|
|
grid: {
|
|
bottom: 0,
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
containLabel: false
|
|
}
|
|
};
|
|
car_status.setOption(option);
|
|
|
|
|
|
|
|
});
|
|
</script>
|
|
{% endblock %}
|