我在 laravel API 中有非常复杂的功能(从移动应用程序调用)。示例函数如下所示。如果有人可以帮助改进代码结构。我想知道在单个 API 中处理多个事务的最佳实践。因为如果我将每个表的条目移动到单独的函数 - 我如何处理每个表的错误?例如:当 $request 模型中没有设置数量时
摘要: 有人可以将其分解为更小的功能吗? .... 因为我不知道如何/在哪里将它分成更小的部分。
public function placeOrder(Request $request)
{
$this->validate($request, [
'addressId' => 'required'
]);
$userId = Auth::user()->id;
$itemList = array();
$deliveryCharge = Store::first()->delivery_charge;
// $deliveryCharge = Store::findOrFail($request->header('StoreId'))->delivery_charge;
$total = $deliveryCharge;
$cod = $request->cod;
$useBalanceFirst = $request->useBalanceFirst;
$addressId = $request->addressId;
$list = $request->list;
$cost = 0;
// fetch all items using id in request
foreach ($list as $orderItemFromRequest) {
if (!isset($orderItemFromRequest['id']))
return $this->error("Invalid item selected");
$itemFromDB = Item::find($orderItemFromRequest['id']);
if (!isset($orderItemFromRequest['quantity']))
return $this->error("Please enter quantity for {$itemFromDB->name}");
$qty = $orderItemFromRequest['quantity'];
if ($qty > 0.0) {
if ($itemFromDB == null || $itemFromDB->available == false)
return $this->error("Invalid item selected");
$itemFromDB->quantity = $qty;
$total += ($itemFromDB->sell_rate * $itemFromDB->quantity) / $itemFromDB->rate_unit_multiple;
$cost += ($qty * $itemFromDB->purchase_rate) / $itemFromDB->rate_unit_multiple;
array_push($itemList, $itemFromDB);
}
}
if (count($itemList) == 0) {
return $this->error("At least 1 item is needed to place the order");
}
// check user balance
$user = User::findOrFail($userId);
// if balance < total -> throw error
if ($cod != true && $user->balance < $total) return $this->error("Insufficient Balance. Please recharge your wallet or use C.O.D.", 403);
$order = new Order();
$order->user_id = $user->id;
$order->total = $total;
$order->delivery_charge = $deliveryCharge;
$order->purchase_rate = $cost;
// because in-case user changes his/her name in future - the order should have the historical name & number
$order->customer_name = $user->name;
$order->customer_contact = $user->contact_no;
$order->address_id = $addressId;
if ($cod == true) {
if ($useBalanceFirst == true) {
if ($user->balance < $order->total)
$order->amount_due = $order->total - $user->balance;
else
$order->amount_due = 0;
} else {
$order->amount_due = $order->total;
}
} else
$order->amount_due = 0;
$ordertransaction = new OrderTimeLine();
$ordertransaction->created_by = Auth::user()->id;
DB::transaction(function () use ($order, $itemList, $user, $ordertransaction) {
// insert 1 entry into orders
$order->save();
$order->refresh();
$newOrderItemList = array();
// insert N entries for Items
foreach ($itemList as $requestItem) {
$item = new OrderItem();
$item->order_id = $order->id;
$item->item_id = $requestItem->id;
$item->item_name = $requestItem->name;
$item->sell_rate = $requestItem->sell_rate;
$item->purchase_rate = $requestItem->purchase_rate;
$item->quantity = $requestItem->quantity;
$item->quantity_unit = $requestItem->unit;
$item->rate_unit_multiple = $requestItem->rate_unit_multiple;
if ($requestItem->remaining_stocks <= 0) {
$item->purchase_rate_qty = 0;
} else if ($requestItem->remaining_stocks < $requestItem->quantity) {
$item->purchase_rate_qty = $requestItem->remaining_stocks;
} else
$item->purchase_rate_qty = $requestItem->quantity;
$item->save();
$item->refresh();
$requestItem->remaining_stocks = $requestItem->remaining_stocks - $requestItem->quantity;
// update remaining QTY and cost price
unset($requestItem->quantity);
if ($requestItem->remaining_stocks <= $requestItem->alert_stocks) {
// send notification
NotificationController::notifyAdminAboutStocks($requestItem);
}
$requestItem->save();
array_push($newOrderItemList, $item);
}
$order->items = $newOrderItemList;
// deduct balance from user table
$user->balance = $user->balance - $order->total + $order->amount_due;
$user->save();
$balanceAffected = 0 - $order->total + $order->amount_due;
// enter transaction in wallet_transaction table
if ($balanceAffected != 0) {
$transaction = new WalletTransaction();
$transaction->user_id = $user->id;
$transaction->amount = $balanceAffected;
$transaction->type = WALLET_ORDER_PLACED;
$transaction->order_id = $order->id;
$transaction->save();
}
$ordertransaction->status = $order->status;
$ordertransaction->order_id = $order->id;
$ordertransaction->save();
});
NotificationController::notifyAdminAboutOrder($user, $order);
return $this->success(["balance" => $user->balance, "order" => $order]);
}