PosController.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. use App\Models\OrderDetail;
  5. use App\Models\ProductStock;
  6. use App\Models\Product;
  7. use App\Models\Order;
  8. use App\Models\City;
  9. use App\Models\User;
  10. use App\Models\Address;
  11. use App\Models\Addon;
  12. use Illuminate\Support\Carbon;
  13. use Session;
  14. use Auth;
  15. use Mail;
  16. use App\Mail\InvoiceEmailManager;
  17. use App\Http\Resources\PosProductCollection;
  18. use App\Models\Country;
  19. use App\Models\State;
  20. use App\Utility\CategoryUtility;
  21. use function get_setting;
  22. class PosController extends Controller
  23. {
  24. public function index()
  25. {
  26. $customers = User::where('user_type', 'customer')->where('email_verified_at', '!=', null)->orderBy('created_at', 'desc')->get();
  27. if (Auth::user()->user_type == 'admin' || Auth::user()->user_type == 'staff') {
  28. return view('pos.index', compact('customers'));
  29. }elseif (Auth::user()->user_type == 'salesman'){
  30. $customers = User::where('user_type', 'customer')->where('referred_by', '=', Auth::user()->id )->orderBy('created_at', 'desc')->get();
  31. return view('pos.salesman.index', compact('customers'));
  32. }
  33. else {
  34. if (get_setting('pos_activation_for_seller') == 1) {
  35. flash(translate('POS is disable for Sellers!!!'))->error();
  36. return back();
  37. return view('pos.frontend.seller.pos.index', compact('customers'));
  38. }
  39. else {
  40. flash(translate('POS is disable for Sellers!!!'))->error();
  41. return back();
  42. }
  43. }
  44. }
  45. public function search(Request $request)
  46. {
  47. if(Auth::user()->user_type == 'admin' || Auth::user()->user_type == 'staff'){
  48. // $products = ProductStock::join('products','product_stocks.product_id', '=', 'products.id')->where('products.added_by', 'admin')->select('products.*','product_stocks.id as stock_id','product_stocks.variant','product_stocks.price as stock_price', 'product_stocks.qty as stock_qty', 'product_stocks.image as stock_image')->orderBy('products.created_at', 'desc');
  49. $products = ProductStock::join('products','product_stocks.product_id', '=', 'products.id')->select('products.*','product_stocks.id as stock_id','product_stocks.variant','product_stocks.price as stock_price', 'product_stocks.qty as stock_qty', 'product_stocks.image as stock_image')->orderBy('products.created_at', 'desc');
  50. // $products = Product::where('added_by', 'admin')->where('published', '1');
  51. }elseif (Auth::user()->user_type == 'salesman'){
  52. $products = ProductStock::join('products','product_stocks.product_id', '=', 'products.id')->select('products.*','product_stocks.id as stock_id','product_stocks.variant','product_stocks.price as stock_price', 'product_stocks.qty as stock_qty', 'product_stocks.image as stock_image')->orderBy('products.created_at', 'desc');
  53. $users = User::where('pid', Auth::user()->id)->get()->toArray();
  54. $products = $products->whereIn('products.user_id', array_column($users, 'id'));
  55. }
  56. else {
  57. $products = ProductStock::join('products','product_stocks.product_id', '=', 'products.id')->where('user_id', Auth::user()->id)->where('published', '1')->select('products.*','product_stocks.id as stock_id','product_stocks.variant','product_stocks.price as stock_price', 'product_stocks.qty as stock_qty', 'product_stocks.image as stock_image')->orderBy('products.created_at', 'desc');
  58. // $products = Product::where('user_id', Auth::user()->id)->where('published', '1');
  59. }
  60. if($request->category != null){
  61. $arr = explode('-', $request->category);
  62. if($arr[0] == 'category'){
  63. $category_ids = CategoryUtility::children_ids($arr[1]);
  64. $category_ids[] = $arr[1];
  65. $products = $products->whereIn('products.category_id', $category_ids);
  66. }
  67. }
  68. if($request->user_id != null){
  69. $products = $products->where('products.user_id', $request->user_id);
  70. }
  71. if($request->brand != null){
  72. $products = $products->where('products.brand_id', $request->brand);
  73. }
  74. if ($request->keyword != null) {
  75. $products = $products->where('products.name', 'like', '%'.$request->keyword.'%')->orWhere('products.barcode', $request->keyword);
  76. }
  77. /*$p = $products->get();
  78. dd($p);*/
  79. $stocks = new PosProductCollection($products->paginate(16));
  80. $stocks->appends(['keyword' => $request->keyword,'category' => $request->category, 'brand' => $request->brand, 'user_id' => $request->user_id]);
  81. return $stocks;
  82. }
  83. public function addToCart(Request $request)
  84. {
  85. $stock = ProductStock::find($request->stock_id);
  86. $product = $stock->product;
  87. $data = array();
  88. $data['stock_id'] = $request->stock_id;
  89. $data['id'] = $product->id;
  90. $data['variant'] = $stock->variant;
  91. $data['quantity'] = $product->min_qty;
  92. if($stock->qty < $product->min_qty){
  93. return array('success' => 0, 'message' => translate("This product doesn't have enough stock for minimum purchase quantity ").$product->min_qty, 'view' => view('pos.cart')->render());
  94. }
  95. $tax = 0;
  96. $price = $stock->price;
  97. // discount calculation
  98. $discount_applicable = false;
  99. if ($product->discount_start_date == null) {
  100. $discount_applicable = true;
  101. }
  102. elseif (strtotime(date('d-m-Y H:i:s')) >= $product->discount_start_date &&
  103. strtotime(date('d-m-Y H:i:s')) <= $product->discount_end_date) {
  104. $discount_applicable = true;
  105. }
  106. if ($discount_applicable) {
  107. if($product->discount_type == 'percent'){
  108. $price -= ($price*$product->discount)/100;
  109. }
  110. elseif($product->discount_type == 'amount'){
  111. $price -= $product->discount;
  112. }
  113. }
  114. //tax calculation
  115. foreach ($product->taxes as $product_tax) {
  116. if($product_tax->tax_type == 'percent'){
  117. $tax += ($price * $product_tax->tax) / 100;
  118. }
  119. elseif($product_tax->tax_type == 'amount'){
  120. $tax += $product_tax->tax;
  121. }
  122. }
  123. $data['price'] = $price;
  124. $data['tax'] = $tax;
  125. if($request->session()->has('pos.cart')){
  126. $foundInCart = false;
  127. $cart = collect();
  128. foreach ($request->session()->get('pos.cart') as $key => $cartItem){
  129. if($cartItem['id'] == $product->id && $cartItem['stock_id'] == $stock->id){
  130. $foundInCart = true;
  131. $loop_product = Product::find($cartItem['id']);
  132. $product_stock = $loop_product->stocks->where('variant', $cartItem['variant'])->first();
  133. if($product_stock->qty >= ($cartItem['quantity'] + 1)){
  134. $cartItem['quantity'] += 1;
  135. }else{
  136. return array('success' => 0, 'message' => translate("This product doesn't have more stock."), 'view' => view('pos.cart')->render());
  137. }
  138. }
  139. $cart->push($cartItem);
  140. }
  141. if (!$foundInCart) {
  142. $cart->push($data);
  143. }
  144. $request->session()->put('pos.cart', $cart);
  145. }
  146. else{
  147. $cart = collect([$data]);
  148. $request->session()->put('pos.cart', $cart);
  149. }
  150. $request->session()->put('pos.cart', $cart);
  151. return array('success' => 1, 'message' => '', 'view' => view('pos.cart')->render());
  152. }
  153. //updated the quantity for a cart item
  154. public function updateQuantity(Request $request)
  155. {
  156. $cart = $request->session()->get('pos.cart', collect([]));
  157. $cart = $cart->map(function ($object, $key) use ($request) {
  158. if($key == $request->key){
  159. $product = Product::find($object['id']);
  160. $product_stock = $product->stocks->where('id', $object['stock_id'])->first();
  161. if($product_stock->qty >= $request->quantity){
  162. $object['quantity'] = $request->quantity;
  163. }else{
  164. return array('success' => 0, 'message' => translate("This product doesn't have more stock."), 'view' => view('pos.cart')->render());
  165. }
  166. }
  167. return $object;
  168. });
  169. $request->session()->put('pos.cart', $cart);
  170. return array('success' => 1, 'message' => '', 'view' => view('pos.cart')->render());
  171. }
  172. //removes from Cart
  173. public function removeFromCart(Request $request)
  174. {
  175. if(Session::has('pos.cart')){
  176. $cart = Session::get('pos.cart', collect([]));
  177. $cart->forget($request->key);
  178. Session::put('pos.cart', $cart);
  179. $request->session()->put('pos.cart', $cart);
  180. }
  181. return view('pos.cart');
  182. }
  183. //Shipping Address for admin
  184. public function getShippingAddress(Request $request){
  185. $user_id = $request->id;
  186. if($user_id == ''){
  187. return view('pos.guest_shipping_address');
  188. }
  189. else{
  190. return view('pos.shipping_address', compact('user_id'));
  191. }
  192. }
  193. //Shipping Address for seller
  194. public function getShippingAddressForSeller(Request $request){
  195. $user_id = $request->id;
  196. if($user_id == ''){
  197. return view('pos.frontend.seller.pos.guest_shipping_address');
  198. }
  199. else{
  200. return view('pos.frontend.seller.pos.shipping_address', compact('user_id'));
  201. }
  202. }
  203. public function set_shipping_address(Request $request) {
  204. if ($request->address_id != null) {
  205. $address = Address::findOrFail($request->address_id);
  206. $data['name'] = $address->user->name;
  207. $data['email'] = $address->user->email;
  208. $data['address'] = $address->address;
  209. $data['country'] = $address->country->name;
  210. $data['state'] = $address->state->name;
  211. $data['city'] = $address->city->name;
  212. $data['postal_code'] = $address->postal_code;
  213. $data['phone'] = $address->phone;
  214. } else {
  215. $data['name'] = $request->name;
  216. $data['email'] = $request->email;
  217. $data['address'] = $request->address;
  218. $data['country'] = Country::find($request->country_id)->name;
  219. $data['state'] = State::find($request->state_id)->name;
  220. $data['city'] = City::find($request->city_id)->name;
  221. $data['postal_code'] = $request->postal_code;
  222. $data['phone'] = $request->phone;
  223. }
  224. $shipping_info = $data;
  225. $request->session()->put('pos.shipping_info', $shipping_info);
  226. }
  227. //set Discount
  228. public function setDiscount(Request $request){
  229. if($request->discount >= 0){
  230. Session::put('pos.discount', $request->discount);
  231. }
  232. return view('pos.cart');
  233. }
  234. //set Shipping Cost
  235. public function setShipping(Request $request){
  236. if($request->shipping != null){
  237. Session::put('pos.shipping', $request->shipping);
  238. }
  239. return view('pos.cart');
  240. }
  241. //order summary
  242. public function get_order_summary(Request $request){
  243. return view('pos.order_summary');
  244. }
  245. //order place
  246. public function order_store(Request $request){
  247. if(Session::get('pos.shipping_info') == null || Session::get('pos.shipping_info')['name'] == null || Session::get('pos.shipping_info')['phone'] == null || Session::get('pos.shipping_info')['address'] == null){
  248. return array('success' => 0, 'message' => translate("Please Add Shipping Information."));
  249. }
  250. if(Session::has('pos.cart') && count(Session::get('pos.cart')) > 0){
  251. $order = new Order;
  252. $shipping_info = Session::get('pos.shipping_info');
  253. if ($request->user_id == null) {
  254. $order->guest_id = mt_rand(100000, 999999);
  255. }
  256. else {
  257. $order->user_id = $request->user_id;
  258. }
  259. $data['name'] = $shipping_info['name'];
  260. $data['email'] = $shipping_info['email'];
  261. $data['address'] = $shipping_info['address'];
  262. $data['country'] = $shipping_info['country'];
  263. $data['city'] = $shipping_info['city'];
  264. $data['postal_code'] = $shipping_info['postal_code'];
  265. $data['phone'] = $shipping_info['phone'];
  266. $order->shipping_address = json_encode($data);
  267. $order->payment_type = $request->payment_type;
  268. $order->delivery_viewed = '0';
  269. $order->payment_status_viewed = '0';
  270. $order->code = date('Ymd-His').rand(10,99);
  271. $order->date = strtotime('now');
  272. $order->payment_status = $request->payment_type != 'cash_on_delivery' ? 'paid' : 'unpaid';
  273. $order->payment_details = $request->payment_type;
  274. if($request->payment_type == 'offline_payment'){
  275. if($request->offline_trx_id == null){
  276. return array('success' => 0, 'message' => translate("Transaction ID can not be null."));
  277. }
  278. $data['name'] = $request->offline_payment_method;
  279. $data['amount'] = $request->offline_payment_amount;
  280. $data['trx_id'] = $request->offline_trx_id;
  281. $data['photo'] = $request->offline_payment_proof;
  282. $order->manual_payment_data = json_encode($data);
  283. $order->manual_payment = 1;
  284. }
  285. $shipping_info = Session::get('pos.shipping_info');
  286. $order->picking_switch = get_setting('picking_switch');
  287. if($order->save()){
  288. $subtotal = 0;
  289. $tax = 0;
  290. $productStorehouseTotal = 0;
  291. foreach (Session::get('pos.cart') as $key => $cartItem){
  292. $product_stock = ProductStock::find($cartItem['stock_id']);
  293. if ($product_stock){
  294. $product = $product_stock->product;
  295. $product_variation = $product_stock->variant;
  296. $subtotal += $cartItem['price']*$cartItem['quantity'];
  297. $tax += $cartItem['tax']*$cartItem['quantity'];
  298. // 计算产品仓库的产品货款
  299. $originalProduct = null;
  300. if ($product->original_id) {
  301. $originalProduct = Product::query()->find($product->original_id);
  302. if ($originalProduct) {
  303. $productStorehouseTotal += cart_product_price($cartItem, $originalProduct, false, false) * $cartItem['quantity'];
  304. }
  305. }
  306. if($cartItem['quantity'] > $product_stock->qty){
  307. $order->delete();
  308. return array('success' => 0, 'message' => $product->name.' ('.$product_variation.') '.translate(" just stock outs."));
  309. }
  310. else {
  311. $product_stock->qty -= $cartItem['quantity'];
  312. $product_stock->save();
  313. }
  314. $order_detail = new OrderDetail;
  315. $order_detail->order_id =$order->id;
  316. $order_detail->seller_id = $product->user_id;
  317. $order_detail->product_id = $product->id;
  318. $order_detail->payment_status = $request->payment_type != 'cash_on_delivery' ? 'paid' : 'unpaid';
  319. $order_detail->variation = $product_variation;
  320. $order_detail->price = $cartItem['price'] * $cartItem['quantity'];
  321. $order_detail->tax = $cartItem['tax'] * $cartItem['quantity'];
  322. $order_detail->quantity = $cartItem['quantity'];
  323. $order_detail->shipping_type = null;
  324. if (Session::get('pos.shipping', 0) >= 0){
  325. $order_detail->shipping_cost = Session::get('pos.shipping', 0)/count(Session::get('pos.cart'));
  326. }
  327. else {
  328. $order_detail->shipping_cost = 0;
  329. }
  330. $order_detail->save();
  331. $product->num_of_sale++;
  332. $product->save();
  333. }
  334. }
  335. $order->grand_total = $subtotal + $tax + Session::get('pos.shipping', 0);
  336. if(Session::has('pos.discount')){
  337. $order->grand_total -= Session::get('pos.discount');
  338. $order->coupon_discount = Session::get('pos.discount');
  339. }
  340. $order->seller_id = $product->user_id;
  341. $order->product_storehouse_total = $productStorehouseTotal;
  342. $order->save();
  343. if ( get_setting('picking_switch') != 1 )
  344. {//如果不需要提货,直接修改订单为已提货状态
  345. $shop = $order->shop;
  346. $shop->admin_to_pay += ( $order->grand_total - $order->product_storehouse_total );
  347. $shop->save();
  348. // 保存订单冻结资金过期时间
  349. $freezeDays = get_setting('frozen_funds_unfrozen_days', 15);
  350. $order->freeze_expired_at = Carbon::now()->addDays($freezeDays)->timestamp;
  351. $order->product_storehouse_status = 1;
  352. $order->save();
  353. }
  354. $array['view'] = 'emails.invoice';
  355. $array['subject'] = 'Your order has been placed - '.$order->code;
  356. $array['from'] = env('MAIL_USERNAME');
  357. $array['order'] = $order;
  358. $admin_products = array();
  359. $seller_products = array();
  360. foreach ($order->orderDetails as $key => $orderDetail){
  361. if($orderDetail->product->added_by == 'admin'){
  362. array_push($admin_products, $orderDetail->product->id);
  363. }
  364. else{
  365. $product_ids = array();
  366. if(array_key_exists($orderDetail->product->user_id, $seller_products)){
  367. $product_ids = $seller_products[$orderDetail->product->user_id];
  368. }
  369. array_push($product_ids, $orderDetail->product->id);
  370. $seller_products[$orderDetail->product->user_id] = $product_ids;
  371. }
  372. }
  373. foreach($seller_products as $key => $seller_product){
  374. try {
  375. Mail::to(User::find($key)->email)->queue(new InvoiceEmailManager($array));
  376. } catch (\Exception $e) {
  377. }
  378. }
  379. //sends email to customer with the invoice pdf attached
  380. if(env('MAIL_USERNAME') != null){
  381. try {
  382. Mail::to($request->session()->get('pos.shipping_info')['email'])->queue(new InvoiceEmailManager($array));
  383. Mail::to(User::where('user_type', 'admin')->first()->email)->queue(new InvoiceEmailManager($array));
  384. } catch (\Exception $e) {
  385. }
  386. }
  387. if($request->user_id != NULL){
  388. if (Addon::where('unique_identifier', 'club_point')->first() != null && Addon::where('unique_identifier', 'club_point')->first()->activated) {
  389. $clubpointController = new ClubPointController;
  390. $clubpointController->processClubPoints($order);
  391. }
  392. }
  393. calculateCommissionAffilationClubPoint($order);
  394. Session::forget('pos.shipping_info');
  395. Session::forget('pos.shipping');
  396. Session::forget('pos.discount');
  397. Session::forget('pos.cart');
  398. return array('success' => 1, 'message' => translate('Order Completed Successfully.'));
  399. }
  400. else {
  401. return array('success' => 0, 'message' => translate('Please input customer information.'));
  402. }
  403. }
  404. return array('success' => 0, 'message' => translate("Please select a product."));
  405. }
  406. public function pos_activation()
  407. {
  408. return view('pos.pos_activation');
  409. }
  410. }