Skip to content

Commit 598f57f

Browse files
committed
commerce dashboard
1 parent 8f677ff commit 598f57f

File tree

2 files changed

+111
-30
lines changed

2 files changed

+111
-30
lines changed

app/base/controllers/Admin/Commerce/Dashboard.php

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,18 @@ protected function collectData(DateTime $to, ?DateTime $from = null): array
9494
$args['to'] = $to->format('Y-m-d 23:59:59');
9595
}
9696

97-
// === 1️⃣ Statistiche generali (solo tabella `order`) ===
97+
// === 1️⃣ Statistiche generali ===
9898
$qOrders = "
9999
SELECT
100100
COUNT(o.id) AS total_sales,
101+
COUNT(DISTINCT o.user_id) AS unique_customers,
102+
SUM(o.admin_sub_total) AS net_income,
101103
SUM(o.admin_total_incl_tax) AS total_income,
102-
SUM(o.discount_amount) AS total_discounts,
103-
SUM(o.tax_amount) AS total_tax,
104+
SUM(o.admin_shipping_amount) AS total_shipping,
105+
SUM(o.admin_discount_amount) AS total_discounts,
106+
SUM(o.admin_tax_amount) AS total_tax,
107+
AVG(o.admin_discount_amount) AS avg_discount,
108+
AVG(o.admin_tax_amount) AS avg_tax,
104109
MAX(o.admin_currency_code) AS admin_currency_code
105110
FROM `order` o
106111
$where
@@ -122,7 +127,7 @@ protected function collectData(DateTime $to, ?DateTime $from = null): array
122127
$stmt2->execute($args);
123128
$items = $stmt2->fetch(\PDO::FETCH_ASSOC) ?: [];
124129

125-
// === 3️⃣ Prodotti più venduti (TOP 10) ===
130+
// === 3️⃣ Prodotti più venduti (TOP 5) ===
126131
$qTop = "
127132
SELECT
128133
CONCAT(oi.product_class, ':', oi.product_id) AS product_key,
@@ -146,9 +151,9 @@ protected function collectData(DateTime $to, ?DateTime $from = null): array
146151
$label = method_exists($product, 'getSku')
147152
? ($product->getSku() ?: $product->getName())
148153
: $product->getName();
149-
$stock = ($product instanceof PhysicalProductInterface) ?
150-
$product->getProductStock()->getCurrentQuantity() :
151-
$this->getUtils()->translate('unlimited', locale: $this->getCurrentLocale());
154+
$stock = ($product instanceof PhysicalProductInterface)
155+
? $product->getProductStock()->getCurrentQuantity()
156+
: $this->getUtils()->translate('unlimited', locale: $this->getCurrentLocale());
152157
} catch (\Exception $e) {
153158
$label = 'n/a';
154159
$stock = 'n/a';
@@ -181,22 +186,33 @@ protected function collectData(DateTime $to, ?DateTime $from = null): array
181186
$currency = $orders['admin_currency_code'] ?? 'EUR';
182187

183188
$total_sales = (int) ($orders['total_sales'] ?? 0);
189+
$total_products = (int) ($items['total_products'] ?? 0);
190+
$unique_customers = (int) ($orders['unique_customers'] ?? 0);
184191
$total_income = (float) ($orders['total_income'] ?? 0);
192+
$net_income = (float) ($orders['net_income'] ?? 0);
185193
$total_tax = (float) ($orders['total_tax'] ?? 0);
186194
$total_discount = (float) ($orders['total_discounts'] ?? 0);
187-
$total_products = (int) ($items['total_products'] ?? 0);
195+
$total_shipping = (float) ($orders['total_shipping'] ?? 0);
188196

189197
$aov = $total_sales > 0 ? $total_income / $total_sales : 0;
198+
$avg_products = $total_sales > 0 ? $total_products / $total_sales : 0;
199+
$days = $from ? max(1, $to->diff($from)->days) : 1;
200+
$orders_per_day = $days > 0 ? $total_sales / $days : 0;
190201

191202
return [
192-
'total_sales' => $total_sales,
193-
'total_income' => $utils->formatPrice($total_income, $currency),
194-
'total_tax' => $utils->formatPrice($total_tax, $currency),
195-
'total_discount' => $utils->formatPrice($total_discount, $currency),
196-
'total_products' => $total_products,
197-
'average_order' => $utils->formatPrice($aov, $currency),
198-
'most_sold' => $most_sold,
199-
'top_payment' => $payment['payment_method'] ?? 'n/a',
203+
'total_sales' => $total_sales,
204+
'unique_customers' => $unique_customers,
205+
'total_income' => $utils->formatPrice($total_income, $currency),
206+
'net_income' => $utils->formatPrice($net_income, $currency),
207+
'total_tax' => $utils->formatPrice($total_tax, $currency),
208+
'total_discount' => $utils->formatPrice($total_discount, $currency),
209+
'total_shipping' => $utils->formatPrice($total_shipping, $currency),
210+
'total_products' => $total_products,
211+
'average_order' => $utils->formatPrice($aov, $currency),
212+
'avg_products' => round($avg_products, 2),
213+
'orders_per_day' => round($orders_per_day, 2),
214+
'most_sold' => $most_sold,
215+
'top_payment' => $payment['payment_method'] ?? 'n/a',
200216
];
201217
}
202218
}

templates/admin/commerce/dashboard.php

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,24 @@ class="tab-pane fade <?= $first ? 'show active' : '' ?>"
4444
role="tabpanel"
4545
aria-labelledby="<?= $tab_id ?>-tab"
4646
>
47-
<!-- Summary cards -->
47+
<!-- Row 1: Main metrics -->
4848
<div class="row mt-3">
4949
<div class="col-md-3">
5050
<div class="card text-center">
51-
<div class="card-header"><h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Orders') ?></h6></div>
52-
<div class="card-body">
51+
<div class="card-header">
52+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Orders') ?></h6>
53+
</div>
54+
<div class="card-body">
5355
<p class="h3 mb-0"><?= (int)$data['total_sales'] ?></p>
5456
</div>
5557
</div>
5658
</div>
5759

5860
<div class="col-md-3">
5961
<div class="card text-center">
60-
<div class="card-header"><h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Revenue') ?></h6></div>
62+
<div class="card-header">
63+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Revenue (Gross)') ?></h6>
64+
</div>
6165
<div class="card-body">
6266
<p class="h3 mb-0"><?= htmlspecialchars($data['total_income']) ?></p>
6367
</div>
@@ -66,28 +70,82 @@ class="tab-pane fade <?= $first ? 'show active' : '' ?>"
6670

6771
<div class="col-md-3">
6872
<div class="card text-center">
69-
<div class="card-header"><h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Average order value') ?></h6></div>
73+
<div class="card-header">
74+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Net Income') ?></h6>
75+
</div>
76+
<div class="card-body">
77+
<p class="h3 mb-0"><?= htmlspecialchars($data['net_income']) ?></p>
78+
</div>
79+
</div>
80+
</div>
81+
82+
<div class="col-md-3">
83+
<div class="card text-center">
84+
<div class="card-header">
85+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Average Order Value') ?></h6>
86+
</div>
7087
<div class="card-body">
7188
<p class="h3 mb-0"><?= htmlspecialchars($data['average_order']) ?></p>
7289
</div>
7390
</div>
7491
</div>
92+
</div>
7593

94+
<!-- Row 2: Secondary metrics -->
95+
<div class="row mt-3">
7696
<div class="col-md-3">
7797
<div class="card text-center">
78-
<div class="card-header"><h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Products sold') ?></h6></div>
98+
<div class="card-header">
99+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Products Sold') ?></h6>
100+
</div>
79101
<div class="card-body">
80102
<p class="h3 mb-0"><?= (int)$data['total_products'] ?></p>
103+
<small class="text-muted"><?= $this->sitebase()->translate('Avg per order: %s', [$data['avg_products']]) ?></small>
104+
</div>
105+
</div>
106+
</div>
107+
108+
<div class="col-md-3">
109+
<div class="card text-center">
110+
<div class="card-header">
111+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Unique Customers') ?></h6>
112+
</div>
113+
<div class="card-body">
114+
<p class="h3 mb-0"><?= (int)$data['unique_customers'] ?></p>
115+
</div>
116+
</div>
117+
</div>
118+
119+
<div class="col-md-3">
120+
<div class="card text-center">
121+
<div class="card-header">
122+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Orders per day') ?></h6>
123+
</div>
124+
<div class="card-body">
125+
<p class="h3 mb-0"><?= $data['orders_per_day'] ?></p>
126+
</div>
127+
</div>
128+
</div>
129+
130+
<div class="col-md-3">
131+
<div class="card text-center">
132+
<div class="card-header">
133+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Shipping total') ?></h6>
134+
</div>
135+
<div class="card-body">
136+
<p class="h3 mb-0"><?= htmlspecialchars($data['total_shipping']) ?></p>
81137
</div>
82138
</div>
83139
</div>
84140
</div>
85141

86-
<!-- More stats -->
142+
<!-- Row 3: Tax, discount, payment -->
87143
<div class="row mt-3">
88144
<div class="col-md-4">
89145
<div class="card text-center">
90-
<div class="card-header"><h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Tax collected') ?></h6></div>
146+
<div class="card-header">
147+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Tax collected') ?></h6>
148+
</div>
91149
<div class="card-body">
92150
<p class="h4 mb-0"><?= htmlspecialchars($data['total_tax']) ?></p>
93151
</div>
@@ -96,16 +154,20 @@ class="tab-pane fade <?= $first ? 'show active' : '' ?>"
96154

97155
<div class="col-md-4">
98156
<div class="card text-center">
99-
<div class="card-header"><h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Discounts given') ?></h6></div>
100-
<div class="card-body">
157+
<div class="card-header">
158+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Discounts given') ?></h6>
159+
</div>
160+
<div class="card-body">
101161
<p class="h4 mb-0"><?= htmlspecialchars($data['total_discount']) ?></p>
102162
</div>
103163
</div>
104164
</div>
105165

106166
<div class="col-md-4">
107167
<div class="card text-center">
108-
<div class="card-header"><h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Most used payment method') ?></h6></div>
168+
<div class="card-header">
169+
<h6 class="text-muted mb-2"><?= $this->sitebase()->translate('Most used payment method') ?></h6>
170+
</div>
109171
<div class="card-body">
110172
<p class="h4 mb-0"><?= htmlspecialchars($data['top_payment']) ?></p>
111173
</div>
@@ -114,7 +176,10 @@ class="tab-pane fade <?= $first ? 'show active' : '' ?>"
114176
</div>
115177

116178
<!-- Top sellers -->
117-
<h4 class="mt-4 mb-3"><?= $this->sitebase()->translate('Top %d best sellers', [count($data['most_sold'])]); ?></h4>
179+
<h4 class="mt-4 mb-3">
180+
<?= $this->sitebase()->translate('Top %d best sellers', [count($data['most_sold'])]); ?>
181+
</h4>
182+
118183
<div class="table-responsive">
119184
<table class="table table-striped table-bordered table-sm">
120185
<thead class="thead-dark">
@@ -129,14 +194,14 @@ class="tab-pane fade <?= $first ? 'show active' : '' ?>"
129194
<tr>
130195
<td><?= htmlspecialchars($item['product']) ?></td>
131196
<td class="text-right"><?= (int)$item['total_qty'] ?></td>
132-
<td class="text-right"><?= $item['stock'] ?></td>
197+
<td class="text-right"><?= htmlspecialchars($item['stock']) ?></td>
133198
</tr>
134199
<?php endforeach; ?>
135200
</tbody>
136201
</table>
137202
</div>
138-
139203
</div>
140204
<?php $first = false; endforeach; ?>
141205
</div>
206+
142207
</div>

0 commit comments

Comments
 (0)