feat(convert): let customers list and change pending requests
History is limited to the signed-in customer. Update and delete only apply while the request is still pending. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -10,6 +10,16 @@ use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
|||||||
|
|
||||||
class CopperConvertRequestController extends Controller
|
class CopperConvertRequestController extends Controller
|
||||||
{
|
{
|
||||||
|
public function index(CopperConvertRequestService $service)
|
||||||
|
{
|
||||||
|
$customer = auth('customer')->user();
|
||||||
|
if (!$customer instanceof Customer) {
|
||||||
|
throw new UnprocessableEntityHttpException('مشتری یافت نشد.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json($service->listForCustomer($customer));
|
||||||
|
}
|
||||||
|
|
||||||
public function store(Request $request, CopperConvertRequestService $service)
|
public function store(Request $request, CopperConvertRequestService $service)
|
||||||
{
|
{
|
||||||
$customer = auth('customer')->user();
|
$customer = auth('customer')->user();
|
||||||
@@ -35,4 +45,45 @@ class CopperConvertRequestController extends Controller
|
|||||||
|
|
||||||
return response()->json($row);
|
return response()->json($row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function update(Request $request, int $id, CopperConvertRequestService $service)
|
||||||
|
{
|
||||||
|
$customer = $this->customer();
|
||||||
|
self::assertCustomerIdentityVerified($customer);
|
||||||
|
if (!$customer->trade_active) {
|
||||||
|
throw new UnprocessableEntityHttpException('امکان سفارش برای شما غیرفعال است.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$source = (string) $request->input('source');
|
||||||
|
if (!in_array($source, ['katod', 'maftoul', 'shamsh'], true)) {
|
||||||
|
throw new UnprocessableEntityHttpException('نوع دارایی نامعتبر است.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = $service->update(
|
||||||
|
$customer,
|
||||||
|
$id,
|
||||||
|
$source,
|
||||||
|
max(0, (int) $request->input('rings15')),
|
||||||
|
max(0, (int) $request->input('rings25'))
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json($row);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy(int $id, CopperConvertRequestService $service)
|
||||||
|
{
|
||||||
|
$service->remove($this->customer(), $id);
|
||||||
|
|
||||||
|
return response()->json(['ok' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function customer(): Customer
|
||||||
|
{
|
||||||
|
$customer = auth('customer')->user();
|
||||||
|
if (!$customer instanceof Customer) {
|
||||||
|
throw new UnprocessableEntityHttpException('مشتری یافت نشد.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $customer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,22 +30,32 @@ class CopperConvertRequestService
|
|||||||
|
|
||||||
$quote = $this->quote($customer, $source, $rings15, $rings25);
|
$quote = $this->quote($customer, $source, $rings15, $rings25);
|
||||||
|
|
||||||
return CopperConvertRequest::query()->create([
|
return CopperConvertRequest::query()->create(
|
||||||
'customer_id' => $customer->id,
|
$this->quoteAttributes($customer, $source, $rings15, $rings25, $quote)
|
||||||
'status' => 'pending',
|
);
|
||||||
'source' => $source,
|
}
|
||||||
'source_product_id' => $quote['source']->id,
|
|
||||||
'asset_unit' => $quote['unit'],
|
public function update(Customer $customer, int $id, string $source, int $rings15, int $rings25): CopperConvertRequest
|
||||||
'consumed_amount' => $quote['consumed'],
|
{
|
||||||
'leftover_amount' => $quote['leftover'],
|
if ($rings15 < 1 && $rings25 < 1) {
|
||||||
'source_unit_price' => $quote['source_unit_price'],
|
throw new UnprocessableEntityHttpException('حداقل یک حلقه انتخاب کنید.');
|
||||||
'wire15_product_id' => $quote['wire15']?->id,
|
}
|
||||||
'wire15_rings' => $rings15,
|
|
||||||
'wire15_unit_price' => $quote['price15'],
|
return DB::transaction(function () use ($customer, $id, $source, $rings15, $rings25) {
|
||||||
'wire25_product_id' => $quote['wire25']?->id,
|
$row = $this->ownedPending($customer, $id);
|
||||||
'wire25_rings' => $rings25,
|
$quote = $this->quote($customer, $source, $rings15, $rings25);
|
||||||
'wire25_unit_price' => $quote['price25'],
|
$row->fill($this->quoteAttributes($customer, $source, $rings15, $rings25, $quote));
|
||||||
]);
|
$row->save();
|
||||||
|
|
||||||
|
return $row;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove(Customer $customer, int $id): void
|
||||||
|
{
|
||||||
|
DB::transaction(function () use ($customer, $id) {
|
||||||
|
$this->ownedPending($customer, $id)->delete();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function listForAdmin(): array
|
public function listForAdmin(): array
|
||||||
@@ -82,6 +92,29 @@ class CopperConvertRequestService
|
|||||||
->all();
|
->all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function listForCustomer(Customer $customer): array
|
||||||
|
{
|
||||||
|
return CopperConvertRequest::query()
|
||||||
|
->where('customer_id', $customer->id)
|
||||||
|
->orderByDesc('id')
|
||||||
|
->limit(50)
|
||||||
|
->get()
|
||||||
|
->map(function (CopperConvertRequest $row) {
|
||||||
|
return [
|
||||||
|
'id' => $row->id,
|
||||||
|
'status' => $row->status,
|
||||||
|
'source' => $row->source,
|
||||||
|
'asset_unit' => $row->asset_unit,
|
||||||
|
'consumed_amount' => $row->consumed_amount,
|
||||||
|
'leftover_amount' => $row->leftover_amount,
|
||||||
|
'wire15_rings' => $row->wire15_rings,
|
||||||
|
'wire25_rings' => $row->wire25_rings,
|
||||||
|
'created_at' => optional($row->created_at)->toDateTimeString(),
|
||||||
|
];
|
||||||
|
})
|
||||||
|
->all();
|
||||||
|
}
|
||||||
|
|
||||||
public function approve(int $id, int $adminId): CopperConvertRequest
|
public function approve(int $id, int $adminId): CopperConvertRequest
|
||||||
{
|
{
|
||||||
$row = DB::transaction(function () use ($id, $adminId) {
|
$row = DB::transaction(function () use ($id, $adminId) {
|
||||||
@@ -166,6 +199,42 @@ class CopperConvertRequestService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function ownedPending(Customer $customer, int $id): CopperConvertRequest
|
||||||
|
{
|
||||||
|
$row = CopperConvertRequest::query()
|
||||||
|
->where('customer_id', $customer->id)
|
||||||
|
->lockForUpdate()
|
||||||
|
->find($id);
|
||||||
|
if (!$row) {
|
||||||
|
throw new UnprocessableEntityHttpException('درخواست تبدیل پیدا نشد.');
|
||||||
|
}
|
||||||
|
if ($row->status !== 'pending') {
|
||||||
|
throw new UnprocessableEntityHttpException('فقط درخواست در انتظار تایید قابل تغییر است.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function quoteAttributes(Customer $customer, string $source, int $rings15, int $rings25, array $quote): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'customer_id' => $customer->id,
|
||||||
|
'status' => 'pending',
|
||||||
|
'source' => $source,
|
||||||
|
'source_product_id' => $quote['source']->id,
|
||||||
|
'asset_unit' => $quote['unit'],
|
||||||
|
'consumed_amount' => $quote['consumed'],
|
||||||
|
'leftover_amount' => $quote['leftover'],
|
||||||
|
'source_unit_price' => $quote['source_unit_price'],
|
||||||
|
'wire15_product_id' => $quote['wire15']?->id,
|
||||||
|
'wire15_rings' => $rings15,
|
||||||
|
'wire15_unit_price' => $quote['price15'],
|
||||||
|
'wire25_product_id' => $quote['wire25']?->id,
|
||||||
|
'wire25_rings' => $rings25,
|
||||||
|
'wire25_unit_price' => $quote['price25'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
private function sourceLabel(string $source): string
|
private function sourceLabel(string $source): string
|
||||||
{
|
{
|
||||||
if ($source === 'katod') {
|
if ($source === 'katod') {
|
||||||
|
|||||||
@@ -132,7 +132,10 @@ Route::middleware(['auth:customer', 'customer.active'])->group(function () use (
|
|||||||
Route::get('order/pending', [SingleOrderController::class, 'pendingColleague']);
|
Route::get('order/pending', [SingleOrderController::class, 'pendingColleague']);
|
||||||
Route::get('order/{id}/status', [SingleOrderController::class, 'colleagueStatus']);
|
Route::get('order/{id}/status', [SingleOrderController::class, 'colleagueStatus']);
|
||||||
Route::post('order', [OrderController::class, 'store']);
|
Route::post('order', [OrderController::class, 'store']);
|
||||||
|
Route::get('copper-convert-request', [CopperConvertRequestController::class, 'index']);
|
||||||
Route::post('copper-convert-request', [CopperConvertRequestController::class, 'store']);
|
Route::post('copper-convert-request', [CopperConvertRequestController::class, 'store']);
|
||||||
|
Route::put('copper-convert-request/{id}', [CopperConvertRequestController::class, 'update']);
|
||||||
|
Route::delete('copper-convert-request/{id}', [CopperConvertRequestController::class, 'destroy']);
|
||||||
|
|
||||||
//-----------------single order
|
//-----------------single order
|
||||||
Route::post('single/order/table', [SingleOrderController::class, 'table']);
|
Route::post('single/order/table', [SingleOrderController::class, 'table']);
|
||||||
|
|||||||
Reference in New Issue
Block a user