11<?php
22namespace App \Services ;
33
4+ use App \Models \Customer ;
5+ use App \Models \CustomerCoupon ;
6+ use App \Models \Procurement ;
7+ use App \Models \Product ;
8+ use App \Models \Provider ;
9+ use App \Models \Tax ;
10+ use App \Models \TaxGroup ;
411use App \Models \Unit ;
512use App \Models \UnitGroup ;
613use Database \Seeders \CustomerGroupSeeder ;
714use Database \Seeders \DefaultProviderSeeder ;
15+ use Faker \Factory ;
16+ use Illuminate \Support \Arr ;
817use Illuminate \Support \Facades \Auth ;
18+ use Illuminate \Support \Str ;
19+ use Carbon \Carbon ;
920
1021class DemoCoreService
1122{
1223 protected $ categoryService ;
1324 protected $ productService ;
25+ protected $ orderCount = 25 ;
26+ protected $ customOrderParams = [];
27+ protected $ customDate = true ;
28+ protected $ customProductParams = [];
29+ protected $ shouldMakePayment = true ;
30+
31+ /**
32+ * @var OrdersService
33+ */
34+ protected $ orderService ;
35+
36+ /**
37+ * @var ProcurementService
38+ */
39+ protected $ procurementService ;
1440 protected $ user ;
1541
1642 /**
@@ -52,5 +78,258 @@ public function createCustomers()
5278 public function createProviders ()
5379 {
5480 (new DefaultProviderSeeder )->run ();
81+ }
82+
83+ /**
84+ * Create sample tax group
85+ * and taxes on the system
86+ * @return void
87+ */
88+ public function createTaxes ()
89+ {
90+ $ taxGroup = TaxGroup::where ( 'name ' , __ ( 'GST ' ) )->first ();
91+
92+ if ( ! $ taxGroup instanceof TaxGroup ) {
93+ $ taxGroup = new TaxGroup ;
94+ $ taxGroup ->name = __ ( 'GST ' );
95+ $ taxGroup ->author = Auth::id ();
96+ $ taxGroup ->save ();
97+ }
98+
99+ $ tax = Tax::where ( 'name ' , __ ( 'SGST ' ) )->first ();
100+
101+ if ( ! $ tax instanceof Tax ) {
102+ $ tax = new Tax ;
103+ $ tax ->name = __ ( 'SGST ' );
104+ $ tax ->rate = 8 ;
105+ $ tax ->tax_group_id = $ taxGroup ->id ;
106+ $ tax ->author = Auth::id ();
107+ $ tax ->save ();
108+ }
109+
110+ $ tax = Tax::where ( 'name ' , __ ( 'CGST ' ) )->first ();
111+
112+ if ( ! $ tax instanceof Tax ) {
113+ $ tax = new Tax ;
114+ $ tax ->name = __ ( 'CGST ' );
115+ $ tax ->rate = 8 ;
116+ $ tax ->tax_group_id = $ taxGroup ->id ;
117+ $ tax ->author = Auth::id ();
118+ $ tax ->save ();
119+ }
120+ }
121+
122+ public function performProcurement ()
123+ {
124+ $ faker = Factory::create ();
125+
126+ /**
127+ * @var TaxService
128+ */
129+ $ taxService = app ()->make ( TaxService::class );
130+
131+ /**
132+ * @var CurrencyService
133+ */
134+ $ currencyService = app ()->make ( CurrencyService::class );
135+
136+ $ taxType = Arr::random ([ 'inclusive ' , 'exclusive ' ]);
137+ $ taxGroup = TaxGroup::get ()->random ();
138+ $ margin = 25 ;
139+
140+ $ this ->procurementService ->create ([
141+ 'name ' => sprintf ( __ ( 'Sample Procurement %s ' ), Str::random (5 ) ),
142+ 'general ' => [
143+ 'provider_id ' => Provider::get ()->random ()->id ,
144+ 'payment_status ' => Procurement::PAYMENT_PAID ,
145+ 'delivery_status ' => Procurement::DELIVERED ,
146+ 'automatic_approval ' => 1
147+ ],
148+ 'products ' => Product::withStockEnabled ()
149+ ->with ( 'unitGroup ' )
150+ ->get ()
151+ ->map ( function ( $ product ) {
152+ return $ product ->unitGroup ->units ->map ( function ( $ unit ) use ( $ product ) {
153+ $ unitQuantity = $ product ->unit_quantities ->filter ( fn ( $ q ) => ( int ) $ q ->unit_id === ( int ) $ unit ->id )->first ();
154+
155+ return ( object ) [
156+ 'unit ' => $ unit ,
157+ 'unitQuantity ' => $ unitQuantity ,
158+ 'product ' => $ product
159+ ];
160+ });
161+ })->flatten ()->map ( function ( $ data ) use ( $ taxService , $ taxType , $ taxGroup , $ margin , $ faker ) {
162+
163+ return [
164+ 'product_id ' => $ data ->product ->id ,
165+ 'gross_purchase_price ' => 15 ,
166+ 'net_purchase_price ' => 16 ,
167+ 'purchase_price ' => $ taxService ->getTaxGroupComputedValue (
168+ $ taxType ,
169+ $ taxGroup ,
170+ $ data ->unitQuantity ->sale_price - $ taxService ->getPercentageOf (
171+ $ data ->unitQuantity ->sale_price ,
172+ $ margin
173+ )
174+ ),
175+ 'quantity ' => $ faker ->numberBetween (500 ,1000 ),
176+ 'tax_group_id ' => $ taxGroup ->id ,
177+ 'tax_type ' => $ taxType ,
178+ 'tax_value ' => $ taxService ->getTaxGroupVatValue (
179+ $ taxType ,
180+ $ taxGroup ,
181+ $ data ->unitQuantity ->sale_price - $ taxService ->getPercentageOf (
182+ $ data ->unitQuantity ->sale_price ,
183+ $ margin
184+ )
185+ ),
186+ 'total_purchase_price ' => $ taxService ->getTaxGroupComputedValue (
187+ $ taxType ,
188+ $ taxGroup ,
189+ $ data ->unitQuantity ->sale_price - $ taxService ->getPercentageOf (
190+ $ data ->unitQuantity ->sale_price ,
191+ $ margin
192+ )
193+ ) * 250 ,
194+ 'unit_id ' => $ data ->unit ->id ,
195+ ];
196+ })
197+ ]);
198+ }
199+
200+ public function createSales ()
201+ {
202+ /**
203+ * @var ReportService $reportService
204+ */
205+ $ reportService = app ()->make ( ReportService::class );
206+ $ dates = [];
207+ $ startOfWeek = ns ()->date ->clone ()->startOfWeek ()->subDay ();
208+
209+ for ( $ i = 0 ; $ i < 7 ; $ i ++ ) {
210+ $ dates [] = $ startOfWeek ->addDay ()->clone ();
211+ }
212+
213+ for ( $ i = 0 ; $ i < $ this ->orderCount ; $ i ++ ) {
214+
215+ $ currentDate = Arr::random ( $ dates );
216+
217+ /**
218+ * @var CurrencyService
219+ */
220+ $ currency = app ()->make ( CurrencyService::class );
221+ $ faker = Factory::create ();
222+ $ products = Product::with ( 'unit_quantities ' )->get ()->shuffle ()->take (3 );
223+ $ shippingFees = $ faker ->randomElement ([10 ,15 ,20 ,25 ,30 ,35 ,40 ]);
224+ $ discountRate = $ faker ->numberBetween (0 ,5 );
225+
226+ $ products = $ products ->map ( function ( $ product ) use ( $ faker ) {
227+ $ unitElement = $ faker ->randomElement ( $ product ->unit_quantities );
228+ return array_merge ([
229+ 'product_id ' => $ product ->id ,
230+ 'quantity ' => $ faker ->numberBetween (1 ,10 ),
231+ 'unit_price ' => $ unitElement ->sale_price ,
232+ 'unit_quantity_id ' => $ unitElement ->id ,
233+ ], $ this ->customProductParams );
234+ });
235+
236+ /**
237+ * testing customer balance
238+ */
239+ $ customer = Customer::get ()->random ();
240+ $ customerFirstPurchases = $ customer ->purchases_amount ;
241+ $ customerFirstOwed = $ customer ->owed_amount ;
242+
243+ $ subtotal = ns ()->currency ->getRaw ( $ products ->map ( function ( $ product ) use ($ currency ) {
244+ return $ currency
245+ ->define ( $ product [ 'unit_price ' ] )
246+ ->multiplyBy ( $ product [ 'quantity ' ] )
247+ ->getRaw ();
248+ })->sum () );
249+
250+ $ customerCoupon = CustomerCoupon::get ()->last ();
251+
252+ if ( $ customerCoupon instanceof CustomerCoupon ) {
253+ $ allCoupons = [
254+ [
255+ 'customer_coupon_id ' => $ customerCoupon ->id ,
256+ 'coupon_id ' => $ customerCoupon ->coupon_id ,
257+ 'name ' => $ customerCoupon ->name ,
258+ 'type ' => 'percentage_discount ' ,
259+ 'code ' => $ customerCoupon ->code ,
260+ 'limit_usage ' => $ customerCoupon ->coupon ->limit_usage ,
261+ 'value ' => $ currency ->define ( $ customerCoupon ->coupon ->discount_value )
262+ ->multiplyBy ( $ subtotal )
263+ ->divideBy ( 100 )
264+ ->getRaw (),
265+ 'discount_value ' => $ customerCoupon ->coupon ->discount_value ,
266+ 'minimum_cart_value ' => $ customerCoupon ->coupon ->minimum_cart_value ,
267+ 'maximum_cart_value ' => $ customerCoupon ->coupon ->maximum_cart_value ,
268+ ]
269+ ];
270+
271+ $ totalCoupons = collect ( $ allCoupons )->map ( fn ( $ coupon ) => $ coupon [ 'value ' ] )->sum ();
272+ } else {
273+ $ allCoupons = [];
274+ $ totalCoupons = 0 ;
275+ }
276+
277+ $ discountValue = $ currency ->define ( $ discountRate )
278+ ->multiplyBy ( $ subtotal )
279+ ->divideBy ( 100 )
280+ ->getRaw ();
281+
282+ $ discountCoupons = $ currency ->define ( $ discountValue )
283+ ->additionateBy ( $ allCoupons [0 ][ 'value ' ] ?? 0 )
284+ ->getRaw ();
285+
286+ $ dateString = $ currentDate ->startOfDay ()->addHours (
287+ $ faker ->numberBetween ( 0 ,23 )
288+ )->format ( 'Y-m-d H:m:s ' );
289+
290+ $ orderData = array_merge ([
291+ 'customer_id ' => $ customer ->id ,
292+ 'type ' => [ 'identifier ' => 'takeaway ' ],
293+ 'discount_type ' => 'percentage ' ,
294+ 'created_at ' => $ this ->customDate ? $ dateString : null ,
295+ 'discount_percentage ' => $ discountRate ,
296+ 'addresses ' => [
297+ 'shipping ' => [
298+ 'name ' => 'First Name Delivery ' ,
299+ 'surname ' => 'Surname ' ,
300+ 'country ' => 'Cameroon ' ,
301+ ],
302+ 'billing ' => [
303+ 'name ' => 'EBENE Voundi ' ,
304+ 'surname ' => 'Antony Hervé ' ,
305+ 'country ' => 'United State Seattle ' ,
306+ ]
307+ ],
308+ 'coupons ' => $ allCoupons ,
309+ 'subtotal ' => $ subtotal ,
310+ 'shipping ' => $ shippingFees ,
311+ 'products ' => $ products ->toArray (),
312+ 'payments ' => $ this ->shouldMakePayment ? [
313+ [
314+ 'identifier ' => 'cash-payment ' ,
315+ 'value ' => $ currency ->define ( $ subtotal )
316+ ->additionateBy ( $ shippingFees )
317+ ->subtractBy (
318+ $ discountCoupons
319+ )
320+ ->getRaw ()
321+ ]
322+ ] : []
323+ ], $ this ->customOrderParams );
324+
325+ $ result = $ this ->orderService ->create ( $ orderData );
326+ }
327+
328+ foreach ( $ dates as $ date ) {
329+ $ startDate = Carbon::parse ( $ date )->startOfDay ()->toDateTimeString ();
330+ $ endDate = Carbon::parse ( $ date )->endOfDay ()->toDateTimeString ();
331+
332+ $ reportService ->computeDayReport ( $ startDate , $ endDate );
333+ }
55334 }
56335}
0 commit comments