currency = Currency::orderBy('id', 'desc')->first()->dollar; $this->data = $data; $this->user = request()->user(); } private function calc() { $products_cart = collect($this->data['products']); $product_ids = $products_cart->pluck('id'); $products = Product::whereNull('child_id')->whereIn('id', $product_ids)->get(); $price_delivery = 0; $price_master = 0; foreach ($products_cart as $cart) { $product = Product::query()->whereNull('child_id')->where('id', $cart['id'])->first(); if (!empty($product)) { if ($product->count < $cart['count']) { throw new \Exception($product->getName() . ' - ' . trans('app.errors.count'), 403); } } } //delivery price if ($this->data['delivery_type'] == 'delivery') { $delivery_products = $products->map(function ($product) use ($products_cart) { $product->power_delivery = $product->power * $products_cart->filter(function ($cart) use ($product) { return $cart['id'] == $product->id; })->value('count'); return $product; }); $power = Power::where('power', '>=', $delivery_products->sum('power_delivery'))->first(); if (empty($power)) { $power_id = 0; } else { $power_id = $power->id; } $city = City::where('id', $this->data['address']['city_id'])->first(); $price_delivery = DeliveryPrice::where('power_id', $power_id)->where('region_id', $city->region_id)->first(); $price_delivery = $price_delivery->price ?? 0; } //delivery price end //master price $power = 0; if ($this->data['type'] == 'ready_solutions') { $settings = Setting::query()->first(); $power_products = $products->map(function ($product) use ($products_cart) { $product->pp = $product->power; $product->power_master = $product->power * $products_cart->filter(function ($cart) use ($product) { return $cart['id'] == $product->id; })->value('count'); return $product; }); $power = $power_products->sum('power_master') / 1000; $price_master = $power * $settings->master_price; } //master price end $price = $products->filter(function ($product) use ($products_cart) { foreach ($products_cart as $p_cart) { if ($p_cart['id'] == $product->id) { return $product->count >= $p_cart['count']; } } })->map(function ($product) use ($products_cart) { foreach ($products_cart as $p_cart) { if ($p_cart['id'] == $product->id) { if (!empty($product->price_discount)) { $product->price_total = ceiling($product->price_discount * $this->currency, 100) * $p_cart['count']; } else { $product->price_total = ceiling($product->price * $this->currency, 100) * $p_cart['count']; } } } return $product; })->sum('price_total'); if ($this->data['with_installation']) { $price_master = $price_master; } else { $price_master = 0; } $this->total = $price + $price_delivery + $price_master; return [ 'power' => $power, 'price_delivery' => $price_delivery, 'price_master' => $price_master, 'price_products' => $price, 'price_total' => $this->total ]; } public function createOrder() { if ($this->data['delivery_type'] == 'delivery') $this->storeAddress(); if ($this->data['client_type'] == 'legal') { $this->storeLegalClientInformation(); } $this->storeOrder(); $this->storeProducts(); if (!in_array($this->data['payment_type'], ['cash', 'bank'])) { $this->storeBilling(); } else { // generate contract $lang = request()->header('Accept-Language') ?? 'ru'; $contract = new ContractService($this->order, $lang, $this->data['client_type']); $contractPath = $contract->generate(); // store OrderContract $this->storeOrderContract($contractPath); } // orders contract return $this; } private function storeOrderContract($contractPath) { OrderContract::create([ 'order_id' => $this->order->id, 'path' => $contractPath, 'type' => 'contract' //TODO: for now ]); } private function storeBilling() { $this->billing = Billing::create([ 'order_id' => $this->order->id, 'amount' => $this->total, 'payment_system' => $this->data['payment_type'] ]); return $this; } private function storeAddress() { $address = Address::create([ 'user_id' => $this->user->id, 'city_id' => $this->data['address']['city_id'], 'address' => isset($this->data['address']['address']) ? $this->data['address']['address'] : null, 'home' => isset($this->data['address']['home']) ? $this->data['address']['home'] : null, 'landmark' => isset($this->data['address']['landmark']) ? $this->data['address']['landmark'] : null, ]); $this->address_id = $address->id; return $this; } private function storeLegalClientInformation() { $legal_user = UserLegalInfo::create([ 'user_id' => $this->user->id, 'director_full_name' => $this->data['client_information']['director_full_name'], 'company_name' => $this->data['client_information']['company_name'], 'inn' => $this->data['client_information']['inn'], 'bank_name' => $this->data['client_information']['bank_name'], 'mfo' => $this->data['client_information']['mfo'], 'oked' => $this->data['client_information']['oked'], 'payment_account' => $this->data['client_information']['payment_account'], 'address' => $this->data['client_information']['address'], 'email' => isset($this->data['client_information']['email']) ?? null, 'phone' => $this->data['client_information']['phone'], ]); $this->legal_id = $legal_user->id; return $this; } public function storeOrder() { if (!empty($this->data['client_information']) && !empty($this->data['client_information']['phone'])) { $this->phone = $this->data['client_information']['phone']; } if (!empty($this->data['client_information']) && !empty($this->data['client_information']['full_name'])) { $this->full_name = $this->data['client_information']['full_name']; } $currency = Currency::orderBy('id', 'desc')->first(); $calc = $this->calc(); if ($this->data['payment_type'] == 'cash') { $payment_status = 'cash'; } else { $payment_status = 'processing'; } $this->order = Order::create([ 'phone' => $this->phone, 'full_name' => $this->full_name, 'legal_id' => $this->legal_id, 'user_id' => $this->user->id, "jshir" => $this->data["client_information"]['jshir'] ?? null, "series" => $this->data["client_information"]['series'] ?? null, 'type' => $this->data['type'], 'delivery_type' => $this->data['delivery_type'], 'client_type' => $this->data['client_type'], 'address_id' => $this->address_id, 'with_installation' => isset($this->data['with_installation']) ? $this->data['with_installation'] : false, 'payment_type' => $this->data['payment_type'], 'with_didox' => isset($this->data['with_didox']) ? $this->data['with_didox'] : false, 'branch_id' => isset($this->data['branch_id']) ? $this->data['branch_id'] : null, 'currency' => $currency->id, 'payment_status' => $payment_status, 'price_products' => $calc['price_products'], 'price_delivery' => $calc['price_delivery'], 'price_master' => $calc['price_master'], 'price_total' => $calc['price_total'] ]); return $this; } private function storeProducts() { foreach ($this->data['products'] as $row) { $product = Product::whereNull('child_id')->where('id', $row['id'])->first(); if (empty($product)) { throw new \Exception(trans('admin.Product not found'), 404); } $product->count = $product->count - (int) $row['count']; $product->save(); Log::info('Product count updated', ['product_id' => $product->id, 'count' => $product->count]); OrderProducts::create([ 'order_id' => $this->order->id, 'product_id' => $row['id'], 'count' => $row['count'], 'price' => $product->price, 'discount' => $product->price_discount, ]); Cart::where('user_id', $this->user->id)->where('product_id', $row['id'])->delete(); } } }