Files
boursecu_server/app/Http/Controllers/Admin/CustomerSpecialPricePackageController.php
T

265 lines
9.5 KiB
PHP
Raw Normal View History

2026-08-16 22:00:23 +03:30
<?php
namespace App\Http\Controllers\Admin;
use App\DB\Te\TableEngine;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\CustomerSpecialPricePackage;
use App\Models\Product;
use App\Services\ConfigService;
use App\Services\CustomerSpecialPricingService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
class CustomerSpecialPricePackageController extends Controller
{
public function table(Request $request)
{
$this->assertFeatureEnabled();
$query = CustomerSpecialPricePackage::query()
->withCount(['customers', 'products'])
->orderByDesc('id');
TableEngine::create($query, $request->all())
->initSearch(['title'])
->select(['*'])
->export($query);
return $query;
}
public function show(int $id)
{
$this->assertFeatureEnabled();
$package = CustomerSpecialPricePackage::query()
->with([
'customers:id,name,mobile',
'products:id,title,group_type',
])
->findOrFail($id);
$categoryNames = [];
if (Schema::hasTable('customer_special_price_package_category')) {
$categoryNames = DB::table('customer_special_price_package_category')
->where('package_id', $package->id)
->pluck('category_name')
->all();
}
return response()->json([
'package' => $package,
'customer_ids' => $package->customers->pluck('id')->values(),
'product_ids' => $package->products->pluck('id')->values(),
'category_names' => array_values($categoryNames),
'customers' => $package->customers,
'products' => $package->products,
]);
}
public function store(Request $request)
{
$this->assertFeatureEnabled();
$data = $this->validatedPayload($request);
$warnings = app(CustomerSpecialPricingService::class)->overlapWarnings(
$data['customer_ids'],
$data['product_ids']
);
$package = DB::transaction(function () use ($data) {
$package = CustomerSpecialPricePackage::create([
'title' => $data['title'],
'profit_buy' => $data['profit_buy'],
'profit_sell' => $data['profit_sell'],
'show_product' => $data['show_product'],
'is_active' => $data['is_active'],
]);
$this->syncRelations($package, $data);
return $package->fresh();
});
return response()->json([
'message' => 'پکیج قیمت ویژه ثبت شد.',
'package' => $package,
'warnings' => $warnings,
]);
}
public function update(Request $request, int $id)
{
$this->assertFeatureEnabled();
$package = CustomerSpecialPricePackage::findOrFail($id);
$data = $this->validatedPayload($request);
$warnings = app(CustomerSpecialPricingService::class)->overlapWarnings(
$data['customer_ids'],
$data['product_ids'],
(int) $package->id
);
DB::transaction(function () use ($package, $data) {
$package->update([
'title' => $data['title'],
'profit_buy' => $data['profit_buy'],
'profit_sell' => $data['profit_sell'],
'show_product' => $data['show_product'],
'is_active' => $data['is_active'],
]);
$this->syncRelations($package, $data);
});
return response()->json([
'message' => 'پکیج قیمت ویژه به‌روز شد.',
'package' => $package->fresh(),
'warnings' => $warnings,
]);
}
public function destroy(int $id)
{
$this->assertFeatureEnabled();
$package = CustomerSpecialPricePackage::findOrFail($id);
DB::transaction(function () use ($package) {
$package->customers()->detach();
$package->products()->detach();
if (Schema::hasTable('customer_special_price_package_category')) {
DB::table('customer_special_price_package_category')->where('package_id', $package->id)->delete();
}
$package->delete();
});
return response()->json(['message' => 'پکیج حذف شد.']);
}
public function toggleActive(int $id)
{
$this->assertFeatureEnabled();
$package = CustomerSpecialPricePackage::findOrFail($id);
$package->is_active = ! $package->is_active;
$package->save();
return response()->json([
'message' => $package->is_active ? 'پکیج فعال شد.' : 'پکیج غیرفعال شد.',
'is_active' => $package->is_active,
]);
}
public function searchCustomers(Request $request)
{
$this->assertFeatureEnabled();
$q = trim((string) $request->get('q', ''));
$rows = Customer::query()
->where('type', 2)
->where(function ($query) {
$query->where('is_archive', false)->orWhereNull('is_archive');
})
->when($q !== '', function ($query) use ($q) {
$query->where(function ($inner) use ($q) {
$inner->where('name', 'like', '%' . $q . '%')
->orWhere('mobile', 'like', '%' . $q . '%')
->orWhere('id', $q);
});
})
->orderByDesc('id')
->limit(40)
->get(['id', 'name', 'mobile']);
return response()->json(['customers' => $rows]);
}
public function productsByCategories(Request $request)
{
$this->assertFeatureEnabled();
$names = array_values(array_filter(array_map('strval', (array) $request->input('category_names', []))));
if ($names === []) {
return response()->json(['products' => []]);
}
$products = Product::query()
->whereIn('group_type', $names)
->orderBy('title')
->get(['id', 'title', 'group_type', 'active']);
return response()->json(['products' => $products]);
}
private function validatedPayload(Request $request): array
{
$title = trim((string) $request->input('title', ''));
if ($title === '') {
throw new UnprocessableEntityHttpException('عنوان پکیج الزامی است.');
}
$customerIds = array_values(array_unique(array_filter(array_map('intval', (array) $request->input('customer_ids', [])))));
$productIds = array_values(array_unique(array_filter(array_map('intval', (array) $request->input('product_ids', [])))));
$categoryNames = array_values(array_unique(array_filter(array_map(
fn ($n) => trim((string) $n),
(array) $request->input('category_names', [])
))));
if ($customerIds === []) {
throw new UnprocessableEntityHttpException('حداقل یک کاربر انتخاب کنید.');
}
if ($categoryNames === []) {
throw new UnprocessableEntityHttpException('حداقل یک گروه دسته‌بندی انتخاب کنید.');
}
if ($productIds === []) {
throw new UnprocessableEntityHttpException('حداقل یک محصول انتخاب کنید.');
}
$profitBuy = (int) preg_replace('/[^\d]/', '', (string) $request->input('profit_buy', 0));
$profitSell = (int) preg_replace('/[^\d]/', '', (string) $request->input('profit_sell', 0));
return [
'title' => $title,
'customer_ids' => $customerIds,
'product_ids' => $productIds,
'category_names' => $categoryNames,
'profit_buy' => max(0, $profitBuy),
'profit_sell' => max(0, $profitSell),
'show_product' => filter_var($request->input('show_product', true), FILTER_VALIDATE_BOOLEAN),
'is_active' => filter_var($request->input('is_active', true), FILTER_VALIDATE_BOOLEAN),
];
}
private function syncRelations(CustomerSpecialPricePackage $package, array $data): void
{
$package->customers()->sync($data['customer_ids']);
$package->products()->sync($data['product_ids']);
if (Schema::hasTable('customer_special_price_package_category')) {
DB::table('customer_special_price_package_category')->where('package_id', $package->id)->delete();
$rows = [];
foreach ($data['category_names'] as $name) {
$rows[] = [
'package_id' => $package->id,
'category_name' => $name,
];
}
if ($rows !== []) {
DB::table('customer_special_price_package_category')->insert($rows);
}
}
}
private function assertFeatureEnabled(): void
{
if (! app(CustomerSpecialPricingService::class)->tablesReady()) {
throw new UnprocessableEntityHttpException('جدول پکیج قیمت ویژه وجود ندارد. مایگریشن را اجرا کنید.');
}
if (! app(ConfigService::class)->getBool(CustomerSpecialPricingService::SETTING_KEY, false)) {
throw new UnprocessableEntityHttpException('قابلیت قیمت ویژه مشتری غیرفعال است.');
}
}
}