2
2
3
3
namespace App \Services ;
4
4
5
+ use Carbon \Carbon ;
6
+ use App \Models \Workflow \Orders ;
7
+ use App \Models \Workflow \Deliverys ;
5
8
use Illuminate \Support \Facades \DB ;
6
9
use App \Models \Workflow \OrderLines ;
7
- use Carbon \Carbon ;
8
10
9
11
class OrderKPIService
10
12
{
13
+
14
+ /**
15
+ * Calculates the percentage of orders fully delivered for the current year.
16
+ *
17
+ * An order is considered fully delivered if the delivered quantity (`delivered_qty`)
18
+ * is greater than or equal to the ordered quantity (`qty`) for all associated order lines.
19
+ *
20
+ * @return float The percentage of orders delivered for the current year.
21
+ */
22
+ public function getDeliveredOrdersPercentage ()
23
+ {
24
+ $ totalOrders = OrderLines::whereYear ('created_at ' , now ()->year )->count ();
25
+
26
+ if ($ totalOrders === 0 ) {
27
+ return 0 ;
28
+ }
29
+
30
+ $ deliveredOrders = OrderLines::whereYear ('created_at ' , now ()->year )
31
+ ->where ('delivery_status ' , '= ' , 3 )
32
+ ->count ();
33
+
34
+ return round (($ deliveredOrders / $ totalOrders ) * 100 ,2 );
35
+ }
36
+
37
+ /**
38
+ * Calculates the percentage of orders that are fully invoiced for the current year.
39
+ *
40
+ * An order is considered fully invoiced if all of its order lines
41
+ * have an `invoice_status` of 5, meaning that the line has been fully invoiced.
42
+ *
43
+ * @return float The percentage of orders that are invoiced for the current year.
44
+ */
45
+ public function getInvoicedOrdersPercentage ()
46
+ {
47
+ $ totalOrders = OrderLines::whereYear ('created_at ' , now ()->year )->count ();
48
+
49
+ if ($ totalOrders === 0 ) {
50
+ return 0 ;
51
+ }
52
+
53
+ $ invoicedOrders = OrderLines::whereYear ('created_at ' , now ()->year )
54
+ ->where ('invoice_status ' , 3 )
55
+ ->count ();
56
+
57
+ return round (($ invoicedOrders / $ totalOrders ) * 100 ,2 );
58
+ }
59
+
60
+ /**
61
+ * Get the number of backorders for the current year.
62
+ *
63
+ * An order is considered backordered if the expected delivery date
64
+ * has passed and it has not yet been fully delivered (delivered quantity < ordered quantity).
65
+ *
66
+ * @return int The number of backorders for the current year.
67
+ */
68
+ public function getLateOrdersCount ()
69
+ {
70
+ return Orders::whereYear ('created_at ' , now ()->year )
71
+ ->whereHas ('orderLines ' , function ($ query ) {
72
+ $ query ->where ('delivery_status ' , 1 ) // delivered quantity < ordered quantity
73
+ ->where ('delivery_date ' , '< ' , now ()); // expected delivery date has passed
74
+ })->count ();
75
+ }
76
+
77
+ /**
78
+ * Retrieve all orders that have quantities still to be delivered for the current year.
79
+ *
80
+ * An order is considered to have a pending delivery if statu != 3
81
+ *
82
+ * @return int of orders with pending deliveries for the current year.
83
+ */
84
+ public function getPendingDeliveries ()
85
+ {
86
+ return Orders::where ('statu ' , '!= ' , '3 ' )->count ();
87
+ }
88
+
89
+
11
90
/**
12
91
* Retrieves the monthly summary of order for the current year.
13
92
*
@@ -29,12 +108,34 @@ public function getOrderMonthlyRecap($year)
29
108
->get ();
30
109
}
31
110
111
+ /**
112
+ * Retrieves the monthly summary of order for the last year.
113
+ *
114
+ * @return \Illuminate\Support\Collection
115
+ */
116
+ public function getOrderMonthlyRecapPreviousYear ($ year )
117
+ {
118
+ $ lastyear = $ year -1 ;
119
+ return DB ::table ('order_lines ' )
120
+ ->selectRaw ('
121
+ MONTH(delivery_date) AS month,
122
+ SUM((selling_price * qty)-(selling_price * qty)*(discount/100)) AS orderSum
123
+ ' )
124
+ ->leftJoin ('orders ' , function ($ join ) {
125
+ $ join ->on ('order_lines.orders_id ' , '= ' , 'orders.id ' )
126
+ ->where ('orders.type ' , '= ' , 1 );
127
+ })
128
+ ->whereYear ('order_lines.created_at ' , $ lastyear )
129
+ ->groupByRaw ('MONTH(order_lines.delivery_date) ' )
130
+ ->get ();
131
+ }
132
+
32
133
/**
33
134
* Retrieves the monthly summary of order for the current month.
34
135
*
35
136
* @return \Illuminate\Support\Collection
36
137
*/
37
- public function getOrderMonthlyRemaining ($ month ,$ year )
138
+ public function getOrderMonthlyRemainingToDelivery ($ month ,$ year )
38
139
{
39
140
return DB ::table ('order_lines ' )
40
141
->selectRaw ('
@@ -46,6 +147,21 @@ public function getOrderMonthlyRemaining($month ,$year)
46
147
->get ();
47
148
}
48
149
150
+ /**
151
+ * Retrieves the monthly summary of order for the current month.
152
+ *
153
+ * @return \Illuminate\Support\Collection
154
+ */
155
+ public function getOrderMonthlyRemainingToInvoice ()
156
+ {
157
+ return DB ::table ('order_lines ' )
158
+ ->selectRaw ('
159
+ FLOOR(SUM((selling_price * qty)-(selling_price * qty)*(discount/100))) AS orderSum
160
+ ' )
161
+ ->where ('invoice_status ' , 1 )
162
+ ->get ();
163
+ }
164
+
49
165
/**
50
166
* Retrieves the total amount summary of order for the comming current year.
51
167
*
@@ -79,4 +195,86 @@ public function getOrdersDataRate()
79
195
->groupBy ('statu ' )
80
196
->get ();
81
197
}
198
+
199
+ /**
200
+ * Calculate the order completion rate for the current year.
201
+ *
202
+ * An order is considered completed if all of its lines are fully delivered.
203
+ *
204
+ * @return float The order completion rate in percentage.
205
+ */
206
+ public function getOrderCompletionRate ()
207
+ {
208
+ $ totalOrders = Orders::whereYear ('created_at ' , now ()->year )->count ();
209
+
210
+ if ($ totalOrders === 0 ) {
211
+ return 0 ;
212
+ }
213
+
214
+ $ completedOrders = Orders::whereYear ('created_at ' , now ()->year )
215
+ ->where ('statu ' , 3 )
216
+ ->count ();
217
+
218
+ return ($ completedOrders / $ totalOrders ) * 100 ;
219
+ }
220
+
221
+ /**
222
+ * Calculate the average processing time of an order for the current year.
223
+ *
224
+ * The processing time is the difference between the order creation date
225
+ * and the date of the last associated delivery.
226
+ *
227
+ * @return float The average processing time in days.
228
+ */
229
+ public function getAverageOrderProcessingTime ()
230
+ {
231
+ $ orders = Orders::whereYear ('created_at ' , now ()->year )
232
+ ->whereHas ('orderLines ' , function ($ query ) {
233
+ $ query ->whereColumn ('delivered_qty ' , '>= ' , 'qty ' );
234
+ })->get ();
235
+
236
+ if ($ orders ->isEmpty ()) {
237
+ return 0 ;
238
+ }
239
+
240
+ $ totalDays = $ orders ->map (function ($ order ) {
241
+ $ lastDeliveryDate = Deliverys::where ('order_id ' , $ order ->id )
242
+ ->latest ('created_at ' )
243
+ ->value ('created_at ' );
244
+
245
+ return $ lastDeliveryDate ? $ lastDeliveryDate ->diffInDays ($ order ->created_at ) : 0 ;
246
+ })->sum ();
247
+
248
+ return $ totalDays / $ orders ->count ();
249
+ }
250
+
251
+ /**
252
+ * Retrieve customers sorted by order volume for the current year.
253
+ *
254
+ * @param int $limit The number of customers to retrieve (default 5).
255
+ * @return \Illuminate\Database\Eloquent\Collection Collection of customers sorted by order volume.
256
+ */
257
+ public function getTopCustomersByOrderVolume ($ limit = 5 )
258
+ {
259
+ return Orders::select ('companies_id ' , DB ::raw ('COUNT(*) as order_count ' ))
260
+ ->whereYear ('created_at ' , now ()->year )
261
+ ->groupBy ('companies_id ' )
262
+ ->orderBy ('order_count ' , 'desc ' )
263
+ ->take ($ limit )
264
+ ->with ('companie ' ) // Assuming a relationship with companie model
265
+ ->get ();
266
+ }
267
+
268
+ /**
269
+ * Get the number of pending orders for the current year.
270
+ *
271
+ * An order is pending if it is not fully delivered and the remaining quantity to be delivered is > 0.
272
+ *
273
+ * @return int The number of pending orders.
274
+ */
275
+ public function getPendingOrdersCount ()
276
+ {
277
+ return Orders::whereYear ('created_at ' , now ()->year )->where ('statu ' , '!= ' , 3 )->count ();
278
+ }
279
+
82
280
}
0 commit comments