MexWarehouseLogic.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <?php
  2. namespace App\Module\Mex\Logic;
  3. use App\Module\Mex\Models\MexWarehouse;
  4. use Illuminate\Support\Facades\DB;
  5. /**
  6. * 农贸市场仓库逻辑
  7. *
  8. * 处理仓库相关的核心业务逻辑
  9. */
  10. class MexWarehouseLogic
  11. {
  12. /**
  13. * 获取商品库存信息
  14. *
  15. * @param int $itemId 商品ID
  16. * @return array|null 库存信息
  17. */
  18. public static function getItemStock(int $itemId): ?array
  19. {
  20. $warehouse = MexWarehouse::where('item_id', $itemId)->first();
  21. if (!$warehouse) {
  22. return null;
  23. }
  24. return [
  25. 'item_id' => $warehouse->item_id,
  26. 'quantity' => $warehouse->quantity,
  27. 'total_buy_amount' => $warehouse->total_buy_amount,
  28. 'total_sell_amount' => $warehouse->total_sell_amount,
  29. 'total_buy_quantity' => $warehouse->total_buy_quantity,
  30. 'total_sell_quantity' => $warehouse->total_sell_quantity,
  31. 'average_buy_price' => self::calculateAveragePrice($warehouse->total_buy_amount, $warehouse->total_buy_quantity),
  32. 'average_sell_price' => self::calculateAveragePrice($warehouse->total_sell_amount, $warehouse->total_sell_quantity),
  33. 'net_buy_quantity' => $warehouse->total_buy_quantity - $warehouse->total_sell_quantity,
  34. 'net_buy_amount' => bcsub($warehouse->total_buy_amount, $warehouse->total_sell_amount, 5),
  35. 'last_transaction_at' => $warehouse->last_transaction_at,
  36. ];
  37. }
  38. /**
  39. * 获取多个商品的库存信息
  40. *
  41. * @param array $itemIds 商品ID数组
  42. * @return array 库存信息列表
  43. */
  44. public static function getItemsStock(array $itemIds): array
  45. {
  46. $warehouses = MexWarehouse::whereIn('item_id', $itemIds)->get();
  47. $result = [];
  48. foreach ($warehouses as $warehouse) {
  49. $result[$warehouse->item_id] = [
  50. 'item_id' => $warehouse->item_id,
  51. 'quantity' => $warehouse->quantity,
  52. 'total_buy_amount' => $warehouse->total_buy_amount,
  53. 'total_sell_amount' => $warehouse->total_sell_amount,
  54. 'total_buy_quantity' => $warehouse->total_buy_quantity,
  55. 'total_sell_quantity' => $warehouse->total_sell_quantity,
  56. 'average_buy_price' => self::calculateAveragePrice($warehouse->total_buy_amount, $warehouse->total_buy_quantity),
  57. 'average_sell_price' => self::calculateAveragePrice($warehouse->total_sell_amount, $warehouse->total_sell_quantity),
  58. 'last_transaction_at' => $warehouse->last_transaction_at,
  59. ];
  60. }
  61. return $result;
  62. }
  63. /**
  64. * 检查库存是否充足
  65. *
  66. * @param int $itemId 商品ID
  67. * @param int $quantity 需要数量
  68. * @return bool 是否充足
  69. */
  70. public static function checkStockSufficient(int $itemId, int $quantity): bool
  71. {
  72. $warehouse = MexWarehouse::where('item_id', $itemId)->first();
  73. if (!$warehouse) {
  74. return false;
  75. }
  76. return $warehouse->quantity >= $quantity;
  77. }
  78. /**
  79. * 获取所有有库存的商品
  80. *
  81. * @return array 商品列表
  82. */
  83. public static function getAvailableItems(): array
  84. {
  85. $warehouses = MexWarehouse::where('quantity', '>', 0)
  86. ->orderBy('quantity', 'desc')
  87. ->get();
  88. $result = [];
  89. foreach ($warehouses as $warehouse) {
  90. $result[] = [
  91. 'item_id' => $warehouse->item_id,
  92. 'quantity' => $warehouse->quantity,
  93. 'average_buy_price' => self::calculateAveragePrice($warehouse->total_buy_amount, $warehouse->total_buy_quantity),
  94. 'last_transaction_at' => $warehouse->last_transaction_at,
  95. ];
  96. }
  97. return $result;
  98. }
  99. /**
  100. * 获取仓库统计信息
  101. *
  102. * @return array 统计信息
  103. */
  104. public static function getWarehouseStats(): array
  105. {
  106. $stats = MexWarehouse::selectRaw('
  107. COUNT(*) as total_items,
  108. COUNT(CASE WHEN quantity > 0 THEN 1 END) as available_items,
  109. SUM(quantity) as total_quantity,
  110. SUM(total_buy_amount) as total_buy_amount,
  111. SUM(total_sell_amount) as total_sell_amount,
  112. SUM(total_buy_quantity) as total_buy_quantity,
  113. SUM(total_sell_quantity) as total_sell_quantity
  114. ')->first();
  115. return [
  116. 'total_items' => $stats->total_items ?? 0,
  117. 'available_items' => $stats->available_items ?? 0,
  118. 'total_quantity' => $stats->total_quantity ?? 0,
  119. 'total_buy_amount' => $stats->total_buy_amount ?? '0.00000',
  120. 'total_sell_amount' => $stats->total_sell_amount ?? '0.00000',
  121. 'total_buy_quantity' => $stats->total_buy_quantity ?? 0,
  122. 'total_sell_quantity' => $stats->total_sell_quantity ?? 0,
  123. 'net_amount' => bcsub($stats->total_buy_amount ?? '0', $stats->total_sell_amount ?? '0', 5),
  124. 'net_quantity' => ($stats->total_buy_quantity ?? 0) - ($stats->total_sell_quantity ?? 0),
  125. ];
  126. }
  127. /**
  128. * 增加库存
  129. *
  130. * @param int $itemId 商品ID
  131. * @param int $quantity 数量
  132. * @param string $amount 金额
  133. * @return bool 操作结果
  134. */
  135. public static function addStock(int $itemId, int $quantity, string $amount): bool
  136. {
  137. try {
  138. $warehouse = MexWarehouse::firstOrCreate(
  139. ['item_id' => $itemId],
  140. [
  141. 'quantity' => 0,
  142. 'total_buy_amount' => '0.00000',
  143. 'total_sell_amount' => '0.00000',
  144. 'total_buy_quantity' => 0,
  145. 'total_sell_quantity' => 0,
  146. ]
  147. );
  148. $warehouse->quantity += $quantity;
  149. $warehouse->total_buy_quantity += $quantity;
  150. $warehouse->total_buy_amount = bcadd($warehouse->total_buy_amount, $amount, 5);
  151. $warehouse->last_transaction_at = now();
  152. return $warehouse->save();
  153. } catch (\Exception $e) {
  154. return false;
  155. }
  156. }
  157. /**
  158. * 减少库存
  159. *
  160. * @param int $itemId 商品ID
  161. * @param int $quantity 数量
  162. * @param string $amount 金额
  163. * @return bool 操作结果
  164. */
  165. public static function reduceStock(int $itemId, int $quantity, string $amount): bool
  166. {
  167. try {
  168. $warehouse = MexWarehouse::where('item_id', $itemId)->first();
  169. if (!$warehouse || $warehouse->quantity < $quantity) {
  170. return false;
  171. }
  172. $warehouse->quantity -= $quantity;
  173. $warehouse->total_sell_quantity += $quantity;
  174. $warehouse->total_sell_amount = bcadd($warehouse->total_sell_amount, $amount, 5);
  175. $warehouse->last_transaction_at = now();
  176. return $warehouse->save();
  177. } catch (\Exception $e) {
  178. return false;
  179. }
  180. }
  181. /**
  182. * 计算平均价格
  183. *
  184. * @param string $totalAmount 总金额
  185. * @param int $totalQuantity 总数量
  186. * @return string 平均价格
  187. */
  188. private static function calculateAveragePrice(string $totalAmount, int $totalQuantity): string
  189. {
  190. if ($totalQuantity <= 0) {
  191. return '0.00000';
  192. }
  193. return bcdiv($totalAmount, $totalQuantity, 5);
  194. }
  195. }