CheckoutController   B
last analyzed

Complexity

Total Complexity 45

Size/Duplication

Total Lines 325
Duplicated Lines 0 %

Importance

Changes 3
Bugs 2 Features 0
Metric Value
wmc 45
eloc 200
dl 0
loc 325
rs 8.8
c 3
b 2
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 34 1
B checkoutForm() 0 42 10
A getProcessingFee() 0 8 4
A updateFinalPrice() 0 14 2
A payNow() 0 26 6
A checkregularPaymentOrRenewal() 0 12 3
B getAttributes() 0 33 7
B postCheckout() 0 58 7
A product() 0 13 2
A checkoutAction() 0 30 3

How to fix   Complexity   

Complex Class

Complex classes like CheckoutController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CheckoutController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace App\Http\Controllers\Front;
4
5
use App\Http\Controllers\Common\MailChimpController;
6
use App\Http\Controllers\Common\TemplateController;
7
use App\Model\Common\Setting;
8
use App\Model\Common\Template;
9
use App\Model\Order\Invoice;
10
use App\Model\Order\InvoiceItem;
11
use App\Model\Order\Order;
12
use App\Model\Payment\Plan;
13
use App\Model\Product\Price;
14
use App\Model\Product\Product;
15
use App\Model\Product\Subscription;
16
use App\Traits\TaxCalculation;
17
use App\User;
18
use Bugsnag;
19
use Cart;
20
use Darryldecode\Cart\CartCondition;
21
use Illuminate\Http\Request;
22
23
class CheckoutController extends InfoController
24
{
25
    use TaxCalculation;
0 ignored issues
show
introduced by
The trait App\Traits\TaxCalculation requires some properties which are not provided by App\Http\Controllers\Front\CheckoutController: $rate, $name, $state, $s_gst, $inclusive, $country, $id, $tax_enable, $c_gst, $state_code, $ut_gst, $i_gst, $active
Loading history...
26
27
    public $subscription;
28
    public $plan;
29
    public $templateController;
30
    public $product;
31
    public $price;
32
    public $user;
33
    public $setting;
34
    public $template;
35
    public $order;
36
    public $addon;
37
    public $invoice;
38
    public $invoiceItem;
39
    public $mailchimp;
40
41
    public function __construct()
42
    {
43
        $subscription = new Subscription();
44
        $this->subscription = $subscription;
45
46
        $plan = new Plan();
47
        $this->plan = $plan;
48
49
        $templateController = new TemplateController();
50
        $this->templateController = $templateController;
51
52
        $product = new Product();
53
        $this->product = $product;
54
55
        $price = new Price();
56
        $this->price = $price;
57
58
        $user = new User();
59
        $this->user = $user;
60
61
        $setting = new Setting();
62
        $this->setting = $setting;
63
64
        $template = new Template();
65
        $this->template = $template;
66
67
        $order = new Order();
68
        $this->order = $order;
69
70
        $invoice = new Invoice();
71
        $this->invoice = $invoice;
72
73
        $invoiceItem = new InvoiceItem();
74
        $this->invoiceItem = $invoiceItem;
75
76
        // $mailchimp = new MailChimpController();
77
        // $this->mailchimp = $mailchimp;
78
    }
79
80
    /*
81
      * When Proceed to chekout button clicked first request comes here
82
     */
83
    public function checkoutForm(Request $request)
84
    {
85
        if (! \Auth::user()) {//If User is not Logged in then send him to login Page
86
            $url = $request->segments(); //The requested url (chekout).Save it in Session
87
            \Session::put('session-url', $url[0]);
88
            $content = Cart::getContent();
89
            $domain = $request->input('domain');
90
            if ($domain) {
91
                foreach ($domain as $key => $value) {
92
                    \Session::put('domain'.$key, $value); //Store all the domains Entered in Cart Page in Session
93
                }
94
            }
95
            \Session::put('content', $content);
96
97
            return redirect('login')->with('fails', 'Please login');
98
        }
99
100
        if (\Cart::isEmpty()) {//During renewal when payment fails due to some reason
101
            $invoice = \Session::get('invoice');
102
            if ($invoice && \Session::has('fails')) {
103
                return redirect('paynow/'.$invoice->id)->with('fails', 'Payment cannot be processed. Please try the other gateway.');
104
            }
105
        }
106
107
        $content = Cart::getContent();
108
        $taxConditions = $this->getAttributes($content);
109
110
        $content = Cart::getContent();
111
        try {
112
            $domain = $request->input('domain');
113
            if ($domain) {//Store the Domain  in session when user Logged In
114
                foreach ($domain as $key => $value) {
115
                    \Session::put('domain'.$key, $value);
116
                }
117
            }
118
119
            return view('themes.default1.front.checkout', compact('content', 'taxConditions'));
120
        } catch (\Exception $ex) {
121
            app('log')->error($ex->getMessage());
122
            Bugsnag::notifyException($ex);
123
124
            return redirect()->back()->with('fails', $ex->getMessage());
125
        }
126
    }
127
128
    /**
129
     * Get all the Attributes Sent From the cart along with Tax Conditions.
130
     *
131
     * @param array $content Collection of the Cart Values
132
     *
133
     * @return array Items along with their details,Attributes(Currency,Agents) and Tax Conditions
134
     */
135
    public function getAttributes($content)
136
    {
137
        try {
138
            if (count($content) > 0) {//after ProductPurchase this is not true as cart is cleared
139
                foreach ($content as $item) {
140
                    $cart_currency = $item->attributes->currency; //Get the currency of Product in the cart
141
                    $currency = \Auth::user()->currency != $cart_currency ? \Auth::user()->currency : $cart_currency; //If User Currency and cart currency are different the currency es set to user currency.
142
                    if ($cart_currency != $currency) {
143
                        $id = $item->id;
144
                        Cart::remove($id);
145
                    }
146
                    $require_domain = $item->associatedModel->require_domain;
147
                    $require = [];
148
                    if ($require_domain) {
149
                        $require[$key] = $item->id;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $key seems to be never defined.
Loading history...
150
                    }
151
                    $taxConditions = $this->calculateTax($item->id, \Auth::user()->state, \Auth::user()->country); //Calculate Tax Condition by passing ProductId
152
                    Cart::condition($taxConditions);
153
                    Cart::remove($item->id);
154
155
                    //Return array of Product Details,attributes and their conditions
156
                    $items[] = ['id' => $item->id, 'name' => $item->name, 'price' => $item->price,
157
                        'quantity'       => $item->quantity, 'attributes' => ['currency'=> $cart_currency, 'symbol'=>$item->attributes->symbol, 'agents'=> $item->attributes->agents], 'associatedModel' => Product::find($item->id), 'conditions' => $taxConditions, ];
158
                }
159
                Cart::add($items);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $items seems to be defined by a foreach iteration on line 139. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
160
161
                return $taxConditions;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $taxConditions seems to be defined by a foreach iteration on line 139. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
162
            }
163
        } catch (\Exception $ex) {
164
            app('log')->error($ex->getMessage());
165
            Bugsnag::notifyException($ex);
166
167
            return redirect()->back()->with('fails', $ex->getMessage());
168
        }
169
    }
170
171
    public function payNow($invoiceid)
172
    {
173
        try {
174
            $paid = 0;
175
            $invoice = $this->invoice->find($invoiceid);
176
            if ($invoice->user_id != \Auth::user()->id) {
177
                throw new \Exception('Cannot initiate payment. Invalid modification of data');
178
            }
179
            if (count($invoice->payment()->get())) {//If partial payment is made
180
                $paid = array_sum($invoice->payment()->pluck('amount')->toArray());
181
                $invoice->grand_total = $invoice->grand_total - $paid;
182
            }
183
            $items = new \Illuminate\Support\Collection();
184
            if ($invoice) {
185
                $items = $invoice->invoiceItem()->get();
186
                if (count($items) > 0) {
187
                    $product = $this->product($invoiceid);
188
                }
189
            }
190
191
            return view('themes.default1.front.paynow', compact('invoice', 'items', 'product', 'paid'));
192
        } catch (\Exception $ex) {
193
            app('log')->error($ex->getMessage());
194
            Bugsnag::notifyException($ex);
195
196
            return redirect()->back()->with('fails', $ex->getMessage());
197
        }
198
    }
199
200
    public function postCheckout(Request $request)
201
    {
202
        $cost = $request->input('cost');
203
        if (Cart::getSubTotal() != 0 || $cost > 0) {
204
            $this->validate($request, [
205
                'payment_gateway'=> 'required',
206
            ], [
207
                'payment_gateway.required'=> 'Please Select a Payment Gateway',
208
            ]);
209
        }
210
        try {
211
            $invoice_controller = new \App\Http\Controllers\Order\InvoiceController();
212
            $info_cont = new \App\Http\Controllers\Front\InfoController();
213
            $payment_method = $request->input('payment_gateway');
214
            \Session::put('payment_method', $payment_method);
215
            $paynow = $this->checkregularPaymentOrRenewal($request->input('invoice_id'));
216
            $cost = $request->input('cost');
217
            $state = $this->getState();
218
            if ($paynow === false) {//When regular payment
219
                $invoice = $invoice_controller->generateInvoice();
220
                $amount = intval(Cart::getSubTotal());
221
                if ($amount) {//If payment is for paid product
222
                    \Event::dispatch(new \App\Events\PaymentGateway(['request' => $request, 'invoice' => $invoice]));
223
                } else {
224
                    $date = getDateHtml($invoice->date);
0 ignored issues
show
Bug introduced by
The property date does not seem to exist on Illuminate\Http\RedirectResponse.
Loading history...
225
                    $product = $this->product($invoice->id);
0 ignored issues
show
Bug introduced by
The property id does not seem to exist on Illuminate\Http\RedirectResponse.
Loading history...
226
                    $items = $invoice->invoiceItem()->get();
227
                    $url = '';
228
                    $this->checkoutAction($invoice); //For free product generate invoice without payment
229
                    $url = view('themes.default1.front.postCheckoutTemplate', compact('invoice', 'date', 'product', 'items', ))->render();
230
                    // }
231
                    \Cart::clear();
232
233
                    return redirect('checkout')->with('success', $url);
234
                }
235
            } else {//When renewal, pending payments
236
                $invoiceid = $request->input('invoice_id');
237
                $invoice = $this->invoice->find($invoiceid);
238
                $amount = intval($invoice->grand_total);
239
                if ($amount) {//If payment is for paid product
240
                    \Event::dispatch(new \App\Events\PaymentGateway(['request' => $request, 'invoice' => $invoice]));
241
                } else {
242
                    $control = new \App\Http\Controllers\Order\RenewController();
243
                    $payment = new \App\Http\Controllers\Order\InvoiceController();
244
                    $payment->postRazorpayPayment($invoice);
245
                    $date = getDateHtml($invoice->date);
246
                    $product = $this->product($invoice->id);
247
                    $items = $invoice->invoiceItem()->get();
248
                    $url = '';
249
                    $this->checkoutAction($invoice); //For free product generate invoice without payment
250
                    $url = view('themes.default1.front.postCheckoutTemplate', compact('invoice', 'date', 'product', 'items', ))->render();
251
                    \Cart::clear();
252
253
                    return redirect('checkout')->with('success', $url);
254
                }
255
            }
256
        } catch (\Exception $ex) {
257
            return redirect()->back()->with('fails', $ex->getMessage());
258
        }
259
    }
260
261
    private function getProcessingFee($paymentMethod, $currency)
0 ignored issues
show
Unused Code introduced by
The method getProcessingFee() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
262
    {
263
        try {
264
            if ($paymentMethod) {
265
                return $paymentMethod == 'razorpay' ? 0 : \DB::table(strtolower($paymentMethod))->where('currencies', $currency)->value('processing_fee');
266
            }
267
        } catch (\Exception $e) {
268
            throw new \Exception('Invalid modification of data');
269
        }
270
    }
271
272
    public static function updateFinalPrice(Request $request)
273
    {
274
        $value = '0%';
275
        if ($request->input('processing_fee')) {
276
            $value = $request->input('processing_fee').'%';
277
        }
278
279
        $updateValue = new CartCondition([
280
            'name'   => 'Processing fee',
281
            'type'   => 'fee',
282
            'target' => 'total',
283
            'value'  => $value,
284
        ]);
285
        \Cart::condition($updateValue);
286
    }
287
288
    public function checkregularPaymentOrRenewal($invoiceid)
289
    {
290
        $paynow = false;
291
292
        if ($invoiceid) {
293
            if (Invoice::find($invoiceid)->user_id != \Auth::user()->id) {
294
                throw new \Exception('Invalid modification of data');
295
            }
296
            $paynow = true;
297
        }
298
299
        return $paynow;
300
    }
301
302
    public function checkoutAction($invoice)
303
    {
304
        try {
305
            //get elements from invoice
306
            $invoice_number = $invoice->number;
307
            $invoice_id = $invoice->id;
308
309
            foreach (\Cart::getConditionsByType('fee') as $value) {
310
                $invoice->processing_fee = $value->getValue();
311
            }
312
            // $invoice->processing_fee =
313
            $invoice->status = 'success';
314
            $invoice->save();
315
            $user_id = \Auth::user()->id;
316
317
            $url = '';
318
319
            $url = url("download/$user_id/$invoice->number");
320
            $payment = new \App\Http\Controllers\Order\InvoiceController();
321
            $payment->postRazorpayPayment($invoice);
322
            //execute the order
323
            $order = new \App\Http\Controllers\Order\OrderController();
324
            $order->executeOrder($invoice->id, $order_status = 'executed');
325
326
            return 'success';
327
        } catch (\Exception $ex) {
328
            app('log')->error($ex->getMessage());
329
            Bugsnag::notifyException($ex);
330
331
            return redirect()->back()->with('fails', $ex->getMessage());
332
        }
333
    }
334
335
    public function product($invoiceid)
336
    {
337
        try {
338
            $invoice = $this->invoiceItem->where('invoice_id', $invoiceid)->first();
339
            $name = $invoice->product_name;
340
            $product = $this->product->where('name', $name)->first();
341
342
            return $product;
343
        } catch (\Exception $ex) {
344
            app('log')->error($ex->getMessage());
345
            Bugsnag::notifyException($ex);
346
347
            throw new \Exception($ex->getMessage());
348
        }
349
    }
350
}
351