287 lines
10 KiB
PHP
Executable File
287 lines
10 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Services\API;
|
|
|
|
use App\Models\Address;
|
|
use App\Models\Billing;
|
|
use App\Models\Cart;
|
|
use App\Models\City;
|
|
use App\Models\Currency;
|
|
use App\Models\DeliveryPrice;
|
|
use App\Models\Order;
|
|
use App\Models\OrderContract;
|
|
use App\Models\Power;
|
|
use App\Models\Product;
|
|
use App\Models\Setting;
|
|
use App\Models\UserLegalInfo;
|
|
use App\Models\OrderProducts;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class OrderService
|
|
{
|
|
protected $data;
|
|
public $order;
|
|
protected $user;
|
|
protected $address_id = null;
|
|
protected $phone = null;
|
|
protected $full_name = null;
|
|
protected $legal_id = null;
|
|
public $billing;
|
|
protected $total;
|
|
protected $currency;
|
|
|
|
public function __construct(array $data)
|
|
{
|
|
$this->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();
|
|
}
|
|
}
|
|
}
|
|
|