| Current Path : /var/www/html/crm/views/dashboard/ |
| Current File : /var/www/html/crm/views/dashboard/general.php |
<?php
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
use app\models\Vendor;
use app\models\Orders;
use yii\helpers\Url;
use app\assets\AmchartsAsset;
use app\assets\DatatableAsset;
use app\models\ParamList;
use app\models\StockIn;
use app\models\Product;
use app\models\StockLog;
AmchartsAsset::register($this);
DatatableAsset::register($this);
$this->title = 'Dashboard';
$this->registerJs("setleftmenu(7,'','');");
$ParamList = new ParamList();
$Product = new Product();
$StockLog = new StockLog();
$vendor_arr = Vendor::find()
->leftJoin('vendor_access', 'vendor.id=vendor_access.vendor_id')
->where(['=', 'vendor_access.user_id', Yii::$app->user->identity->id])
->andwhere(['=', 'vendor.status', '1'])
->orderBy(['name' => SORT_ASC])
->all();
$totalSalesToday = 0;
$totalSalesThisMonth = 0;
$totalSalesLastMonth = 0;
$totalSalesThisYear = 0;
$totalSalesLastYear = 0;
$model = Orders::find()
->where(['=', 'order_status', 'completed'])
->andwhere(['=', 'owner_type', 'vendor'])
->andwhere(['=', 'owner_id', $search_vendor])
->groupBy(['invoice_id'])
->asArray()->all();
if (!empty($model)) {
foreach ($model as $row) {
if (date("Y-m-d", strtotime($row['order_date'])) == date('Y-m-d'))
$totalSalesToday++;
if (date("Y-m", strtotime($row['order_date'])) == date('Y-m'))
$totalSalesThisMonth++;
if (date("Y-m", strtotime($row['order_date'])) == date("Y-m", strtotime("first day of previous month")))
$totalSalesLastMonth++;
if (date("Y", strtotime($row['order_date'])) == date('Y'))
$totalSalesThisYear++;
if (date("Y", strtotime($row['order_date'])) == (date('Y') - 1))
$totalSalesLastYear++;
}
}
function countsales($arr = [], $column, $value, $date) {
$total = 0;
foreach ($arr as $data) {
if (date("Y-m", strtotime($data['order_date'])) == date("Y-m", strtotime($date)) && $data[$column] == $value)
$total++;
}
return $total;
}
function countsales2($arr = [], $date) {
$total = 0;
foreach ($arr as $data) {
if (date("Y-m", strtotime($data['order_date'])) == date("Y-m", strtotime($date)))
$total++;
}
return $total;
}
$courierArr = ['Aramex', 'DHL Express', 'DHL Global Mail', 'UPS', 'Fedex'];
$courierList = '';
if (!empty($courierArr)) {
foreach ($courierArr as $courier) {
$courierList .= '{
"courier": "' . $courier . '",
"thismonthorder":' . countsales($model, 'courier', $courier, date('Y-m-d')) . ',
"lastmonthorder":' . countsales($model, 'courier', $courier, date("Y-m-d", strtotime("first day of previous month"))) . '},';
}
}
$this->registerJs('am4core.ready(function() {
am4core.useTheme(am4themes_animated);
var chart = am4core.create("logisticchart", am4charts.XYChart);
chart.paddingLeft = 0;
chart.paddingTop = 0;
chart.paddingBottom = 0;
chart.data = [' . $courierList . '];
var categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "courier";
categoryAxis.numberFormatter.numberFormat = "#";
categoryAxis.renderer.inversed = true;
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.renderer.minGridDistance = 20;
categoryAxis.renderer.cellStartLocation = 0.1;
categoryAxis.renderer.cellEndLocation = 0.9;
categoryAxis.tooltip.disabled = true;
var label = categoryAxis.renderer.labels.template;
label.wrap = true;
label.maxWidth = 95;
label.align = "left";
chart.cursor = new am4charts.XYCursor();
chart.cursor.lineY.disabled = true;
chart.cursor.lineX.disabled = true;
chart.colors.list = [am4core.color("#FF595E"),am4core.color("#FFCA3A"),];
var valueAxis = chart.xAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.opposite = true;
valueAxis.tooltip.disabled = true;
function createSeries(field, name, startdt, enddt) {
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueX = field;
series.dataFields.categoryY = "courier";
series.name = name;
series.columns.template.height = am4core.percent(100);
series.sequencedInterpolation = true;
series.columns.template.tooltipHTML ="{name}: <b>{valueX}</b>";
series.tooltip.pointerOrientation = "down";
series.tooltip.disabled=true;
var valueLabel = series.bullets.push(new am4charts.LabelBullet());
valueLabel.label.html = "<a href=\'' . Url::to(['orders/index2', 'OrdersSearch[vendor]' => $search_vendor, 'OrdersSearch[data_list]' => ['order_date', 'invoice_id', 'product_id', 'courier']
]) . '&OrdersSearch[start_date]="+startdt+"&OrdersSearch[end_date]="+enddt+"&OrdersSearch[courier][]={categoryY}\' target=\'_blank\'>{valueX}</a>";
valueLabel.label.horizontalCenter = "left";
valueLabel.label.dx = 10;
valueLabel.label.hideOversized = false;
valueLabel.label.truncate = false;
}
createSeries("thismonthorder", "' . date("F") . '", "' . date('Y-m-01') . '", "' . date('Y-m-t') . '");
createSeries("lastmonthorder", "' . date("F", strtotime("first day of previous month")) . '", "' . date("Y-m-d", strtotime("first day of previous month")) . '", "' . date("Y-m-d", strtotime("last day of previous month")) . '");
chart.legend = new am4charts.Legend();
chart.legend.position = "bottom";
chart.legend.paddingBottom = 0;
});');
$marketplace_data = "";
$marketplace_arr = $ParamList->getparamlist(18);
if (!empty($marketplace_arr)) {
foreach ($marketplace_arr as $marketplace_code => $marketplace_name) {
$marketplace_data .= '{"marketplacecode":"' . $marketplace_code . '",
"marketplacename": "' . $marketplace_name . '",
"thismonthorder": ' . countsales($model, 'marketplace', $marketplace_code, date('Y-m-d')) . ',
"lastmonthorder": ' . countsales($model, 'marketplace', $marketplace_code, date("Y-m-d", strtotime("first day of previous month"))) . '
},';
}
}
$this->registerJs('am4core.ready(function() {
//am4core.useTheme(am4themes_kelly);
am4core.useTheme(am4themes_animated);
var chart = am4core.create("marketplacechart", am4charts.XYChart);
chart.paddingLeft = 0;
chart.paddingTop = 0;
chart.paddingBottom = 0;
chart.data = [' . $marketplace_data . '];
var categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "marketplacename";
categoryAxis.numberFormatter.numberFormat = "#";
categoryAxis.renderer.inversed = true;
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.renderer.cellStartLocation = 0.1;
categoryAxis.renderer.cellEndLocation = 0.9;
categoryAxis.tooltip.disabled = true;
var label = categoryAxis.renderer.labels.template;
label.wrap = true;
label.maxWidth = 95;
label.align = "left";
chart.cursor = new am4charts.XYCursor();
chart.cursor.lineY.disabled = true;
chart.cursor.lineX.disabled = true;
chart.colors.list = [am4core.color("#FF00C1"),am4core.color("#9600FF"),];
var valueAxis = chart.xAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.opposite = true;
valueAxis.tooltip.disabled = true;
valueAxis.extraMax = 0.2;
function createSeries(field, name, startdt, enddt) {
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueX = field;
series.dataFields.categoryY = "marketplacename";
series.dataFields.code = "marketplacecode";
series.name = name;
series.columns.template.height = am4core.percent(100);
series.sequencedInterpolation = true;
series.columns.template.tooltipHTML ="{name}: <b>{valueX}</b>";
series.tooltip.pointerOrientation = "down";
series.tooltip.disabled=true;
var valueLabel = series.bullets.push(new am4charts.LabelBullet());
valueLabel.label.html = "<a href=\'' . Url::to(['orders/index2', 'OrdersSearch[vendor]' => $search_vendor, 'OrdersSearch[data_list]' => ['order_date', 'invoice_id', 'product_id', 'marketplace']
]) . '&OrdersSearch[start_date]="+startdt+"&OrdersSearch[end_date]="+enddt+"&OrdersSearch[marketplace][]={categoryY}\' target=\'_blank\'>{valueX}</a>";
valueLabel.label.horizontalCenter = "left";
valueLabel.label.dx = 10;
valueLabel.label.hideOversized = false;
valueLabel.label.truncate = false;
}
createSeries("thismonthorder", "' . date("F") . '","' . date('Y-m-01') . '","' . date('Y-m-t') . '");
createSeries("lastmonthorder", "' . date("F", strtotime("first day of previous month")) . '","' . date("Y-m-d", strtotime("first day of previous month")) . '","' . date("Y-m-d", strtotime("last day of previous month")) . '");
chart.legend = new am4charts.Legend();
chart.legend.position = "bottom";
chart.legend.paddingBottom = 0;
});');
$monthlychartdata = '';
$monthArr = $ParamList->getparamlist(16);
if (!empty($monthArr)) {
foreach ($monthArr as $monthCode => $monthName) {
$startdt_currentyear = date("Y-m-d", strtotime(date("Y") . "-" . $monthCode . "-01"));
$enddt_currentyear = date("Y-m-t", strtotime($startdt_currentyear));
$startdt_lastyear = date("Y-m-d", strtotime((date("Y") - 1) . "-" . $monthCode . "-01"));
$enddt_lastyear = date("Y-m-t", strtotime($startdt_lastyear));
$monthlychartdata .= "{
category: '$monthName',
startdtlastyear:'" . $startdt_lastyear . "',
enddtlastyear:'" . $enddt_lastyear . "',
orderlastyear: " . countsales2($model, $startdt_lastyear) . ",
startdtcurrentyear:'" . $startdt_currentyear . "',
enddtcurrentyear:'" . $enddt_currentyear . "',
ordercurrentyear: " . countsales2($model, $startdt_currentyear) . ",
},";
}
}
$this->registerJs("am4core.ready(function() {
am4core.useTheme(am4themes_animated);
var chart = am4core.create('monthlychart', am4charts.XYChart);
chart.exporting.menu = new am4core.ExportMenu();
chart.paddingLeft = 0;
chart.paddingBottom = 0;
chart.legend = new am4charts.Legend();
chart.legend.position = 'bottom';
var xAxis = chart.xAxes.push(new am4charts.CategoryAxis());
xAxis.dataFields.category = 'category';
xAxis.renderer.cellStartLocation = 0.1;
xAxis.renderer.cellEndLocation = 0.9;
xAxis.renderer.grid.template.location = 0;
xAxis.renderer.minGridDistance = 30;
var yAxis = chart.yAxes.push(new am4charts.ValueAxis());
yAxis.min = 0;
yAxis.extraMax = 0.2;
chart.data = [" . $monthlychartdata . "];
chart.colors.list = [am4core.color('#5d78ff'),am4core.color('#0abb87'),];
var valueAxis2 = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis2.renderer.opposite = true;
valueAxis2.syncWithAxis = yAxis;
valueAxis2.extraMax = 0.2;
createSeries('orderlastyear', '" . (date("Y") - 1) . "');
createSeries('ordercurrentyear', '" . date("Y") . "');
function createSeries(value, name) {
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueY = value;
series.dataFields.categoryX = 'category';
if(value==='ordercurrentyear'){
series.dataFields.startdt = 'startdtcurrentyear';
series.dataFields.endtdt = 'enddtcurrentyear';
}
if(value==='orderlastyear'){
series.dataFields.startdt = 'startdtlastyear';
series.dataFields.endtdt = 'enddtlastyear';
}
series.name = name+' orders';
var valueLabel = series.bullets.push(new am4charts.LabelBullet());
valueLabel.label.html = '<a href=\"" . Url::to(['orders/index2', 'OrdersSearch[vendor]' => $search_vendor, 'OrdersSearch[data_list]' => ['order_date', 'invoice_id', 'product_id', 'marketplace']
]) . "&OrdersSearch[start_date]={startdt}&OrdersSearch[end_date]={endtdt}\" target=\"_blank\">{valueY}</a>';
valueLabel.label.dy = -10;
valueLabel.label.hideOversized = false;
valueLabel.label.truncate = false;
return series;
}
}); ");
$this->registerCss("table-dashboard2 thead, .table-dashboard thead, .table-dashboard3 thead {display:none;}
table.dataTable.no-footer {border-bottom: 0;}");
?>
<div class="kt-subheader kt-grid__item" id="kt_subheader">
<div class="kt-container kt-container--fluid ">
<div class="kt-subheader__main">
<div class="kt-subheader__breadcrumbs">
<span class="kt-subheader__breadcrumbs-separator"></span><span class="mr-2">Home</span>
<span class="kt-subheader__breadcrumbs-separator"></span><span class="mr-2"><?= $this->title; ?></span>
</div>
</div>
</div>
</div>
<div class="kt-container kt-container--fluid kt-grid__item kt-grid__item--fluid">
<div class="row">
<div class="col-3">
<div class="kt-portlet">
<div class="kt-portlet__body">
<form autocomplete="off">
<?=
Html::dropDownList('search_vendor', $search_vendor, ArrayHelper::map($vendor_arr, 'id', 'name'), [
'prompt' => '- Select vendor -',
'data-live-search' => 'true',
'class' => 'form-control kt-selectpicker',
'onchange' => 'javascript:window.location.href = "index.php?r=dashboard/index&search_vendor="+this.value;',
'id' => 'search_vendor']);
?>
</form>
</div></div>
<div class="kt-portlet">
<div class="kt-portlet__body kt-portlet__body--fit">
<div class="kt-widget1">
<div class="kt-widget1__item">
<div class="kt-widget1__info">
<h3 class="kt-widget1__title">Order for the day</h3>
</div>
<span class="kt-widget1__number kt-font-brand">
<a href="<?=
Url::to(['orders/index2',
'OrdersSearch[start_date]' => date('Y-m-d'),
'OrdersSearch[end_date]' => date('Y-m-d'),
'OrdersSearch[vendor]' => $search_vendor,
'OrdersSearch[data_list]' => ['order_date', 'invoice_id', 'product_id']
])
?>">
<?= number_format($totalSalesToday); ?>
</a>
</span>
</div>
</div>
</div>
</div>
<div class="kt-portlet">
<div class="kt-portlet__body kt-portlet__body--fit">
<div class="kt-widget1">
<div class="kt-widget1__item">
<div class="kt-widget1__info">
<h3 class="kt-widget1__title">Total order this month</h3>
<span class="kt-widget1__desc">
Total order last month :
<a href="<?=
Url::to(['orders/index2',
'OrdersSearch[start_date]' => date("Y-m-d", strtotime("first day of previous month")),
'OrdersSearch[end_date]' => date("Y-m-d", strtotime("last day of previous month")),
'OrdersSearch[vendor]' => $search_vendor,
'OrdersSearch[data_list]' => ['order_date', 'invoice_id', 'product_id']
])
?>">
<?= number_format($totalSalesLastMonth); ?>
</a>
</span>
</div>
<span class="kt-widget1__number kt-font-brand">
<a href="<?=
Url::to(['orders/index2',
'OrdersSearch[start_date]' => date('Y-m-01'),
'OrdersSearch[end_date]' => date('Y-m-d'),
'OrdersSearch[vendor]' => $search_vendor,
'OrdersSearch[data_list]' => ['order_date', 'invoice_id', 'product_id']
])
?>">
<?= number_format($totalSalesThisMonth); ?>
</a>
</span>
</div>
</div>
</div>
</div>
<div class="kt-portlet">
<div class="kt-portlet__body kt-portlet__body--fit">
<div class="kt-widget1">
<div class="kt-widget1__item">
<div class="kt-widget1__info">
<h3 class="kt-widget1__title">Total order this year</h3>
<span class="kt-widget1__desc">
Total order last year :
<a href="<?=
Url::to(['orders/index2',
'OrdersSearch[start_date]' => (date('Y') - 1) . '-01-01',
'OrdersSearch[end_date]' => (date('Y') - 1) . '-12-31',
'OrdersSearch[vendor]' => $search_vendor,
'OrdersSearch[data_list]' => ['order_date', 'invoice_id', 'product_id']
])
?>">
<?= number_format($totalSalesLastYear); ?>
</a>
</span>
</div>
<span class="kt-widget1__number kt-font-brand">
<a href="<?=
Url::to(['orders/index2',
'OrdersSearch[start_date]' => date('Y-01-01'),
'OrdersSearch[end_date]' => date('Y-12-31'),
'OrdersSearch[vendor]' => $search_vendor,
'OrdersSearch[data_list]' => ['order_date', 'invoice_id', 'product_id']
])
?>">
<?= number_format($totalSalesThisYear); ?>
</a>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-9">
<div class="kt-portlet kt-portlet--height-fluid">
<div class="kt-portlet__body kt-portlet__body--fit">
<div class="kt-widget14">
<div class="kt-widget14__header">
<h3 class="kt-widget14__title">Monthly Order and Sales Volume Chart</h3>
<!--<span class="kt-widget14__desc">Click on the number of orders to see details</span>-->
</div>
<div class="kt-widget14__content"><div id="monthlychart" style="height: 300px;width:100%;"></div></div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-4">
<div class="kt-portlet">
<div class="kt-portlet__body kt-portlet__body--fit">
<div class="kt-widget14">
<div class="kt-widget14__header pb-0">
<div class="row">
<div class="col-9">
<h3 class="kt-widget14__title">International Shipment By Courier</h3>
<!--<span class="kt-widget14__desc">Click on the number of orders to see details</span>-->
</div>
<div class="col-3"></div>
</div>
</div>
<div class="kt-widget14__content"><div id="logisticchart" style="height: 300px;width:100%;"></div></div>
</div>
</div>
</div>
<div class="kt-portlet">
<div class="kt-portlet__body kt-portlet__body--fit">
<div class="kt-widget14">
<div class="kt-widget14__header pb-0">
<h3 class="kt-widget14__title">Shipment By Marketplace</h3>
<!--<span class="kt-widget14__desc">Click on the number of orders to see details</span>-->
</div>
<div class="kt-widget14__content"><div id="marketplacechart" style="height: 300px;width:100%;"></div></div>
</div>
</div>
</div>
</div>
<div class="col-4">
<div class="kt-portlet kt-portlet--height-fluid">
<div class="kt-portlet__head" style="border:0;">
<div class="kt-portlet__head-label">
<h3 class="kt-portlet__head-title">
Near Expiry Stock
<small>stock will expired within 3 months</small>
</h3>
</div>
</div>
<div class="kt-portlet__body pt-0 pb-1">
<div class="kt-portlet__content">
<div class="kt-widget3">
<table class="table m-0 p-0 table-borderless table-dashboard">
<tbody>
<?php
$modelStockIn = StockIn::find()
->where(['=', 'owner_type', 'vendor'])
->andwhere(['=', 'owner_id', $search_vendor])
->andwhere(['=', 'expire_status', 1])
->andwhere(['<', 'DATE(expire_dt)', date('Y-m-d', strtotime("+3 months", strtotime(date('Y-m-d'))))])
->andwhere(['>', 'DATE(expire_dt)', date('Y-m-d')])
->andwhere(['=', 'soldout', '0'])->orderBy(['expire_dt' => SORT_ASC])->all();
if (!empty($modelStockIn)) {
foreach ($modelStockIn as $rowStockIn) {
$stockInQty = $rowStockIn->quantity;
$datediff = strtotime($rowStockIn['expire_dt']) - time();
$daysLeft = round($datediff / (60 * 60 * 24));
echo '<tr>
<td class="p-0 m-0">
<div class="kt-widget3__item">
<div class="kt-widget3__header">
<div class="kt-widget3__user-img">
<img class="kt-widget3__img" src="images/expired.png" alt="">
</div>
<div class="kt-widget3__info">
<span class="kt-widget3__username">
' . $Product->getname($rowStockIn->product_id) . '
</span><br>
<div class="kt-widget3__time">
Expired on <span class="kt-font-warning">' . date("d/m/Y", strtotime($rowStockIn['expire_dt'])) . '</span>
(' . $daysLeft . ' days left)
</div>
<div class="kt-widget3__time"></div>
</div>
<span class="kt-widget3__status kt-font-info">
<button type="button" onclick="updatesoldout(' . $rowStockIn->id . ')" class="btn btn-outline-warning btn-elevate btn-circle btn-icon btn-sm" title="Update to sold out">
<i class="fas fa-pen"></i>
</button>
</span>
</div>
</div>
</td>
</tr>';
}
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="col-4">
<div class="kt-portlet kt-portlet--height-fluid">
<div class="kt-portlet__head" style="border:0;">
<div class="kt-portlet__head-label">
<h3 class="kt-portlet__head-title">
Safety Stock Alert
<small>List of stock that almost sold out!</small>
</h3>
</div>
</div>
<div class="kt-portlet__body pt-0 pb-1">
<div class="kt-portlet__content">
<div class="kt-widget3">
<table class="table m-0 p-0 table-borderless table-dashboard">
<tbody>
<?php
$modelProduct = Product::find()
->where(['=', 'vendor_id', $search_vendor])
->andwhere(['=', 'status', '1'])
->andwhere(['!=', 'stock_alert', '0'])
->orderBy(['name' => SORT_ASC])
->all();
if (!empty($modelProduct)) {
foreach ($modelProduct as $rowProduct) {
$stock_alert = $rowProduct->stock_alert;
$current_balance = $StockLog->balancestock($rowProduct->id);
//$current_balance = $StockLog->balancestockbyowner($rowProduct->id, 'vendor', $search_vendor, '', '');
if ($current_balance < $stock_alert) {
echo '<tr>
<td class="p-0 m-0">
<div class="kt-widget3__item">
<div class="kt-widget3__header">
<div class="kt-widget3__user-img"><img class="kt-widget3__img" src="images/lowstock.png" alt=""></div>
<div class="kt-widget3__info">
<span class="kt-widget3__username">' . $rowProduct->name . '</span><br>
<div class="kt-widget3__time kt-font-danger">
Current balance : ' . $current_balance . '
</div>
</div>
<span class="kt-widget3__status kt-font-info"></span>
</div>
</div>
</td>
</tr>';
}
}
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php $this->registerJs("$('.table-dashboard').DataTable({
language: {paginate: {next: '<i class=\"fa fa-angle-right\"></i>',previous: '<i class=\"fa fa-angle-left\"></i>'}},
'bLengthChange': false,
'order': [[0,'desc']],
'pageLength': 10,
'searching': false,
'columnDefs': [{'orderable': false, 'targets': 0}],
'language': {
'emptyTable': 'No record found',
'paginate': {
'previous': '<i class=\"fas fa-arrow-left\"></i>',
'next': '<i class=\"fas fa-arrow-right\"></i>'
}
}
});"); ?>
<script>
function updatesoldout(id) {
Swal.fire({
title: 'Are you sure to update this stock to sold out?',
text: "You won't be able to revert this!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, update it!'
}).then((result) => {
if (result.value) {
$.ajax({
url: "index.php?r=stockin/updatesoldout",
method: "POST",
data: {"id": id},
success: function (response) {
if (response === 'success') {
swal.fire({
position: 'center-center',
type: 'success',
title: 'Stock has been updated',
showConfirmButton: false,
timer: 1500,
}).then(function (result) {
location.reload();
});
}
},
});
}
}
);
}
</script>