<?php namespace Onestartup\Shop\Controller; use Illuminate\Http\Request; use App\Http\Requests; use App\Http\Controllers\Controller; use Yajra\Datatables\Datatables; use Onestartup\Shop\Model\ProductShop as Product; use Onestartup\Shop\Model\ProductCategoryShop as Category; use Onestartup\Shop\Model\ShippingPrice as Shipping; use Onestartup\Shop\Model\ClientShop as Client; use Onestartup\Shop\Model\ShippingAddres as Addres; use Onestartup\Shop\Model\SaleShop as Sale; use Onestartup\Shop\Model\DetailShop as Item; use Onestartup\Shop\Model\DiscountCoupon as Coupon; use Onestartup\Shop\Model\Billing; use Onestartup\Shop\Model\UsoCfdi; use Onestartup\Shop\Payment\MP; use Onestartup\Shop\Notifications\PaymentClient; use Onestartup\Shop\Notifications\PaymentAcordarClient; use Onestartup\Shop\Notifications\PaymentClientCard; use Onestartup\Shop\Notifications\ResumenOrder; use PayPal\Rest\ApiContext; use PayPal\Auth\OAuthTokenCredential; use PayPal\Api\Payer; use PayPal\Api\Amount; use PayPal\Api\Transaction; use PayPal\Api\RedirectUrls; use PayPal\Api\Payment; use PayPal\Api\PaymentExecution; use PayPal\Exception\PayPalConnectionException; use PayPal\Api\Item as PaypalItem; use PayPal\Api\ItemList; use PayPal\Api\Details; use Onestartup\Shop\Libs\Util; use Onestartup\Shop\Model\VariableExtra as Variable; use Onestartup\Shop\Model\ExtraSaleInfo; use Onestartup\Shop\Requests\RequestClient; class CartController extends Controller { protected $util; public function __construct() { if (!\Session::has('cart')) { \Session::put('cart', array()); } setlocale(LC_MONETARY, 'en_US'); $this->util = new Util(); } public function show() { $total = $this->total(); $cart = \Session::get('cart'); return view('shop-public::cart.show-cart') ->with('cart', $cart) ->with('total', $total); } public function add(Product $product) { if (\Session::has('sale')) { $sale = Sale::find(\Session::get('sale')->id); $sale->status = 0; $sale->save(); \Session::forget('sale'); } $cart = \Session::get('cart'); $quantity = 1; if (isset($cart[$product->slug])) { $quantity = $cart[$product->slug]->quantity + 1; } if ($this->existencia($product) < $quantity) { return redirect()->back()->with('maximo', $this->existencia($product)); } $product->quantity = $quantity; $cart[$product->slug] = $product; \Session::put('cart', $cart); return redirect()->back(); } public function remove(Product $product) { $cart = \Session::get('cart'); if (!isset($cart[$product->slug])) { return redirect()->route('cart.show'); } unset($cart[$product->slug]); \Session::put('cart', $cart); return redirect()->route('cart.show'); } public function update(Product $product, $quantity) { if (\Session::has('sale')) { $sale = Sale::find(\Session::get('sale')->id); $sale->status = 0; $sale->save(); \Session::forget('sale'); } if ($quantity <= 0) { return redirect()->back(); } $cart = \Session::get('cart'); if (!isset($cart[$product->slug])) { return redirect()->route('cart.show'); } if ($this->existencia($product) >= $quantity){ $cart[$product->slug]->quantity = $quantity; \Session::put('cart', $cart); } else { //return "maximo ".$this->existencia($product); return redirect()->back()->with('maximo', $this->existencia($product)); } return redirect()->route('cart.show'); } public function trash() { if (\Session::has('sale')) { $sale = Sale::find(\Session::get('sale')->id); $sale->status = 0; $sale->save(); } \Session::forget('cart'); \Session::forget('sale'); \Session::forget('client'); return redirect()->route('cart.show'); } public function shipping(){ $client = new Client(); $addres = new Addres(); $sale = new Sale(); if(count(\Session::get('cart')) <= 0) {return redirect()->route('cart.show');} if(\Session::has('client')) { $client = \Session::get('client'); $addres = $client->shipping; } if(\Session::has('sale')){ $sale = Sale::find(\Session::get('sale')->id); } $cart = \Session::get('cart'); $total = $this->total(); $shipping = Shipping::pluck('name', 'id'); return view('shop-public::cart.shipping') ->with("sale", $sale) ->with('cart', $cart) ->with('total', $total) ->with('client', $client) ->with('addres', $addres) ->with('shipping', $shipping); } public function storeClient(Request $request) { $client = new Client(); $addres = new Addres(); $cart = \Session::get('cart'); $costoEnvio = 0; if(\Session::has('client')) { $client = \Session::get('client'); if ($client->shipping != null) { $addres = $client->shipping; } if (\Session::get('client')->email != $request->email) { $client = new Client(); $addres = new Addres(); } } /** Crea cliente ········· */ $client->fill($request->all()); $client->save(); if ($request->home_delivery) { /** Crea forma de envio ····· */ $addres->fill($request->all()); if (!isset($addres->client_id)) { $addres->client_id = $client->id; } $addres->save(); /** Guarda productos en tabla ······ */ $costoEnvio = $addres->shipping_price->cost; } if (!\Session::has('sale')) { $sale = $client->sales()->save(new Sale( ['home_delivery'=>$request->home_delivery, 'status' => 1, 'total'=>($this->total() + $costoEnvio), 'facturacion' => $request->facturacion ])); foreach ($cart as $product) { $item = Item::create([ 'product_id'=> $product->id, 'sale_id'=> $sale->id, 'quantity'=> $product->quantity ]); } } else { $sale = Sale::find(\Session::get('sale')->id); $sale->total = ($this->total() + $costoEnvio); $sale->facturacion = $request->facturacion; $sale->home_delivery = $request->home_delivery; $sale->save(); } if ($request->additional) { $additional = new ExtraSaleInfo($request->all()); $sale->info_extra()->save($additional); } \Session::put('sale', $sale); \Session::put('client', $client); return redirect()->route('cart.finish'); } public function finish() { if (!\Session::has('client')) { return redirect()->route('cart.shipping'); } if (!\Session::has('sale')) { return redirect()->route('cart.shipping'); } $sale = Sale::find(\Session::get('sale')->id); $client = $sale->client; $items = $sale->items; $addres = $client->shipping; return view('shop-public::cart.finish') ->with('sale', $sale) ->with('client', $client) ->with('items', $items) ->with('total', $this->total()) ->with('addres', $addres); } public function cancel() { $sale = Sale::find(\Session::get('sale')->id); $sale->status = 0; $sale->save(); \Session::forget('sale'); return redirect()->route('cart.show'); } public function payment(Request $request) { if (!\Session::has('client')) { return redirect()->route('cart.shipping'); } if (!\Session::has('sale')) { return redirect()->route('cart.shipping'); } $sale = Sale::find(\Session::get('sale')->id); $client = $sale->client; $items = $sale->items; $addres = $client->shipping != null ? $client->shipping : null; $products = $sale->products; $detail = ''; $status = ''; $user = \App\User::first(); $descuento = 0; $cupon = ''; $costo_envio = 0; foreach ($sale->products as $item) { $detail = $detail." ".$item->pivot->quantity." ".$item->name." Sub. ".money_format('%(#10n', ($item->infoSale->sale_price*$item->pivot->quantity)).", "; } if ($addres != null) { $detail = $detail." Envio ". $addres->shipping_price->name." ".money_format('%(#10n',$addres->shipping_price->cost); $costo_envio = $addres->shipping_price->cost; } if ($request->coupon != null) { $data = $this->getDiscount($sale, $request->coupon); if ($data['valid']) { $descuento = $data['amount_unformated']; $sale->total = $data['total_unformated']; $sale->coupon = $request->coupon; $cupon = ' - Descuento '.$request->coupon.' '.$data['amount']; } } $detail = $detail.''.$cupon; $mp = new MP(env('AC_MERCADO_PAGO')); $payment_data = array( "transaction_amount" => ($this->total() + $costo_envio) - $descuento, "token" => $request->card_token_id, "description" => $detail, "installments" => 1, "payment_method_id" => $request->paymentMethodId, "payer" => array ( "email" => $client->email, "first_name"=>$client->name, ) ); $payment = $mp->post("/v1/payments", $payment_data); $sale->payment_type = 'Tarjeta'; if ($payment['response']['status'] == 'approved') { $old = $sale->status; $sale->status = 2; $sale->transaction_id = $payment['response']['id']; $sale->save(); $status = 'Aprobado'; $this->util->stock_change($sale, $old); \Session::forget('client'); \Session::forget('cart'); \Session::forget('sale'); $user->notify(new ResumenOrder($sale, $products, $client, $addres)); $client->notify(new ResumenOrder($sale, $products, $client, $addres)); return redirect() ->route('main.shop') ->with('payment_approved', 'payment_approved'); } elseif ($payment['response']['status'] == 'in_process') { $sale->status = 3; $sale->transaction_id = $payment['response']['id']; $sale->save(); $status = 'En proceso'; \Session::forget('client'); \Session::forget('cart'); \Session::forget('sale'); //$user->notify(new PaymentClientCard($client, $request->paymentMethodId, $status)); $user->notify(new ResumenOrder($sale, $products, $client, $addres)); $client->notify(new ResumenOrder($sale, $products, $client, $addres)); return redirect() ->route('main.shop') ->with('payment_pending', 'payment_pending'); } else { $status = 'Rechazado'; $user->notify(new PaymentClientCard($client, $request->paymentMethodId, $status)); return redirect() ->back() ->with('payment_reject', 'payment_reject'); } //dd($payment); return $request; } public function paymentCash(Request $request) { if (!\Session::has('client')) { return redirect()->route('cart.shipping'); } if (!\Session::has('sale')) { return redirect()->route('cart.shipping'); } $sale = Sale::find(\Session::get('sale')->id); $client = $sale->client; $items = $sale->items; $addres = $client->shipping != null ? $client->shipping : null; $products = $sale->products; $detail = ''; $descuento = 0; $cupon = ''; $costo_envio = 0; foreach ($sale->products as $item) { $detail = $detail." ".$item->pivot->quantity." ".$item->name." Sub. ".money_format('%(#10n', ($item->infoSale->sale_price*$item->pivot->quantity)).", "; } if ($addres != null) { $detail = $detail." Envio ". $addres->shipping_price->name." ".money_format('%(#10n',$addres->shipping_price->cost); $costo_envio = $addres->shipping_price->cost; } if ($request->coupon != null) { $data = $this->getDiscount($sale, $request->coupon); if ($data['valid']) { $descuento = $data['amount_unformated']; $sale->total = $data['total_unformated']; $sale->coupon = $request->coupon; $cupon = ' - Descuento '.$request->coupon.' '.$data['amount']; } } $detail = $detail.''.$cupon; $mp = new MP(env('AC_MERCADO_PAGO')); $payment_data = array( "transaction_amount" => ($this->total() + $costo_envio)-$descuento, "description" => $detail, "payment_method_id" => $request->payment_id, "payer" => array ( "email" => $client->email, "first_name"=>$client->name, "last_name"=>$client->lastname ) ); $payment = $mp->post("/v1/payments", $payment_data); $url_ficha = $payment['response']['transaction_details']['external_resource_url']; $sale->status = 3; $sale->transaction_id = $payment['response']['id']; $sale->payment_type = $request->payment_id; $sale->save(); \Session::forget('client'); \Session::forget('cart'); \Session::forget('sale'); $user = \App\User::first(); $user->notify(new ResumenOrder($sale, $products, $client, $addres)); $client->notify(new ResumenOrder($sale, $products, $client, $addres)); //eturn $url_ficha; return redirect() ->route('main.shop') ->with('url_ficha', $url_ficha); } private function total() { $cart = \Session::get('cart'); $total = 0; foreach($cart as $product){ $total += $product->infoSale->sale_price * $product->quantity; } return $total; } public function successPaypal(Request $request) { if (!\Session::has('client')) { return redirect()->route('cart.shipping'); } if (!\Session::has('sale')) { return redirect()->route('cart.shipping'); } $apiContext = new ApiContext( new OAuthTokenCredential( env('CLIENT_ID_PAYPAL'), env('SECRET_PAYPAL') ) ); $apiContext->setConfig( array( 'log.LogEnabled' => true, 'log.FileName' => base_path().'/Paypal.log', 'log.LogLevel' => 'DEBUG', 'mode' => env('PAYPAL_MODE'), ) ); $paymentId = $request->paymentId; $payment = Payment::get($paymentId, $apiContext); $execution = new PaymentExecution(); $execution->setPayerId($request->PayerID); try { $result = $payment->execute($execution, $apiContext); if ($result->state == 'approved') { $sale = Sale::find(\Session::get('sale')->id); $client = $sale->client; $items = $sale->items; $addres = $client->shipping != null ? $client->shipping : null; $costo_envio = 0; $products = $sale->products; $old = $sale->status; $sale->status = 2; $sale->payment_type = 'Pay Pal'; $sale->save(); $this->util->stock_change($sale, $old); $user = \App\User::first(); $user->notify(new ResumenOrder($sale, $products, $client, $addres)); $client->notify(new ResumenOrder($sale, $products, $client, $addres)); \Session::forget('client'); \Session::forget('cart'); \Session::forget('sale'); return redirect() ->route('main.shop') ->with('payment_approved', 'payment_approved'); } else { return redirect() ->route('cart.finish') ->with('paypal_fail',$result->state); } } catch (\PayPal\Exception\PayPalConnectionException $ex) { return $ex->getData(); } } public function cancelPaypal() { return redirect() ->route('cart.finish') ->with('paypal_cancel', 'paypal_cancel'); } public function paymentPaypal(Request $request) { if (!\Session::has('client')) { return redirect()->route('cart.shipping'); } if (!\Session::has('sale')) { return redirect()->route('cart.shipping'); } $sale = Sale::find(\Session::get('sale')->id); $client = $sale->client; $items = $sale->items; $products = $sale->products; $addres = $client->shipping != null ? $client->shipping : null; $costo_envio = 0; $detail = ''; $descuento = 0; $apiContext = new ApiContext( new OAuthTokenCredential( env('CLIENT_ID_PAYPAL'), env('SECRET_PAYPAL') ) ); $apiContext->setConfig( array( 'log.LogEnabled' => true, 'log.FileName' => base_path().'/Paypal.log', 'log.LogLevel' => 'DEBUG', 'mode' => env('PAYPAL_MODE'), ) ); $payer = new \PayPal\Api\Payer(); $payer->setPaymentMethod('paypal'); $items = array(); foreach ($sale->items as $item) { //$cost = $item->product->infoSale->sale_price * $item->quantity; $item1 = new PaypalItem(); $item1->setName($item->product->name) ->setDescription($item->product->name) ->setCurrency('MXN') ->setQuantity($item->quantity) ->setPrice($item->product->infoSale->sale_price); $items[]=$item1; } if ($addres != null) { $costo_envio = $addres->shipping_price->cost; $item2 = new PaypalItem(); $item2->setName($addres->shipping_price->name) ->setDescription($addres->shipping_price->name) ->setCurrency('MXN') ->setQuantity(1) ->setPrice($addres->shipping_price->cost); array_push($items, $item2); } if ($request->coupon != null) { $data = $this->getDiscount($sale, $request->coupon); if ($data['valid']) { $descuento = $data['amount_unformated']; $sale->total = $data['total_unformated']; $sale->coupon = $request->coupon; //Descuento en caso de haber $item3 = new PaypalItem(); $item3->setName('Código de descuento: '.$request->coupon) ->setDescription('Código de descuento: '.$request->coupon) ->setCurrency('MXN') ->setQuantity(1) ->setPrice(($descuento * -1)); array_push($items, $item3); } } $itemList = new ItemList(); $itemList->setItems($items); $details = new Details(); $details->setSubtotal(($this->total() + $costo_envio) - $descuento); $amount = new \PayPal\Api\Amount(); $amount->setCurrency("MXN") ->setTotal(($this->total() + $costo_envio)-$descuento) ->setDetails($details); $transaction = new \PayPal\Api\Transaction(); $transaction->setAmount($amount) ->setItemList($itemList) ->setDescription("Compra en Onestartup") ->setInvoiceNumber(uniqid()); $redirectUrls = new \PayPal\Api\RedirectUrls(); $redirectUrls->setReturnUrl(route('cart.successPaypal')) ->setCancelUrl(route('cart.cancelPaypal')); $payment = new \PayPal\Api\Payment(); $payment->setIntent('sale') ->setPayer($payer) ->setRedirectUrls($redirectUrls) ->setTransactions(array($transaction)); try { $payment->create($apiContext); $sale->status = 3; $sale->transaction_id = $payment->id; $sale->save(); return redirect($payment->getApprovalLink()); } catch (\PayPal\Exception\PayPalConnectionException $ex) { echo $ex->getData(); } } public function acordar(Request $request) { if (!\Session::has('client')) { return redirect()->route('cart.shipping'); } if (!\Session::has('sale')) { return redirect()->route('cart.shipping'); } $sale = Sale::find(\Session::get('sale')->id); $client = $sale->client; $products = $sale->products; $items = $sale->items; $addres = $client->shipping != null ? $client->shipping : null; $costo_envio = 0; $detail = ''; $sale->status = 3; $sale->transaction_id = null; $sale->payment_type = 'Acordar con vendedor'; if ($request->coupon != null) { $data = $this->getDiscount($sale, $request->coupon); if ($data['valid']) { $sale->total = $data['total_unformated']; $sale->coupon = $request->coupon; } } $sale->save(); \Session::forget('client'); \Session::forget('cart'); \Session::forget('sale'); $user = \App\User::first(); //$user->notify(new PaymentAcordarClient('Acordar con el vendedor', $client)); $user->notify(new ResumenOrder($sale, $products, $client, $addres)); $client->notify(new ResumenOrder($sale, $products, $client, $addres)); return redirect() ->route('main.shop') ->with('acordar', 'acordar'); } public function testmail() { /*$sale = Sale::find(10); $data = $this->getDiscount($sale, 'test1'); return $data['amount']; $products = $sale->products; //return $products; if ($sale->status == 2) { foreach ($products as $product) { $aux = Product::find($product->id); $aux->infoSale()->increment('quantity', $product->pivot->quantity); } } else { foreach ($products as $product) { $aux = Product::find($product->id); $aux->infoSale()->decrement('quantity', $product->pivot->quantity); } } $sale->status = 3; $sale->save();*/ return "yei"; } public function existencia($product) { $quantity = 0; $sales = Sale::where('status',3)->get(); foreach ($sales as $order) { $products = $order->products; foreach($products as $aux){ if ($product->id == $aux->id ) { $quantity += $aux->pivot->quantity; } } } return $product->infoSale->quantity - $quantity; } public function discount(Request $request) { $sale = Sale::find($request->total); $data = $this->getDiscount($sale, $request->coupon); return response() ->json($data); } public function getDiscount($sale,$code) { $client = $sale->client; $addres = null; $cost_shipping = 0; if ($sale->home_delivery) { $addres = $client->shipping; $cost_shipping = $addres->shipping_price->cost; } $coupon = Coupon::where('code', $code)->first(); $today = date("Y-m-d"); $descuento = 0; $total = 0; $msg = 'Codigo de promoción no valido'; $valid = false; $data = []; foreach ($sale->products as $product) { $aux = $product->pivot->quantity * $product->infoSale->sale_price; $total += $aux; } if ($coupon != null) { if ($today <= $coupon->expiration) { if ($total >= $coupon->min_sale) { if ($coupon->type == 'Efectivo') { $descuento = $coupon->value; $msg = 'Tienes un descuento de: '.money_format('%(#10n',$descuento); $valid = true; } if ($coupon->type == 'Porcentaje') { $descuento = ($coupon->value/100) * $total; $msg = 'Tienes un descuento de: '.money_format('%(#10n',$descuento); $valid = true; } } else { $msg = 'Para aplicar este código de descuento tu compra minima debe ser de: ' .money_format('%(#10n',$coupon->min_sale); } } else{ $msg = 'Lo sentimos este código de descuento ya expiró :('; } } $data = [ 'valid'=>$valid, 'msg'=>$msg, 'amount'=>money_format('%(#10n',$descuento), 'amount_unformated'=>$descuento, 'total'=>money_format('%(#10n', (($total+$cost_shipping)-$descuento)), 'total_unformated'=>($total+$cost_shipping)-$descuento ]; return $data; } public function getDiscount2($sale) { $client = $sale->client; $addres = null; $cost_shipping = 0; if ($sale->home_delivery) { $addres = $client->shipping; $cost_shipping = $addres->shipping_price->cost; } $coupon = Coupon::where('code', $sale->coupon)->first(); $descuento = 0; $total = 0; $total_without = 0; $data = []; foreach ($sale->products as $product) { $aux = $product->pivot->quantity * $product->infoSale->sale_price; $total += $aux; $total_without += $aux; } if ($coupon != null) { if ($total >= $coupon->min_sale) { if ($coupon->type == 'Efectivo') { $descuento = $coupon->value; } if ($coupon->type == 'Porcentaje') { $descuento = ($coupon->value/100) * $total; } } } $data = [ 'amount' => money_format('%(#10n',$descuento), 'amount_unformated' => $descuento, 'total' => money_format('%(#10n', (($total+$cost_shipping)-$descuento)), 'total_unformated' => ($total+$cost_shipping)-$descuento, 'shipping' => money_format('%(#10n',$cost_shipping), 'shipping_unformated' => $cost_shipping, 'total_without'=> money_format('%(#10n',$total_without), 'total_without_unformated'=> $total_without ]; return $data; } public function search(Request $request) { $error = ['error' => 'Sin resultados, ingrese otros campos para la búsqueda.']; if($request->has('text')) { $products = Product::search($request->get('text'))->get(); return $products->count() ? $products : $error; } return $error; } public function facturacion($order_id) { $id_decript = \Crypt::decryptString($order_id); $order = Sale::find($id_decript); $data = null; $client = $order->client; $products = $order->products; $addres = $client->shipping; $billing = new Billing(); $uso_cfdi = UsoCfdi::select( \DB::raw("CONCAT(descripcion,' - Persona Física ',fisica, ', Persona Moral ', moral) AS resumen"),'clave_uso') ->pluck('resumen', 'clave_uso'); $forma_pago = [ '01' => 'Efectivo', '02' => 'Cheque Nominativo', '03' => 'Transferencia electrónica', '04' => 'Tarjeta de crédito', '28' => 'Tarjeta de débito' ]; if ($order->billing()->count() > 0 ) { $billing = $order->billing;; } $data = $this->getDiscount2($order); return view('shop-public::cart.facturacion') ->with('order', $order) ->with('order_id', $order_id) ->with('billing', $billing) ->with('client', $client) ->with('data', $data) ->with('products', $products) ->with('total', 0) ->with('uso_cfdi', $uso_cfdi) ->with('forma_pago', $forma_pago) ->with('addres', $addres); } public function facturacionStore(Request $request, $order_id) { $id_decript = \Crypt::decryptString($order_id); $order = Sale::find($id_decript); $billing = null; if ($order->billing()->count() < 1 ) { $billing = new Billing($request->all()); $order->billing()->save($billing); } else { $billing = $order->billing; $billing->fill($request->all()); $billing->save(); } return redirect() ->route('root') ->with('billing', 'billing'); } }