update perbaikan pos, return, dan report profit nlost
All checks were successful
All checks were successful
This commit is contained in:
@@ -40,212 +40,65 @@ public function store(Request $request)
|
||||
'warehouse_id' => 'nullable|exists:warehouses,id',
|
||||
'type' => 'nullable|string|in:sale,purchase',
|
||||
'id' => 'required|integer',
|
||||
'name' => 'nullable|string',
|
||||
'name' => 'required|string',
|
||||
'quantity' => 'required|numeric',
|
||||
'price' => 'required|numeric',
|
||||
'product_code' => 'nullable|string',
|
||||
'product_unit_id' => 'nullable|integer',
|
||||
'product_unit_name' => 'nullable|string',
|
||||
'product_image' => 'nullable|string',
|
||||
'profit_percent' => 'nullable|numeric',
|
||||
'sales_price' => 'nullable|numeric',
|
||||
'whole_sale_price' => 'nullable|numeric',
|
||||
'dealer_price' => 'nullable|numeric',
|
||||
'expire_date' => 'nullable|date',
|
||||
'product_type' => 'nullable|in:single,variant,combo',
|
||||
'variant_name' => 'nullable|string',
|
||||
'serial_numbers' => 'nullable|array',
|
||||
'serial_numbers.*' => 'string',
|
||||
'has_serial' => 'nullable|boolean',
|
||||
'price_without_tax' => 'required_without:serial_numbers|numeric|nullable',
|
||||
'customer_type' => 'nullable|string'
|
||||
'vat_percent' => 'nullable|numeric',
|
||||
]);
|
||||
|
||||
$incomingSerials = $request->serial_numbers ?? [];
|
||||
|
||||
// Serial Mode
|
||||
if (!empty($incomingSerials)) {
|
||||
// Sale
|
||||
if ($request->type === 'sale') {
|
||||
|
||||
$stocks = Stock::where('business_id', auth()->user()->business_id)
|
||||
->where('product_id', $request->id)
|
||||
->where(function ($query) use ($incomingSerials) {
|
||||
foreach ($incomingSerials as $serial) {
|
||||
$query->orWhereJsonContains('serial_numbers', $serial);
|
||||
}
|
||||
})->get();
|
||||
|
||||
// Map serial → stock
|
||||
$serialStockMap = [];
|
||||
|
||||
foreach ($stocks as $stock) {
|
||||
foreach ($incomingSerials as $serial) {
|
||||
if (in_array($serial, $stock->serial_numbers ?? [])) {
|
||||
$serialStockMap[$stock->id][] = $serial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add or merge cart per stock
|
||||
foreach ($serialStockMap as $stockId => $serialsForStock) {
|
||||
|
||||
$resolvedStock = $stocks->firstWhere('id', $stockId);
|
||||
$qty = count($serialsForStock);
|
||||
|
||||
$customerType = $request->customer_type ?? 'Retailer';
|
||||
|
||||
// Determine price based on customer type
|
||||
$price = round($resolvedStock->productSalePrice ?? 0, 2);
|
||||
|
||||
if ($customerType === 'Dealer') {
|
||||
$price = round($resolvedStock->productDealerPrice ?? 0, 2);
|
||||
} elseif ($customerType === 'Wholesaler') {
|
||||
$price = round($resolvedStock->productWholeSalePrice ?? 0, 2);
|
||||
}
|
||||
|
||||
$existingCartItem = Cart::search(function ($item) use ($request, $stockId) {
|
||||
return $item->id == $request->id &&
|
||||
$item->options->type === 'sale' &&
|
||||
$item->options->stock_id == $stockId;
|
||||
})->first();
|
||||
|
||||
if ($existingCartItem) {
|
||||
|
||||
$existingSerials = $existingCartItem->options->serial_numbers ?? [];
|
||||
|
||||
// Remove already existing serials from incoming
|
||||
$newSerials = array_diff($serialsForStock, $existingSerials);
|
||||
|
||||
$duplicates = array_intersect($existingSerials, $newSerials);
|
||||
|
||||
if (!empty($duplicates)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Serial already exists in cart',
|
||||
'duplicates' => array_values($duplicates),
|
||||
], 422);
|
||||
}
|
||||
|
||||
$mergedSerials = array_values(array_unique(
|
||||
array_merge($existingSerials, $serialsForStock)
|
||||
));
|
||||
|
||||
Cart::update($existingCartItem->rowId, [
|
||||
'qty' => count($mergedSerials),
|
||||
'options' => $existingCartItem->options->merge([
|
||||
'serial_numbers' => $mergedSerials,
|
||||
]),
|
||||
]);
|
||||
|
||||
} else {
|
||||
|
||||
Cart::add([
|
||||
'id' => $request->id,
|
||||
'name' => $request->name,
|
||||
'qty' => $qty,
|
||||
'price' => $price,
|
||||
'options' => [
|
||||
'type' => 'sale',
|
||||
'product_code' => $request->product_code,
|
||||
'product_unit_id' => $request->product_unit_id,
|
||||
'product_unit_name' => $request->product_unit_name,
|
||||
'product_image' => $request->product_image,
|
||||
'product_type' => $request->product_type,
|
||||
'variant_name' => $request->variant_name,
|
||||
'stock_id' => $resolvedStock->id,
|
||||
'warehouse_id' => $resolvedStock->warehouse_id,
|
||||
'sales_price' => $resolvedStock->productSalePrice,
|
||||
'whole_sale_price' => $resolvedStock->productWholeSalePrice,
|
||||
'dealer_price' => $resolvedStock->productDealerPrice,
|
||||
'serial_numbers' => $serialsForStock,
|
||||
'has_serial' => $request->has_serial ?? 1,
|
||||
'price_without_tax' => $resolvedStock->price_without_tax,
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
// Check for existing item in cart by type
|
||||
$existingCartItem = Cart::search(
|
||||
fn($item) => $item->id == $request->id &&
|
||||
$item->options->type == $request->type &&
|
||||
match ($request->type) {
|
||||
'purchase' => $item->options->batch_no == $request->batch_no,
|
||||
'sale' => $item->options->stock_id == $request->stock_id,
|
||||
default => false,
|
||||
}
|
||||
// Purchase
|
||||
else {
|
||||
Cart::add([
|
||||
'id' => $request->id,
|
||||
'name' => $request->name,
|
||||
'qty' => count($incomingSerials),
|
||||
'price' => round($request->price, 2),
|
||||
'options' => [
|
||||
'type' => 'purchase',
|
||||
'product_code' => $request->product_code,
|
||||
'product_unit_id' => $request->product_unit_id,
|
||||
'product_unit_name' => $request->product_unit_name,
|
||||
'product_image' => $request->product_image,
|
||||
'product_type' => $request->product_type,
|
||||
'variant_name' => $request->variant_name,
|
||||
'stock_id' => null,
|
||||
'warehouse_id' => $request->warehouse_id,
|
||||
'serial_numbers' => $incomingSerials,
|
||||
'batch_no' => $request->batch_no,
|
||||
'expire_date' => $request->expire_date,
|
||||
'purchase_price' => $request->purchase_price,
|
||||
'profit_percent' => $request->profit_percent,
|
||||
'sales_price' => $request->sales_price,
|
||||
'whole_sale_price' => $request->whole_sale_price,
|
||||
'dealer_price' => $request->dealer_price,
|
||||
'has_serial' => $request->has_serial ?? 1,
|
||||
'price_without_tax' => $request->price_without_tax,
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Serial product added successfully.'
|
||||
]);
|
||||
}
|
||||
|
||||
// Normal product ( without serial)
|
||||
$existingCartItem = Cart::search(function ($item) use ($request) {
|
||||
return $item->id == $request->id &&
|
||||
$item->options->type == $request->type;
|
||||
})->first();
|
||||
)->first();
|
||||
|
||||
if ($existingCartItem) {
|
||||
|
||||
Cart::update($existingCartItem->rowId, [
|
||||
'qty' => $existingCartItem->qty + $request->quantity
|
||||
]);
|
||||
|
||||
$newQty = $existingCartItem->qty + $request->quantity;
|
||||
Cart::update($existingCartItem->rowId, ['qty' => $newQty]);
|
||||
} else {
|
||||
|
||||
Cart::add([
|
||||
// Add new item to cart
|
||||
$mainItemData = [
|
||||
'id' => $request->id,
|
||||
'name' => $request->name,
|
||||
'qty' => $request->quantity,
|
||||
'price' => round($request->price, 2),
|
||||
'price' => $request->price,
|
||||
'options' => [
|
||||
'type' => $request->type,
|
||||
'product_code' => $request->product_code,
|
||||
'product_unit_id' => $request->product_unit_id,
|
||||
'product_unit_name' => $request->product_unit_name,
|
||||
'product_image' => $request->product_image,
|
||||
'product_type' => $request->product_type,
|
||||
'variant_name' => $request->variant_name,
|
||||
'stock_id' => $request->stock_id,
|
||||
'batch_no' => $request->batch_no,
|
||||
'product_image' => $request->product_image,
|
||||
'expire_date' => $request->expire_date,
|
||||
'purchase_price' => $request->purchase_price,
|
||||
'profit_percent' => $request->profit_percent,
|
||||
'sales_price' => $request->sales_price,
|
||||
'whole_sale_price' => $request->whole_sale_price,
|
||||
'dealer_price' => $request->dealer_price,
|
||||
'product_type' => $request->product_type,
|
||||
'warehouse_id' => $request->warehouse_id,
|
||||
'has_serial' => $request->has_serial ?? 0,
|
||||
'price_without_tax' => $request->price_without_tax,
|
||||
'variant_name' => $request->variant_name,
|
||||
'vat_percent' => $request->vat_percent,
|
||||
]
|
||||
]);
|
||||
];
|
||||
Cart::add($mainItemData);
|
||||
}
|
||||
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Item added to cart successfully.'
|
||||
@@ -255,45 +108,20 @@ public function store(Request $request)
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$cart = Cart::get($id);
|
||||
|
||||
if (!$cart) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => __('Item not found in cart')
|
||||
]);
|
||||
return response()->json(['success' => false, 'message' => __('Item not found in cart')]);
|
||||
}
|
||||
|
||||
$qty = $request->qty ?? $cart->qty;
|
||||
|
||||
if ($qty < 0) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => __('Enter a valid quantity')
|
||||
]);
|
||||
}
|
||||
|
||||
// incoming serial
|
||||
$incomingSerials = $request->serial_numbers ?? null;
|
||||
|
||||
if (is_array($incomingSerials)) {
|
||||
$existingSerials = $incomingSerials;
|
||||
} else {
|
||||
$existingSerials = $cart->options->serial_numbers ?? [];
|
||||
}
|
||||
|
||||
// normalize to array
|
||||
if (!is_array($existingSerials)) {
|
||||
$existingSerials = !empty($existingSerials) ? [$existingSerials] : [];
|
||||
}
|
||||
|
||||
$hasSerial = $cart->options->has_serial ?? 0;
|
||||
|
||||
if ($hasSerial) {
|
||||
$qty = count($existingSerials);
|
||||
return response()->json(['success' => false, 'message' => __('Enter a valid quantity')]);
|
||||
}
|
||||
|
||||
Cart::update($id, [
|
||||
'qty' => $qty,
|
||||
'price' => round($request->price ?? $cart->price, 2),
|
||||
'price' => $request->price ?? $cart->price,
|
||||
'options' => [
|
||||
'type' => $cart->options->type,
|
||||
'expire_date' => $request->expire_date ?? $cart->options->expire_date,
|
||||
@@ -303,7 +131,6 @@ public function update(Request $request, $id)
|
||||
'product_unit_id' => $cart->options->product_unit_id,
|
||||
'product_unit_name' => $cart->options->product_unit_name,
|
||||
'product_image' => $cart->options->product_image,
|
||||
'profit_percent' => $cart->options->profit_percent,
|
||||
'sales_price' => $cart->options->sales_price,
|
||||
'discount' => $request->discount ?? $cart->options->discount,
|
||||
'whole_sale_price' => $cart->options->whole_sale_price,
|
||||
@@ -312,9 +139,7 @@ public function update(Request $request, $id)
|
||||
'product_type' => $cart->options->product_type,
|
||||
'warehouse_id' => $cart->options->warehouse_id,
|
||||
'variant_name' => $cart->options->variant_name,
|
||||
'price_without_tax' => $cart->options->price_without_tax,
|
||||
'has_serial' => $hasSerial,
|
||||
'serial_numbers' => $existingSerials,
|
||||
'vat_percent' => $cart->options->vat_percent,
|
||||
]
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user