with = ['file'/*, 'price', 'default', 'sub'*/]; // $this->with = []; parent::__construct(Product::class, $this->with, ['*'], null, null, ['title']); } public function tableProduct(Request $request) { $data = $request->all(); if (isset($data["select"]) && is_null($data["select"])){ $data["select"] = []; } if (is_null($this->query)){ $query_table = $this->model::with($this->with); //*******کداضافه شده // ->where('active', '<=', now()) // فیلتر محصولات فعال // ->get(); //********* }else{ $query_table = $this->query; // $query_table = $query_table->where('active', '<=', now()); } TableEngine::create($query_table, $data) ->initSearch($this->search) ->select($this->select) ->export($query_table); if (Schema::hasColumn((new Product)->getTable(), 'auto_open_at')) { $query_table['auto_open_at'] = Product::selectRaw( 'SEC_TO_TIME(AVG(TIME_TO_SEC(TIME(auto_open_at)))) as avg_time' )->value('avg_time'); } if (Schema::hasColumn((new Product)->getTable(), 'auto_close_at')) { $query_table['auto_close_at'] = Product::selectRaw( 'SEC_TO_TIME(AVG(TIME_TO_SEC(TIME(auto_close_at)))) as avg_time' )->value('avg_time'); } // $query_table['11'] = $avgDuration; // $query_table['11'] = Product::avg('auto_open_at'); // $query_table['112'] = Product::avg('auto_close_at'); return $query_table; } public function editProducts(Request $request) { if (isset($request->auto_open_at, $request->auto_close_at)) { Product::query()->update([ 'auto_open_at' => $request->auto_open_at, 'auto_close_at' => $request->auto_close_at, ]); return response()->json(['message' => 'Products updated successfully.']); } return response()->json(['error' => 'auto_open_at and auto_close_at must be set'], 400); } public function store(Request $request) { $data = $this->filterProductData($request->all()); $product = Product::create($data); return $this->resultCreate($product->id); } public function update(Request $request, $id) { // return 1; $data = $this->filterProductData($request->all()); $clearingReadingMethod = array_key_exists('reading_method', $data) && ($data['reading_method'] === null || $data['reading_method'] === ''); if ($clearingReadingMethod) { $data['reading_method'] = null; } if (isset($data["price"])) { $data["reading_method"] = null; if (Product::hasPriceOffsetColumn()) { $data['price_offset_percent'] = 0; } } if (isset($data["auto_close_at"]) and isset($data["auto_close_at"])){ if ($data["auto_close_at"] == $data["auto_open_at"]){ unset($data["auto_open_at"]); unset($data["auto_close_at"]); } } // return $data['price']; // if(!isset($data['default'])){ // throw new UnprocessableEntityHttpException('مقادیر اعتبارات را وارد کنید'); // } // $data['auto_open_at'] = Carbon::parse($data['auto_open_at'])->format('Y-m-d H:i:s'); // $data['auto_close_at'] = Carbon::parse($data['auto_close_at'])->format('Y-m-d H:i:s'); $product = Product::findOrFail($id); $oldOffsetPercent = (float) ($product->price_offset_percent ?? 0); if ( Product::hasPriceOffsetColumn() && $product->reading_method && array_key_exists('price_offset_percent', $data) && !$clearingReadingMethod ) { ProductPriceService::reapplyOffsetPercent( $product, (float) $data['price_offset_percent'], $oldOffsetPercent ); unset($data['price'], $data['price_profit']); } $product->update($data); return response()->json(true); } public function destroy($id) { Product::findOrFail($id)->delete(); return response()->json(true); } public function listProduct() { if (app(ConfigService::class)->isStore()) { app(ProductPriceSyncService::class)->syncStorePrices(true); if (! str_contains(request()->path(), '/customer/')) { $this->auto_close_open(); } $products = Product::with(['file'])->where('active', 1)->get(); if (str_contains(request()->path(), '/customer/')) { $products->each(function (Product $product) { $product->setAttribute('show', $this->storeProductShowForCustomer($product)); }); } return response()->json($products); } // آبشده خانگی — ادمین: sync از کش؛ کاربر: enrich بدون UPDATE if (! str_contains(request()->path(), '/customer/')) { app(ProductPriceSyncService::class)->syncAll(false); } $products = Product::with(['file'])->where('active', 1)->get(); if (str_contains(request()->path(), '/customer/')) { $displayPriceService = app(ProductDisplayPriceService::class); $displayPriceService->enrichForApi($products); $products->each(function (Product $product) use ($displayPriceService) { if (! $displayPriceService->hasCustomerDisplayPrice($product)) { $product->setAttribute('show', false); } }); } if (Product::hasPriceOffsetColumn() && str_contains(request()->path(), '/customer/')) { $products->each(function (Product $product) { if ($product->reading_method) { $product->makeHidden(['price_offset_percent']); } }); } return response()->json($products); } public function ProductById($id) { app(ProductPriceSyncService::class)->syncStorePrices(true); $this->auto_close_open(); $product = Product::with(['file']) ->where('id', $id) ->first(); if ($product) { $product->similar = Product::with(['file']) ->where('group_type', $product->group_type) ->where('id', '!=', $id) ->get(); } else { return response()->json(false); } return response()->json($product); } public function getPrice() { if (app(ConfigService::class)->isStore()) { app(ProductPriceSyncService::class)->syncStorePrices(true); } else { app(ProductPriceSyncService::class)->syncAll(true); } return response()->json(true); } public function auto_close_open() { $products = Product::with([])->get(); $current_time = now()->format('H:i:s'); foreach ($products as $product) { $show = ($current_time >= $product->auto_open_at && $current_time <= $product->auto_close_at); Product::where('id', $product->id)->update([ 'show' => $show, ]); } return response()->json(true); } public function getProduct($id) { $product = Product::with($this->with)->where('id', $id)->first(); return response()->json($product); } /** * فعال/غیرفعال محصول — show باید با active هم‌گام باشد (اپ کاربر از show استفاده می‌کند). */ public function active($id) { $product = Product::findOrFail($id); $active = !$product->active; $product->update([ 'active' => $active, 'show' => $active, ]); return response()->json(true); } public function hide($id) { $query = Product::findOrFail($id); $query->update([ 'show' => !$query->show ]); return response()->json(true); } public function openSell($id) { return $this->toggleBooleanStatus($id, 'open_sell'); } public function openBuy($id) { return $this->toggleBooleanStatus($id, 'open_buy'); } public function auto_buy($id) { return $this->toggleBooleanStatus($id, 'auto_buy'); } public function auto_sell($id) { return $this->toggleBooleanStatus($id, 'auto_sell'); } private function toggleBooleanStatus($id, $field) { $product = Product::findOrFail($id); $product->$field = !$product->$field; $product->save(); if (!$product->open_buy and !$product->open_sell) { $product->show = false; $product->active = false; } else { $product->show = true; $product->active = true; } $product->save(); return response()->json($product->$field); } public function auto_group($action, $method) { // Define valid actions and methods $validActions = ['sell' => 'auto_sell', 'buy' => 'auto_buy', 'all' => ['auto_buy', 'auto_sell']]; $validMethods = ['true' => 1, 'false' => 0]; // Validate action and method if (!isset($validActions[$action]) || !array_key_exists($method, $validMethods)) { return response()->json(['error' => 'Invalid action or method'], 400); } // Get fields to update and value to set $fields = $validActions[$action]; $value = $validMethods[$method]; // Update products Product::query()->update(array_fill_keys((array)$fields, $value)); return response()->json(true); } public function updatePrice(Request $request){ } /** فروشگاه — نمایش در اپ کاربر: فعال + قیمت ذخیره‌شده یا محصول وزنی */ private function storeProductShowForCustomer(Product $product): bool { if (! $product->active) { return false; } $storedPrice = (int) ($product->price ?? 0) + (int) ($product->price_profit ?? 0); if ($storedPrice > 0) { return true; } if ((int) ($product->direct_price ?? 0) === 0 && (float) ($product->amount ?? 0) > 0) { return true; } return false; } private function filterProductData(array $data): array { if (!Product::hasPriceOffsetColumn()) { unset($data['price_offset_percent']); } if (!Product::hasOrderLimitColumns()) { unset($data['order_limit_enabled'], $data['min_order_cash'], $data['max_order_cash']); } elseif (empty($data['order_limit_enabled'])) { $data['order_limit_enabled'] = false; $data['min_order_cash'] = null; $data['max_order_cash'] = null; } else { $min = $data['min_order_cash'] ?? null; $max = $data['max_order_cash'] ?? null; $hasMin = $min !== null && $min !== ''; $hasMax = $max !== null && $max !== ''; if (!$hasMin && !$hasMax) { throw new UnprocessableEntityHttpException( 'با فعال بودن محدودیت مبلغ سفارش، حداقل یکی از حداقل یا حداکثر مبلغ باید وارد شود' ); } if ($hasMin && $hasMax && (float) $min > (float) $max) { throw new UnprocessableEntityHttpException('حداقل مبلغ نمی‌تواند بیشتر از حداکثر باشد'); } $data['order_limit_enabled'] = true; $data['min_order_cash'] = $hasMin ? (int) $min : null; $data['max_order_cash'] = $hasMax ? (int) $max : null; } if (!Product::hasShowInAssetsColumn()) { unset($data['show_in_assets']); } elseif (array_key_exists('show_in_assets', $data)) { $data['show_in_assets'] = !empty($data['show_in_assets']); } if (!Product::hasUseLastPriceIfZeroColumn()) { unset($data['use_last_price_if_zero']); } elseif (array_key_exists('use_last_price_if_zero', $data)) { $data['use_last_price_if_zero'] = !empty($data['use_last_price_if_zero']); } return $data; } }