first(); if (!$warehouse) { return null; } return [ 'item_id' => $warehouse->item_id, 'quantity' => $warehouse->quantity, 'total_buy_amount' => $warehouse->total_buy_amount, 'total_sell_amount' => $warehouse->total_sell_amount, 'total_buy_quantity' => $warehouse->total_buy_quantity, 'total_sell_quantity' => $warehouse->total_sell_quantity, 'average_buy_price' => self::calculateAveragePrice($warehouse->total_buy_amount, $warehouse->total_buy_quantity), 'average_sell_price' => self::calculateAveragePrice($warehouse->total_sell_amount, $warehouse->total_sell_quantity), 'net_buy_quantity' => $warehouse->total_buy_quantity - $warehouse->total_sell_quantity, 'net_buy_amount' => bcsub($warehouse->total_buy_amount, $warehouse->total_sell_amount, 5), 'last_transaction_at' => $warehouse->last_transaction_at, ]; } /** * 获取多个商品的库存信息 * * @param array $itemIds 商品ID数组 * @return array 库存信息列表 */ public static function getItemsStock(array $itemIds): array { $warehouses = MexWarehouse::whereIn('item_id', $itemIds)->get(); $result = []; foreach ($warehouses as $warehouse) { $result[$warehouse->item_id] = [ 'item_id' => $warehouse->item_id, 'quantity' => $warehouse->quantity, 'total_buy_amount' => $warehouse->total_buy_amount, 'total_sell_amount' => $warehouse->total_sell_amount, 'total_buy_quantity' => $warehouse->total_buy_quantity, 'total_sell_quantity' => $warehouse->total_sell_quantity, 'average_buy_price' => self::calculateAveragePrice($warehouse->total_buy_amount, $warehouse->total_buy_quantity), 'average_sell_price' => self::calculateAveragePrice($warehouse->total_sell_amount, $warehouse->total_sell_quantity), 'last_transaction_at' => $warehouse->last_transaction_at, ]; } return $result; } /** * 检查库存是否充足 * * @param int $itemId 商品ID * @param int $quantity 需要数量 * @return bool 是否充足 */ public static function checkStockSufficient(int $itemId, int $quantity): bool { $warehouse = MexWarehouse::where('item_id', $itemId)->first(); if (!$warehouse) { return false; } return $warehouse->quantity >= $quantity; } /** * 获取所有有库存的商品 * * @return array 商品列表 */ public static function getAvailableItems(): array { $warehouses = MexWarehouse::where('quantity', '>', 0) ->orderBy('quantity', 'desc') ->get(); $result = []; foreach ($warehouses as $warehouse) { $result[] = [ 'item_id' => $warehouse->item_id, 'quantity' => $warehouse->quantity, 'average_buy_price' => self::calculateAveragePrice($warehouse->total_buy_amount, $warehouse->total_buy_quantity), 'last_transaction_at' => $warehouse->last_transaction_at, ]; } return $result; } /** * 获取仓库统计信息 * * @return array 统计信息 */ public static function getWarehouseStats(): array { $stats = MexWarehouse::selectRaw(' COUNT(*) as total_items, COUNT(CASE WHEN quantity > 0 THEN 1 END) as available_items, SUM(quantity) as total_quantity, SUM(total_buy_amount) as total_buy_amount, SUM(total_sell_amount) as total_sell_amount, SUM(total_buy_quantity) as total_buy_quantity, SUM(total_sell_quantity) as total_sell_quantity ')->first(); return [ 'total_items' => $stats->total_items ?? 0, 'available_items' => $stats->available_items ?? 0, 'total_quantity' => $stats->total_quantity ?? 0, 'total_buy_amount' => $stats->total_buy_amount ?? '0.00000', 'total_sell_amount' => $stats->total_sell_amount ?? '0.00000', 'total_buy_quantity' => $stats->total_buy_quantity ?? 0, 'total_sell_quantity' => $stats->total_sell_quantity ?? 0, 'net_amount' => bcsub($stats->total_buy_amount ?? '0', $stats->total_sell_amount ?? '0', 5), 'net_quantity' => ($stats->total_buy_quantity ?? 0) - ($stats->total_sell_quantity ?? 0), ]; } /** * 增加库存 * * @param int $itemId 商品ID * @param int $quantity 数量 * @param string $amount 金额 * @return bool 操作结果 */ public static function addStock(int $itemId, int $quantity, string $amount): bool { try { $warehouse = MexWarehouse::firstOrCreate( ['item_id' => $itemId], [ 'quantity' => 0, 'total_buy_amount' => '0.00000', 'total_sell_amount' => '0.00000', 'total_buy_quantity' => 0, 'total_sell_quantity' => 0, ] ); $warehouse->quantity += $quantity; $warehouse->total_buy_quantity += $quantity; $warehouse->total_buy_amount = bcadd($warehouse->total_buy_amount, $amount, 5); $warehouse->last_transaction_at = now(); return $warehouse->save(); } catch (\Exception $e) { return false; } } /** * 减少库存 * * @param int $itemId 商品ID * @param int $quantity 数量 * @param string $amount 金额 * @return bool 操作结果 */ public static function reduceStock(int $itemId, int $quantity, string $amount): bool { try { $warehouse = MexWarehouse::where('item_id', $itemId)->first(); if (!$warehouse || $warehouse->quantity < $quantity) { return false; } $warehouse->quantity -= $quantity; $warehouse->total_sell_quantity += $quantity; $warehouse->total_sell_amount = bcadd($warehouse->total_sell_amount, $amount, 5); $warehouse->last_transaction_at = now(); return $warehouse->save(); } catch (\Exception $e) { return false; } } /** * 计算平均价格 * * @param string $totalAmount 总金额 * @param int $totalQuantity 总数量 * @return string 平均价格 */ private static function calculateAveragePrice(string $totalAmount, int $totalQuantity): string { if ($totalQuantity <= 0) { return '0.00000'; } return bcdiv($totalAmount, $totalQuantity, 5); } }