Complete Domain-Driven Architecture migration: - Phase 1-4: Transport, ProductSet, Coupon, Shop, Search, Basket, ProductCustomField, Category, ProductAttribute, Promotion - Phase 5: Order (~562 lines) + Product (~952 lines) - ~20 Product methods migrated to ProductRepository - Apilo sync migrated to OrderAdminService - Production hotfixes: stale Redis cache (prices 0.00), unqualified Product:: refs in LayoutEngine, object->array template conversion - AttributeRepository::getAttributeValueById() Redis cache added Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
253 lines
9.1 KiB
PHP
253 lines
9.1 KiB
PHP
<div class="dashboard-summary">
|
|
<div class="panel panel-tile text-center">
|
|
<div class="panel-body bg-primary">
|
|
<h1 class="fs35 mbn"><?= number_format( $this -> summary_sales, 2, '.', ' ' );?> zł</h1>
|
|
<h6 class="text-white">wartość zamówień</h6>
|
|
</div>
|
|
</div>
|
|
<div class="panel panel-tile text-center">
|
|
<div class="panel-body bg-success">
|
|
<h1 class="fs35 mbn"><?= $this -> summary_orders;?></h1>
|
|
<h6 class="text-white">ilość zamówień</h6>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="dashboard-content">
|
|
<div class="dashboard-title">
|
|
Ostatnie zamówienia
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">Data zamówienia</th>
|
|
<th scope="col">Nr zamówienia</th>
|
|
<th scope="col">Status</th>
|
|
<th scope="col" class="text-right">Wartość</th>
|
|
<th scope="col">Klient</th>
|
|
<th scope="col">Email</th>
|
|
<th scope="col">Telefon</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<? if ( \Shared\Helpers\Helpers::is_array_fix( $this -> last_orders ) ): foreach ( $this -> last_orders as $order ):?>
|
|
<tr class="status-<?= $order['status'];?>">
|
|
<td><?= date( "Y-m-d H:i", strtotime( $order['date_order'] ) );?></td>
|
|
<td>
|
|
<a href="/admin/shop_order/order_details/order_id=<?= $order['id'];?>"><?= $order['number'];?></a>
|
|
</td>
|
|
<td class="order-status"><?= $this -> order_statuses[ $order['status'] ];?></td>
|
|
<td class="text-right"><?= $order['summary'];?> zł</td>
|
|
<td><?= $order['client'];?></td>
|
|
<td><?= $order['client_email'];?></td>
|
|
<td><?= $order['client_phone'];?></td>
|
|
</tr>
|
|
<? endforeach; endif;?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="dashboard-content">
|
|
<div class="dashboard-title">
|
|
Sprzedaż z ostatnich 24 m-cy
|
|
</div>
|
|
<div id="sale"></div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="dashboard-content">
|
|
<div class="dashboard-title">
|
|
Sprzedaż wg godzin i dni
|
|
</div>
|
|
<?
|
|
$min = 999999999999999999;
|
|
for ( $i = 0; $i < 24; $i++ )
|
|
{
|
|
for ( $j = 1; $j < 8; $j++ )
|
|
{
|
|
if ( $max < $this -> sales_grid[$j][$i] )
|
|
$max = $this -> sales_grid[$j][$i];
|
|
|
|
if ( $min > (int) $this -> sales_grid[$j][$i] )
|
|
$min = (int) $this -> sales_grid[$j][$i];
|
|
}
|
|
}
|
|
|
|
if ( $max == 0 )
|
|
$max = 1;
|
|
?>
|
|
<div class="table-responsive">
|
|
<table class="sales-grid table">
|
|
<? for ( $i = 0; $i < 24; $i++ ):?>
|
|
<tr>
|
|
<td><?= $i;?></td>
|
|
<? for ( $j = 1; $j < 8; $j++ ):?>
|
|
<td style="background: rgba( 10, 92, 150, <?= (int) $this -> sales_grid[$j][$i] * 100 / $max / 100;?> ); <? if ( (int) $this -> sales_grid[$j][$i] * 100 / $max > 50 ):?> color: #FFF;<? endif;?>"><?= (int) $this -> sales_grid[$j][$i];?></td>
|
|
<? endfor;?>
|
|
</tr>
|
|
<? endfor;?>
|
|
<tr>
|
|
<td></td>
|
|
<td>poniedziałek | <? $sum = 0; for ( $i = 0; $i < 24; $i++ ): $sum += $this -> sales_grid[ 1 ][$i]; endfor; echo $sum;?></td>
|
|
<td>wtorek | <? $sum = 0; for ( $i = 0; $i < 24; $i++ ): $sum += $this -> sales_grid[ 2 ][$i]; endfor; echo $sum;?></td>
|
|
<td>środa | <? $sum = 0; for ( $i = 0; $i < 24; $i++ ): $sum += $this -> sales_grid[ 3 ][$i]; endfor; echo $sum;?></td>
|
|
<td>czwartek | <? $sum = 0; for ( $i = 0; $i < 24; $i++ ): $sum += $this -> sales_grid[ 4 ][$i]; endfor; echo $sum;?></td>
|
|
<td>piątek | <? $sum = 0; for ( $i = 0; $i < 24; $i++ ): $sum += $this -> sales_grid[ 5 ][$i]; endfor; echo $sum;?></td>
|
|
<td>sobota | <? $sum = 0; for ( $i = 0; $i < 24; $i++ ): $sum += $this -> sales_grid[ 6 ][$i]; endfor; echo $sum;?></td>
|
|
<td>niedziela | <? $sum = 0; for ( $i = 0; $i < 24; $i++ ): $sum += $this -> sales_grid[ 7 ][$i]; endfor; echo $sum;?></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-xl-6">
|
|
<div class="dashboard-content">
|
|
<div class="dashboard-title">
|
|
Najczęściej kupowane produkty
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table table-hover dashboard-products">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">Zdjęcie</th>
|
|
<th scope="col">Nazwa</th>
|
|
<th scope="col" class="text-center">Ilość</th>
|
|
<th scope="col" class="text-right">Wartość</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<? if ( \Shared\Helpers\Helpers::is_array_fix( $this -> best_sales_products ) ): foreach ( $this -> best_sales_products as $row ):?>
|
|
<? $product = (new \Domain\Product\ProductRepository($GLOBALS['mdb']))->findCached( (int)$row['parent_product_id'], ( new \Domain\Languages\LanguagesRepository( $GLOBALS['mdb'] ) )->defaultLanguage() );?>
|
|
<tr>
|
|
<td>
|
|
<?
|
|
$img = '../' . $product['images'][0]['src'];
|
|
if ( file_exists( $img ) )
|
|
echo '<img src="'. $product['images'][0]['src'] . '">';
|
|
?>
|
|
</td>
|
|
<td><?= $product['language']['name'];?></td>
|
|
<td class="text-center"><?= $row['quantity_summary'];?></td>
|
|
<td class="text-right"><?= number_format( $row['sales'], 2, '.', " " );?> zł</td>
|
|
</tr>
|
|
<? endforeach; endif;?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-6">
|
|
<div class="dashboard-content">
|
|
<div class="dashboard-title">
|
|
Najczęściej oglądane produkty
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">Zdjęcie</th>
|
|
<th scope="col">Nazwa</th>
|
|
<th scope="col" class="text-center">Ilość</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<? if ( \Shared\Helpers\Helpers::is_array_fix( $this -> most_view_products ) ): foreach ( $this -> most_view_products as $row ):?>
|
|
<? $product = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->findCached( $row['id'] );?>
|
|
<tr>
|
|
<td>
|
|
<?
|
|
$img = '../' . $product['images'][0]['src'];
|
|
if ( file_exists( $img ) )
|
|
echo '<img src="'. $product['images'][0]['src'] . '">';
|
|
?>
|
|
</td>
|
|
<td><?= $product['language']['name'];?></td>
|
|
<td class="text-center"><?= $row['visits'];?></td>
|
|
</tr>
|
|
<? endforeach; endif;?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script type="text/javascript" src="/libraries/apexcharts/apexcharts.js"></script>
|
|
<script type="text/javascript">
|
|
$(function () {
|
|
|
|
var options = {
|
|
series: [{
|
|
name: 'Sprzedaż',
|
|
data: [ <? for ( $i = 23; $i >= 0; $i-- ) { echo number_format( (float)$this -> sales[$i]['sales'], 0 , '.', "" ); if ( $i != 0 ) echo ','; }?> ]
|
|
}],
|
|
chart: {
|
|
height: 600,
|
|
type: 'bar',
|
|
},
|
|
plotOptions: {
|
|
bar: {
|
|
dataLabels: {
|
|
position: 'top',
|
|
},
|
|
}
|
|
},
|
|
dataLabels: {
|
|
enabled: true,
|
|
formatter: function (val) {
|
|
return parseFloat(val).toFixed(0) + " zł";
|
|
},
|
|
offsetY: -20,
|
|
style: {
|
|
fontSize: '12px',
|
|
colors: ["#304758"]
|
|
}
|
|
},
|
|
stroke: {
|
|
curve: 'smooth'
|
|
},
|
|
xaxis: {
|
|
categories: [ <? for ( $i = 23; $i >= 0; $i-- ) { echo "'" . $this -> sales[$i]['date'] . "'"; if ( $i != 0 ) echo ','; }?> ],
|
|
position: 'bottom',
|
|
axisBorder: {
|
|
show: false
|
|
},
|
|
axisTicks: {
|
|
show: false
|
|
},
|
|
crosshairs: {
|
|
fill: {
|
|
type: 'gradient',
|
|
gradient: {
|
|
colorFrom: '#D8E3F0',
|
|
colorTo: '#BED1E6',
|
|
stops: [0, 100],
|
|
opacityFrom: 0.4,
|
|
opacityTo: 0.5,
|
|
}
|
|
}
|
|
}
|
|
},
|
|
yaxis: {
|
|
axisBorder: {
|
|
show: false
|
|
},
|
|
axisTicks: {
|
|
show: false,
|
|
},
|
|
labels: {
|
|
show: false,
|
|
formatter: function (val) {
|
|
return parseFloat(val).toFixed(2) + " zł";
|
|
}
|
|
}
|
|
}
|
|
};
|
|
var chart = new ApexCharts(document.querySelector("#sale"), options);
|
|
chart.render();
|
|
});
|
|
</script>
|