PurchaseClass.php 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644
  1. <?php
  2. namespace bizHd\purchase\classes;
  3. use biz\ghs\classes\GhsClass;
  4. use biz\product\classes\XjClass;
  5. use biz\shop\classes\ShopCapitalClass;
  6. use biz\shop\classes\ShopClass;
  7. use biz\stat\classes\StatCgClass;
  8. use biz\stat\classes\StatCgGhsClass;
  9. use biz\stat\classes\StatOutClass;
  10. use biz\stock\classes\StockClass;
  11. use biz\wx\classes\WxMessageClass;
  12. use bizGhs\admin\classes\AdminClass;
  13. use bizGhs\custom\classes\CustomClass;
  14. use bizGhs\item\classes\CostChangeClass;
  15. use bizGhs\order\classes\OrderClass;
  16. use bizGhs\order\classes\OrderMergeSnClass;
  17. use bizGhs\order\traits\OrderTrait;
  18. use bizGhs\product\classes\ProductClass;
  19. use bizGhs\stock\classes\OnStockRecordClass;
  20. use bizGhs\stock\classes\StockRecordClass;
  21. use bizHd\cg\classes\CgMergeClass;
  22. use bizHd\cg\classes\CgMergeSnClass;
  23. use bizHd\cg\models\CgMerge;
  24. use bizHd\cg\classes\CgRefundClass;
  25. use bizHd\cg\classes\CgTreeClass;
  26. use bizHd\cg\classes\CgXjClass;
  27. use bizHd\shop\classes\MainClass;
  28. use bizHd\stat\classes\StatIncomeClass;
  29. use common\components\dict;
  30. use common\components\imgUtil;
  31. use common\components\IntraCityExpress;
  32. use common\components\mapUtil;
  33. use common\components\noticeUtil;
  34. use common\components\orderSn;
  35. use common\components\stringUtil;
  36. use common\components\util;
  37. use bizHd\base\classes\BaseClass;
  38. use common\components\lakala\Lakala;
  39. use Yii;
  40. use yii\helpers\ArrayHelper;
  41. class PurchaseClass extends BaseClass
  42. {
  43. use OrderTrait;
  44. public static $baseFile = '\bizHd\purchase\models\Purchase';
  45. //订单状态 1待付款,待确认,2待配送,3配送中,4已完成,5取消,失败
  46. const STATUS_UN_PAY = 1;
  47. const STATUS_UN_SEND = 2;
  48. const STATUS_SENDING = 3;
  49. const STATUS_COMPLETE = 4;
  50. const STATUS_CANCEL = 5;
  51. //未知
  52. const DEBT_UNKNOWN = 0;
  53. //欠款
  54. const DEBT_YES = 1;
  55. //没有欠款
  56. const DEBT_NO = 2;
  57. //配送,这里的数值是错的,请参考dict.php的数值
  58. const GET_TYPE_SEND = 1;
  59. //自取,这里的数值是错的,请参考dict.php的数值
  60. const GET_TYPE_SELF_GET = 2;
  61. const REFUND_NO = 1;
  62. const REFUND_YES = 2;
  63. //更新同一供货商、同一天的多张采购单合并 $update 0 添加 1 修改(写法对齐 OrderClass::updateMergeOrder)
  64. public static function updateMergeCg($cg, $update = 0)
  65. {
  66. $date = substr($cg->payTime, 0, 10);
  67. $ghsId = $cg->ghsId ?? 0;
  68. $mainId = $cg->mainId ?? 0;
  69. $cgId = $cg->id ?? 0;
  70. //当前零售商 + 供货商 + 账单日 下的采购单
  71. $startTime = $date . ' 00:00:00';
  72. $endTime = $date . ' 23:59:59';
  73. $dayOrders = self::getAllByCondition([
  74. 'mainId' => $mainId,
  75. 'ghsId' => $ghsId,
  76. 'payTime' => ['between', [$startTime, $endTime]]
  77. ], 'id ASC', 'id');
  78. if (empty($dayOrders)) {
  79. return false;
  80. }
  81. $ids = array_column($dayOrders, 'id');
  82. $count = count($ids);
  83. if ($update == 0) {
  84. if ($count <= 1) {
  85. //新增,如果当天只有一个订单,不需要操作
  86. return false;
  87. }
  88. $hasMerge = CgMergeSnClass::getByCondition(['ghsId' => $ghsId, 'mergeDate' => $date], true);
  89. if (!empty($hasMerge)) {
  90. $hasMergeId = $hasMerge->id ?? 0;
  91. $cg->mergeId = $hasMergeId;
  92. $cg->save();
  93. CgMergeClass::add(['mergeId' => $hasMergeId, 'cgId' => $cgId, 'mergeDate' => $date, 'ghsId' => $ghsId, 'mainId' => $mainId]);
  94. self::syncCgMergeNumForMergeId($hasMergeId);
  95. self::syncMergeRelationByCgIds([$cgId]);
  96. } else {
  97. self::rebuildCgMergeGroupForDay($ids, $date, $ghsId, $mainId);
  98. }
  99. } else {
  100. //修改账单日:payTime 已在调用方改为新日 $date
  101. $oldMergeId = (int)($cg->mergeId ?? 0);
  102. if ($oldMergeId > 0) {
  103. $oldMergeSn = CgMergeSnClass::getById($oldMergeId, true);
  104. if (empty($oldMergeSn)) {
  105. $cg->mergeId = 0;
  106. $cg->mergeNum = 0;
  107. $cg->save();
  108. } else {
  109. $oldDate = $oldMergeSn->mergeDate ?? '';
  110. if ($oldDate == $date) {
  111. return false;
  112. }
  113. $oldMergeList = CgMergeClass::getAllByCondition(['mergeId' => $oldMergeId], null, '*', null, true);
  114. if (count($oldMergeList) <= 2) {
  115. $oldMergeSn->delete();
  116. $del = [];
  117. foreach ($oldMergeList as $mergeRow) {
  118. $del[] = $mergeRow->cgId;
  119. $mergeRow->delete();
  120. }
  121. self::updateByIds($del, ['mergeId' => 0, 'mergeNum' => 0]);
  122. } else {
  123. $cg->mergeId = 0;
  124. $cg->mergeNum = 0;
  125. $cg->save();
  126. CgMergeClass::deleteByCondition(['mergeId' => $oldMergeId, 'cgId' => $cgId]);
  127. self::syncCgMergeNumForMergeId($oldMergeId);
  128. }
  129. }
  130. }
  131. $hasNewMerge = CgMergeSnClass::getByCondition(['ghsId' => $ghsId, 'mergeDate' => $date], true);
  132. if (!empty($hasNewMerge)) {
  133. $newMergeId = $hasNewMerge->id ?? 0;
  134. $cg->mergeId = $newMergeId;
  135. $cg->save();
  136. CgMergeClass::add(['mergeId' => $newMergeId, 'cgId' => $cgId, 'mergeDate' => $date, 'ghsId' => $ghsId, 'mainId' => $mainId]);
  137. self::syncCgMergeNumForMergeId($newMergeId);
  138. self::syncMergeRelationByCgIds([$cgId]);
  139. } else {
  140. self::rebuildCgMergeGroupForDay($ids, $date, $ghsId, $mainId);
  141. }
  142. }
  143. return true;
  144. }
  145. /**
  146. * 指定零售商、供货商、某日多采购单:清理旧明细后新建合并主档,回写 mergeId,并写入 xhCgMerge。
  147. *
  148. * @param int[] $ids 当日同供货商采购单 id 列表
  149. */
  150. private static function rebuildCgMergeGroupForDay(array $ids, $date, $ghsId, $mainId)
  151. {
  152. if (!empty($ids)) {
  153. CgMerge::deleteAll(['cgId' => $ids]);
  154. }
  155. $mergeData = ['mergeDate' => $date, 'ghsId' => $ghsId, 'mainId' => $mainId];
  156. $mergeId = orderSn::getCgMergeId($mergeData);
  157. $mergeNum = count($ids);
  158. self::updateByIds($ids, ['mergeId' => $mergeId, 'mergeNum' => $mergeNum]);
  159. $addData = [];
  160. foreach ($ids as $currentId) {
  161. $addData[] = ['mergeId' => $mergeId, 'cgId' => $currentId, 'mergeDate' => $date, 'ghsId' => $ghsId, 'mainId' => $mainId];
  162. }
  163. CgMergeClass::batchAdd($addData);
  164. self::syncMergeRelationByCgIds($ids);
  165. }
  166. public static function syncMergeRelationByOrderIds($orderIds)
  167. {
  168. if (empty($orderIds)) {
  169. return false;
  170. }
  171. $orders = OrderClass::getByIds($orderIds, null, null, 'id,purchaseId');
  172. if (empty($orders)) {
  173. return false;
  174. }
  175. $cgIds = [];
  176. foreach ($orders as $order) {
  177. $purchaseId = $order['purchaseId'] ?? 0;
  178. if (!empty($purchaseId)) {
  179. $cgIds[] = $purchaseId;
  180. }
  181. }
  182. return self::syncMergeRelationByCgIds($cgIds);
  183. }
  184. public static function syncMergeRelationByCgIds($cgIds)
  185. {
  186. if (empty($cgIds)) {
  187. return false;
  188. }
  189. $cgIds = array_values(array_unique(array_filter($cgIds)));
  190. if (empty($cgIds)) {
  191. return false;
  192. }
  193. $cgs = self::getByIds($cgIds, null, null, 'id,saleId,mergeId');
  194. if (empty($cgs)) {
  195. return false;
  196. }
  197. foreach ($cgs as $cg) {
  198. $cgId = $cg['id'] ?? 0;
  199. $orderId = $cg['saleId'] ?? 0;
  200. $cgMergeId = $cg['mergeId'] ?? 0;
  201. if (empty($cgId) || empty($orderId) || empty($cgMergeId)) {
  202. continue;
  203. }
  204. $order = OrderClass::getById($orderId, false, 'id,mergeId');
  205. $ghsMergeId = $order['mergeId'] ?? 0;
  206. if (empty($ghsMergeId)) {
  207. continue;
  208. }
  209. $cgMergeSn = CgMergeSnClass::getById($cgMergeId, false, 'id,salt');
  210. $ghsMergeSn = OrderMergeSnClass::getById($ghsMergeId, false, 'id,salt');
  211. $cgSalt = $cgMergeSn['salt'] ?? '';
  212. $ghsSalt = $ghsMergeSn['salt'] ?? '';
  213. if (empty($cgSalt) || empty($ghsSalt)) {
  214. continue;
  215. }
  216. CgMergeSnClass::updateById($cgMergeId, [
  217. 'ghsMergeId' => $ghsMergeId,
  218. 'ghsSalt' => $ghsSalt,
  219. ]);
  220. OrderMergeSnClass::updateById($ghsMergeId, [
  221. 'cgMergeId' => $cgMergeId,
  222. 'cgSalt' => $cgSalt,
  223. ]);
  224. }
  225. return true;
  226. }
  227. /** 按 xhCgMerge 明细数量,回写该合并组内所有采购单的 mergeNum */
  228. private static function syncCgMergeNumForMergeId($mergeId)
  229. {
  230. $mergeId = (int)$mergeId;
  231. if ($mergeId <= 0) {
  232. return;
  233. }
  234. $rows = CgMergeClass::getAllByCondition(['mergeId' => $mergeId], null, 'cgId', null, true);
  235. $mergeNum = count($rows);
  236. if ($mergeNum === 0) {
  237. return;
  238. }
  239. $cgIds = [];
  240. foreach ($rows as $row) {
  241. $cgIds[] = (int)(is_object($row) ? ($row->cgId ?? 0) : ($row['cgId'] ?? 0));
  242. }
  243. $cgIds = array_values(array_filter($cgIds));
  244. if (!empty($cgIds)) {
  245. self::updateByIds($cgIds, ['mergeNum' => $mergeNum]);
  246. }
  247. }
  248. //获取打包费
  249. public static function getKmPackCost($mainId)
  250. {
  251. $cost = dict::getDict('kmPackCost');
  252. if (getenv('YII_ENV') == 'production') {
  253. //云漫梦金鹏 徐记花卉 康多鲜 旭海 打包费0元
  254. if (in_array($mainId, [10728, 20528, 10866, 38657, 41121])) {
  255. $cost = dict::getDict('kmPackCost2');
  256. }
  257. //花瀚鲜花供应链
  258. if (in_array($mainId, [50, 14499])) {
  259. $cost = dict::getDict('kmPackCost3');
  260. }
  261. } else {
  262. }
  263. return $cost;
  264. }
  265. //订单发货主方法 ssh 20231119
  266. public static function orderSend($cg, $params, $allowRepeat)
  267. {
  268. $respond = self::orderFh($cg, $params, $allowRepeat);
  269. $orderId = $cg->saleId ?? 0;
  270. $orderInfo = OrderClass::getById($orderId, true);
  271. if (empty($orderInfo)) {
  272. util::fail('没有找到销售单信息');
  273. }
  274. OrderClass::orderFh($orderInfo, $params, $allowRepeat);
  275. return $respond;
  276. }
  277. public static function cancelFh($cg, $params)
  278. {
  279. $cg->status = 2;
  280. $cg->save();
  281. $orderSn = $cg->orderSn ?? '';
  282. $itemList = PurchaseItemClass::getAllByCondition(['orderSn' => $orderSn], null, '*', null, true);
  283. if (!empty($itemList)) {
  284. $sjId = $cg->sjId ?? 0;
  285. $shopId = $cg->shopId ?? 0;
  286. $mainId = $cg->mainId ?? 0;
  287. $ghsName = $cg->ghsName ?? '';
  288. foreach ($itemList as $key => $val) {
  289. $productId = $val->productId ?? 0;
  290. $itemId = $val->itemId ?? 0;
  291. $num = $val->xhNum ?? 0;
  292. $product = ProductClass::getLockById($productId);
  293. if (empty($product)) {
  294. util::fail('没有找到花材呢');
  295. }
  296. //减少路上库存
  297. $onRecord = [];
  298. $onRecord['sjId'] = $sjId;
  299. $onRecord['shopId'] = $shopId;
  300. $onRecord['mainId'] = $mainId;
  301. $onRecord['orderSn'] = $orderSn;
  302. $onRecord['productId'] = $productId;
  303. $onRecord['itemId'] = $itemId;
  304. $onRecord['relateName'] = $ghsName;
  305. $onRecord['itemNum'] = $num;
  306. $oldOnStock = $product->onStock ?? 0;
  307. $onRecord['oldStock'] = $oldOnStock;
  308. $newOnStock = bcsub($oldOnStock, $num);
  309. $onRecord['newStock'] = $newOnStock;
  310. $onRecord['ptStyle'] = 1;
  311. OnStockRecordClass::cancelCg($onRecord);
  312. ProductClass::decreaseOnStockByItemNum($productId, $num);
  313. }
  314. }
  315. }
  316. //订单发货子方法 ssh 20231119
  317. public static function orderFh($cg, $params, $allowRepeat = false, $notice = false)
  318. {
  319. if ($notice) {
  320. $noticeText = json_encode(['id' => $cg->id]);
  321. $noticeKey = "ghsKdNoticeHd";
  322. Yii::$app->redis->executeCommand('LPUSH', [$noticeKey, $noticeText]);
  323. }
  324. if ($cg->status == 3) {
  325. if (!$allowRepeat) {
  326. util::fail('订单已发货');
  327. } else {
  328. return true;
  329. }
  330. }
  331. $fhType = $params['fhType'] ?? 0;
  332. if (!is_numeric($fhType)) {
  333. util::fail('请选择发货类型');
  334. }
  335. if ($fhType == 1) {
  336. $fhWl = $params['fhWl'] ?? '';
  337. $fhWlNo = $params['fhWlNo'] ?? '';
  338. if (empty($fhWl)) {
  339. util::fail('请填写物流名称');
  340. }
  341. if (empty($fhWlNo)) {
  342. util::fail('请填写物流编号');
  343. }
  344. $cg->fhWl = $fhWl;
  345. $cg->fhWlNo = $fhWlNo;
  346. }
  347. $cg->fhType = $fhType;
  348. $cg->status = 3;
  349. $cg->fhTime = date("Y-m-d H:i:s");
  350. $cg->save();
  351. $orderSn = $cg->orderSn ?? '';
  352. $itemList = PurchaseItemClass::getAllByCondition(['orderSn' => $orderSn], null, '*', null, true);
  353. if (!empty($itemList)) {
  354. $sjId = $cg->sjId ?? 0;
  355. $shopId = $cg->shopId ?? 0;
  356. $mainId = $cg->mainId ?? 0;
  357. $ghsName = $cg->ghsName ?? '';
  358. foreach ($itemList as $key => $val) {
  359. $productId = $val->productId ?? 0;
  360. $itemId = $val->itemId ?? 0;
  361. $num = $val->xhNum ?? 0;
  362. $product = ProductClass::getLockById($productId);
  363. if (empty($product)) {
  364. util::fail('没有找到花材呢');
  365. }
  366. //增加路上库存
  367. $onRecord = [];
  368. $onRecord['sjId'] = $sjId;
  369. $onRecord['shopId'] = $shopId;
  370. $onRecord['mainId'] = $mainId;
  371. $onRecord['orderSn'] = $orderSn;
  372. $onRecord['productId'] = $productId;
  373. $onRecord['itemId'] = $itemId;
  374. $onRecord['relateName'] = $ghsName;
  375. $onRecord['itemNum'] = $num;
  376. $oldOnStock = $product->onStock ?? 0;
  377. $onRecord['oldStock'] = $oldOnStock;
  378. $newOnStock = bcadd($oldOnStock, $num);
  379. $onRecord['newStock'] = $newOnStock;
  380. $onRecord['ptStyle'] = 1;
  381. OnStockRecordClass::addPurchaseOrderRecord($onRecord);
  382. ProductClass::addOnStockByItemNum($productId, $num);
  383. }
  384. }
  385. return $cg;
  386. }
  387. //确认收货 ssh 20231119
  388. public static function confirmTake($cg)
  389. {
  390. //订单如果没有发货,则先发货
  391. if ($cg->status == self::STATUS_UN_SEND) {
  392. $cg = self::orderSend($cg, [], true);
  393. }
  394. // 构建“冲销”函数的参数 -- 变动前的花材存库数据
  395. $purchaseItems = PurchaseItemClass::getAllByCondition(['orderSn' => $cg->orderSn], null, "productId");
  396. $productIds = ArrayHelper::getColumn($purchaseItems, 'productId'); //$productIds 是本次入库涉及的花材ID数组
  397. $oldStocks = [];
  398. foreach ($productIds as $productId) {
  399. $product = ProductClass::getById($productId, true);
  400. $oldStocks[$productId] = $product;
  401. }
  402. self::takeToPutIn($cg);
  403. $shop = ShopClass::getLockById($cg->shopId);
  404. if (empty($shop)) {
  405. util::fail('没有找到门店14');
  406. }
  407. $adminId = $shop->adminId;
  408. $mainId = $shop->mainId;
  409. PurchaseClass::rollbackProductStock($oldStocks, $shop, $adminId, $mainId, '系统');
  410. }
  411. //确认收货并入库 ssh 20231119
  412. public static function takeToPutIn($cg)
  413. {
  414. if ($cg->status != 3) {
  415. util::fail('订单不是待收货状态哦,编号:cg' . $cg->id);
  416. }
  417. $saleId = $cg->saleId ?? 0;
  418. $order = OrderClass::getById($saleId, true);
  419. if (empty($order)) {
  420. util::fail('没有找到订单');
  421. }
  422. if ($order->status != 3) {
  423. util::fail('订单不是待收货状态,订单状态:' . $order->status . ',订单ID:' . $saleId);
  424. }
  425. $order->status = 4;
  426. $order->save();
  427. //加库存 lqh 2021-05-10
  428. $orderSn = $cg->orderSn;
  429. $sjId = $cg->sjId ?? 0;
  430. $shopId = $cg->shopId ?? 0;
  431. $mainId = $cg->mainId ?? 0;
  432. $ghsName = $cg->ghsName ?? '';
  433. $purchaseItem = PurchaseItemClass::getAllByCondition(['orderSn' => $orderSn], null, "*");
  434. foreach ($purchaseItem as $v) {
  435. //小单位库存不考虑入库 ssh 202310
  436. $itemNum = $v['itemNum'];
  437. if ($itemNum > 0) {
  438. $productId = $v['productId'];
  439. $stockInfo = ProductClass::addStockByItemNum($v['productId'], $itemNum);
  440. //记录库存流水
  441. $recordData = [];
  442. $recordData['sjId'] = $cg->sjId;
  443. $recordData['shopId'] = $cg->shopId;
  444. $recordData['mainId'] = $cg->mainId;
  445. $recordData['itemId'] = $v['itemId'] ?? 0;
  446. $recordData['itemNum'] = $itemNum;
  447. $recordData['oldStock'] = $stockInfo['oldStock'];
  448. $recordData['newStock'] = $stockInfo['newStock'];
  449. $recordData['productId'] = $v['productId'];
  450. $recordData['orderSn'] = $orderSn;
  451. $recordData['relateName'] = $cg->ghsName ?? '';
  452. StockRecordClass::addPurchaseOrderRecord($recordData);
  453. $product = ProductClass::getLockById($productId);
  454. if (empty($product)) {
  455. util::fail('没有找到花材哈');
  456. }
  457. //减少路上库存
  458. $onRecord = [];
  459. $onRecord['sjId'] = $sjId;
  460. $onRecord['shopId'] = $shopId;
  461. $onRecord['mainId'] = $mainId;
  462. $onRecord['orderSn'] = $orderSn;
  463. $onRecord['productId'] = $productId;
  464. $onRecord['itemId'] = $v['itemId'] ?? 0;
  465. $onRecord['relateName'] = $ghsName;
  466. $onRecord['itemNum'] = $itemNum;
  467. $oldOnStock = $product->onStock ?? 0;
  468. $onRecord['oldStock'] = $oldOnStock;
  469. $onRecord['newStock'] = bcsub($oldOnStock, $itemNum);
  470. $onRecord['ptStyle'] = 1;
  471. OnStockRecordClass::addInStockOrderRecord($onRecord);
  472. ProductClass::decreaseOnStockByItemNum($productId, $itemNum);
  473. $unitPrice = $v['xhUnitPrice'] ?? 0;
  474. $product->cost = $unitPrice;
  475. $product->save();
  476. $ptItemId = $product->itemId ?? 0;
  477. $mainId = $product->mainId ?? 0;
  478. $staffId = $cg->shopAdminId ?? 0;
  479. $staffName = $cg->shopAdminName ?? '';
  480. //成本变动记录
  481. $changeData = [
  482. 'ptStyle' => 2,
  483. 'sjId' => 0,
  484. 'mainId' => $mainId,
  485. 'itemId' => $productId,
  486. 'ptItemId' => $ptItemId,
  487. 'cost' => $unitPrice,
  488. 'staffId' => $staffId,
  489. 'staffName' => $staffName,
  490. 'name' => $product->name ?? '',
  491. 'cover' => $product->cover ?? '',
  492. 'targetId' => $cg->id ?? 0,
  493. 'event' => '采购',
  494. ];
  495. CostChangeClass::addData($changeData);
  496. }
  497. }
  498. $cg->status = 4;
  499. $cg->stockChange = 1;
  500. $cg->save();
  501. }
  502. // 库存回滚为入库前的状态
  503. public static function rollbackProductStock($oldStocks, $shop, $adminId, $mainId, $staffName)
  504. {
  505. $itemInfo = [];
  506. foreach ($oldStocks as $productId => $product) {
  507. $ratio = $product->ratio;
  508. $formNum = ProductClass::formatStock($product->stock, $ratio); //花材的库存转换
  509. $itemInfo[] = [
  510. 'productId' => $productId,
  511. 'itemNum' => $product->stock, // 回滚为入库前的库存
  512. 'itemId' => $product->itemId,
  513. 'bigNum' => $formNum['bigNum'],
  514. 'smallNum' => $formNum['smallNum'],
  515. 'price' => $product->price,
  516. ];
  517. }
  518. $data = [
  519. 'sjId' => $shop->sjId,
  520. 'shopId' => $shop->id,
  521. 'adminId' => $adminId,
  522. 'mainId' => $mainId,
  523. 'staffName' => $staffName,
  524. 'itemInfo' => $itemInfo,
  525. 'pdType' => 'rollbackStock',
  526. 'remark' => '',
  527. ];
  528. \bizGhs\order\classes\CheckOrderClass::opOrder($data, false, false, false);
  529. }
  530. // 指定花材新增库存
  531. public static function increaseProductStock($itemDatas, $shop, $adminId, $mainId, $staffName)
  532. {
  533. $itemInfo = [];
  534. foreach ($itemDatas as $productId => $arr) {
  535. $addNum = $arr['addNum']; //新增的数值
  536. $product = $arr['product'];
  537. $ratio = $product->ratio;
  538. $newStock = bcadd($product->stock, $addNum, 2);
  539. $formNum = ProductClass::formatStock($newStock, $ratio); //花材的库存转换
  540. $itemInfo[] = [
  541. 'productId' => $productId,
  542. 'itemNum' => $newStock, // 新库存数
  543. 'itemId' => $product->itemId,
  544. 'bigNum' => $formNum['bigNum'],
  545. 'smallNum' => $formNum['smallNum'],
  546. 'price' => $product->price,
  547. ];
  548. }
  549. $data = [
  550. 'sjId' => $shop->sjId,
  551. 'shopId' => $shop->id,
  552. 'adminId' => $adminId,
  553. 'mainId' => $mainId,
  554. 'staffName' => $staffName,
  555. 'itemInfo' => $itemInfo,
  556. 'pdType' => 'rollbackStock',
  557. 'remark' => '',
  558. ];
  559. \bizGhs\order\classes\CheckOrderClass::opOrder($data, false, false, false);
  560. }
  561. public static function notSameCity($shop, $ghsShop)
  562. {
  563. return true;
  564. $shopLat = $shop->lat ?? '';
  565. $shopLong = $shop->long ?? '';
  566. if (empty($shopLat) || empty($shopLong)) {
  567. util::fail('请完善门店地址');
  568. }
  569. $ghsShopLat = $ghsShop->lat ?? '';
  570. $ghsShopLong = $ghsShop->long ?? '';
  571. $distance = mapUtil::calculateDistance($shopLong, $shopLat, $ghsShopLong, $ghsShopLat);
  572. $formatDistance = ceil($distance / 1000);
  573. if ($formatDistance > 150) {
  574. return false;
  575. }
  576. return true;
  577. }
  578. //计算距离和运费【另外还有个地方要同步修改,关键词calc_freight_distance】 ssh 20221003
  579. public static function getDistanceFee($shop, $ghsShop, $weight, $custom)
  580. {
  581. $ability = ShopClass::hasIntraCity($ghsShop);
  582. $openIntraCity = $ability['openIntraCity'] ?? 0;
  583. if ($openIntraCity == 0) {
  584. //没有开启同城配送能力,不计算运费和距离
  585. return ['distance' => 0, 'showDistance' => 0, 'fee' => 0];
  586. }
  587. $shopLat = $shop->lat ?? '';
  588. $shopLong = $shop->long ?? '';
  589. if (empty($shopLat) || empty($shopLong)) {
  590. util::fail('请完善你的收花地址');
  591. }
  592. $address = $shop->address ?? '';
  593. if (empty($address)) {
  594. util::fail('请完善收花地址');
  595. }
  596. if ($weight <= 0) {
  597. util::fail('花材没有重量');
  598. }
  599. $wxStoreId = $ability['wxStoreId'] ?? '';
  600. $packageNum = 1;
  601. $price = 300;
  602. $cargo = [
  603. 'cargo_name' => '鲜花花材', // 商品名称 -- $order 中没有,要在 goodsInfo 中取
  604. 'cargo_weight' => intval($weight * 1000), // 单位:克 -- 把千克转换为克
  605. 'cargo_price' => intval($price * 100), // 单位:分 -- 把元转换为分
  606. 'cargo_type' => IntraCityExpress::GOODS_TYPE_FLOWER,
  607. 'cargo_num' => $packageNum
  608. ];
  609. $customName = $custom->name ?? '';
  610. if (empty($customName)) {
  611. util::fail('客户名称是空的');
  612. }
  613. $customMobile = $custom->mobile ?? '';
  614. if (empty($customMobile)) {
  615. util::fail('客户手机缺失');
  616. }
  617. //根据环境变量判断是否使用沙盒环境
  618. // $useSandBox = getenv('YII_ENV') == 'production' ? 0 : 1;
  619. $orderData = [
  620. 'wx_store_id' => $wxStoreId,
  621. 'user_name' => $customName,
  622. 'user_phone' => $customMobile,
  623. 'user_lng' => $shopLong,
  624. 'user_lat' => $shopLat,
  625. 'user_address' => $address,
  626. 'cargo' => $cargo,
  627. // 'use_sandbox' => $useSandBox,//正式环境不能传这个参数,会报错
  628. ];
  629. //多处有用到这个方法,需修改请同步修改,搜索关键词 intra_city_express_pre_add
  630. $result = IntraCityExpress::preAddOrder($orderData);
  631. if ($result['errcode'] !== 0) {
  632. $errMsg = $result['errmsg'] ?? '';
  633. noticeUtil::push('运费查询失败原因:' . $errMsg . '参数:' . $result['errcode'], '15280215347');
  634. util::fail('运费查询失败,编号1160');
  635. }
  636. $distance = $result['distance'] ?? 0;
  637. $showDistance = sprintf("%.1f", ($distance / 1000));
  638. $fee = $result['est_fee'] ?? 0;
  639. $totalFee = sprintf("%.1f", ($fee / 100));
  640. //noticeUtil::push("批发订单,获取运费:{$totalFee} 重量:{$weight} 距离:{$showDistance} 客户名:{$customMobile} 手机号 {$customMobile} 经纬 {$shopLong} {$shopLat} 金额:{$price} 数量:{$packageNum}", '15280215347');
  641. return ['distance' => $distance, 'showDistance' => $showDistance, 'fee' => $totalFee];
  642. }
  643. //到货之后 ssh 20220321
  644. public static function arrival($cg, $data)
  645. {
  646. if ($cg->stockChange == 1) {
  647. util::fail('您已操作过了');
  648. }
  649. $sendCost = isset($data['sendCost']) && is_numeric($data['sendCost']) ? $data['sendCost'] : 0;
  650. $packCost = isset($data['packCost']) && is_numeric($data['packCost']) ? $data['packCost'] : 0;
  651. $cg->sendCost = $sendCost;
  652. $cg->packCost = $packCost;
  653. $cg->save();
  654. $sjId = $data['sjId'] ?? 0;
  655. $shopId = $data['shopId'] ?? 0;
  656. //product [{"productId":"3674","num":0,"price":1}]
  657. $product = $data['product'] ?? '';
  658. if (empty($product)) {
  659. util::fail('请填写成本价和到货数量');
  660. }
  661. $ghsName = $cg->ghsName ?? '';
  662. $orderSn = $cg->orderSn ?? '';
  663. $list = PurchaseItemClass::getAllByCondition(['orderSn' => $orderSn], null, '*', null, true);
  664. if (empty($list)) {
  665. util::fail('没有找到花材哦');
  666. }
  667. $weight = 0;
  668. $itemPrice = 0;
  669. foreach ($list as $key => $val) {
  670. $productId = $val->productId ?? 0;
  671. if (isset($product[$productId]) == false) {
  672. util::fail('没有找到对应采购花材');
  673. }
  674. $num = $product[$productId]['num'] ?? 0;
  675. $price = $product[$productId]['price'] ?? 0;
  676. if ($price <= 0) {
  677. util::fail('花材金额需要大于0');
  678. }
  679. $totalPrice = bcmul($num, $price, 2);
  680. $itemPrice = bcadd($itemPrice, $totalPrice, 2);
  681. $val->price = $price;
  682. $val->itemNum = $num;
  683. $val->preTotalPrice = $totalPrice;
  684. $val->totalPrice = $totalPrice;
  685. $val->xhNum = $num;
  686. $val->xhUnitPrice = $price;
  687. $val->xhPrice = $totalPrice;
  688. $val->save();
  689. $unitWeight = $val->unitWeight ?? 0;
  690. $currentWeight = bcmul($num, $unitWeight, 2);
  691. $weight = bcadd($weight, $currentWeight, 2);
  692. $unitType = $val->xhUnitType ?? 0;
  693. $bigNum = 0;
  694. $smallNum = 0;
  695. if ($unitType == dict::getDict('unitType', 'big')) {
  696. $bigNum = $num;
  697. } else {
  698. $smallNum = $num;
  699. }
  700. //增加库存
  701. $option = ['relateName' => $ghsName];
  702. StockClass::purchaseItem($orderSn, $sjId, $shopId, $productId, $bigNum, $smallNum, $option);
  703. }
  704. $cg->itemPrice = $itemPrice;
  705. $sendCost = $cg->sendCost ?? 0;
  706. $currentPrice = bcadd($itemPrice, $sendCost, 2);
  707. $packCost = $cg->packCost ?? 0;
  708. $currentPrice = bcadd($currentPrice, $packCost, 2);
  709. $kiloFee = $data['kiloFee'] ?? 0;
  710. $miniKilo = $data['miniKilo'] ?? 0;
  711. $calcWeight = $weight > $miniKilo ? $weight : $miniKilo;
  712. $allKiloFee = bcmul($calcWeight, $kiloFee, 2);
  713. $currentPrice = bcadd($currentPrice, $allKiloFee, 2);
  714. $cg->prePrice = $currentPrice;
  715. $cg->orderPrice = $currentPrice;
  716. $cg->actPrice = $currentPrice;
  717. $cg->realPrice = $currentPrice;
  718. $cg->stockChange = 1;
  719. $cg->save();
  720. $mainId = $cg->mainId ?? 0;
  721. $sjId = $cg->sjId ?? 0;
  722. $shopId = $cg->shopId ?? 0;
  723. $cgId = $cg->id ?? 0;
  724. $saleRefundId = $data['saleRefundId'] ?? 0;
  725. $shop = ShopClass::getLockById($shopId);
  726. if (empty($shop)) {
  727. util::fail('没有找到零售店的门店');
  728. }
  729. $main = MainClass::getLockById($mainId);
  730. if (empty($main)) {
  731. util::fail('没有main信息12');
  732. }
  733. $main->cgUnSend -= 1;
  734. $main->cgFinish += 1;
  735. $main->save();
  736. $cgRefund = null;
  737. $bookPrice = $cg->bookPrice ?? 0;
  738. if ($bookPrice == $currentPrice) {
  739. return ['refund' => $cgRefund];
  740. } elseif ($bookPrice > $currentPrice) {
  741. //退款
  742. $refundPrice = bcsub($bookPrice, $currentPrice, 2);
  743. $book = 1;
  744. $refundOrderSn = orderSn::getCgRefundSn();
  745. $refundType = CgRefundClass::REFUND_TYPE_MONEY;
  746. $refundData = [
  747. 'book' => $book,
  748. 'mainId' => $mainId,
  749. 'orderSn' => $refundOrderSn,
  750. 'cgId' => $cgId,
  751. 'status' => CgRefundClass::STATUS_COMPLETE,
  752. 'shopAdminId' => 0,
  753. 'shopAdminName' => '',
  754. 'refundType' => $refundType,
  755. 'refundPrice' => $refundPrice,
  756. 'saleRefundId' => $saleRefundId,
  757. 'sjId' => $sjId,
  758. 'shopId' => $shopId,
  759. ];
  760. $cgRefund = CgRefundClass::add($refundData, true);
  761. //门店收入增加
  762. $currentTotalIncome = bcadd($main->totalIncome, $refundPrice, 2);
  763. $main->totalIncome = $currentTotalIncome;
  764. $main->save();
  765. //供货商退款,向供货商采购总金额减少
  766. StatCgClass::replace($main, $shop, $refundPrice, 0, false);
  767. //供货商退款,按供货商分别采购的金额减少
  768. StatCgGhsClass::hdCgGhsReplace(false, $cg, $refundPrice, 0);
  769. $currentType = dict::getDict('capitalType', 'hdBookRefund', 'id');
  770. $sjId = $cg->sjId ?? 0;
  771. $shopId = $cg->shopId ?? 0;
  772. $event = "预订单{$orderSn}多退少补({$ghsName})";
  773. $capitalData = [
  774. 'capitalType' => $currentType,
  775. 'io' => 1,
  776. 'totalIncome' => $currentTotalIncome,
  777. 'payWay' => 0,
  778. 'amount' => $refundPrice,
  779. 'sjId' => $sjId,
  780. 'shopId' => $shopId,
  781. 'event' => $event,
  782. 'mainId' => $mainId,
  783. ];
  784. ShopCapitalClass::addCapital($capitalData);
  785. //收入统计
  786. StatIncomeClass::updateOrInsert($main, $shop, $refundPrice);
  787. $ghsId = $cg->ghsId ?? 0;
  788. $ghs = GhsClass::getLockById($ghsId);
  789. if (empty($ghs)) {
  790. util::fail('没有找到供货商');
  791. }
  792. $ghsShopId = $ghs->shopId ?? 0;
  793. $ghsShop = ShopClass::getById($ghsShopId, true);
  794. if (empty($ghsShop)) {
  795. util::fail('没有找到供货商的门店');
  796. }
  797. $refundFee = bcmul($refundPrice, 100);
  798. $merchantPrivateKeyPath = Yii::getAlias("@vendor/lakala") . '/production/api_private_key.pem';
  799. $lklCertificatePath = Yii::getAlias("@vendor/lakala") . '/production/lkl-apigw-v1.cer';
  800. $params = [
  801. 'appid' => 'OP00002119',
  802. 'serial_no' => '018b08cfddbd',
  803. 'merchant_no' => $ghsShop->lklSjNo,
  804. 'term_no' => $ghsShop->lklScanTermNo,
  805. 'merchantPrivateKeyPath' => $merchantPrivateKeyPath,
  806. 'lklCertificatePath' => $lklCertificatePath,
  807. ];
  808. $laResource = new Lakala($params);
  809. $refundReason = '';
  810. $aliParams = [
  811. 'refundSn' => $refundOrderSn,
  812. 'orderSn' => $orderSn,
  813. 'refundAmount' => $refundFee,
  814. 'refundReason' => $refundReason,
  815. ];
  816. $response = $laResource->refund($aliParams);
  817. if (isset($response['code']) == false || $response['code'] != 'BBS00000') {
  818. $errMsg = $response['msg'] ?? '';
  819. noticeUtil::push('退款失败了哦!请注意:' . $errMsg . ' 金额:' . $refundFee, '15280215347');
  820. util::fail('退款失败');
  821. }
  822. $refundTradeNo = isset($response['resp_data']['trade_no']) ? $response['resp_data']['trade_no'] : '';
  823. $cgRefund->thirdRefundNo = $refundTradeNo;
  824. $cgRefund->save();
  825. $cg->refundPrice = $refundPrice;
  826. $cg->tkPrice = bcadd($cg->tkPrice, $refundPrice, 2);
  827. $cg->refund = self::REFUND_YES;
  828. $cg->refundLog = 1;
  829. $cg->save();
  830. } else {
  831. //欠款
  832. $currentDebt = bcsub($currentPrice, $bookPrice, 2);
  833. $cg->debtPrice = $currentDebt;
  834. $cg->remainDebtPrice = $currentDebt;
  835. $cg->debt = PurchaseClass::DEBT_YES;
  836. $cg->save();
  837. $payWay = dict::getDict('payWay', 'debtPay');
  838. $ghsId = $cg->ghsId ?? 0;
  839. $ghs = GhsClass::getLockById($ghsId);
  840. if (empty($ghs)) {
  841. util::fail('没有找到供货商');
  842. }
  843. \bizHd\ghs\classes\GhsClass::cgDebtAmountAdd($ghs, $cg, true);
  844. //支出统计
  845. StatOutClass::updateOrInsert($main, $shop, $currentDebt);
  846. //支出流水
  847. $capitalType = dict::getDict('capitalType', 'hdBookFinalPay', 'id');
  848. $sjId = $cg->sjId ?? 0;
  849. $shopId = $cg->shopId ?? 0;
  850. $currentExpend = bcadd($main->totalExpend, $currentDebt, 2);
  851. $main->totalExpend = $currentExpend;
  852. $main->save();
  853. $event = "预订单{$orderSn}补尾款欠款";
  854. $capitalData = [
  855. 'capitalType' => $capitalType,
  856. 'io' => 0,
  857. 'totalExpend' => $currentExpend,
  858. 'payWay' => $payWay,
  859. 'amount' => $currentDebt,
  860. 'sjId' => $sjId,
  861. 'shopId' => $shopId,
  862. 'event' => $event,
  863. 'mainId' => $mainId,
  864. ];
  865. ShopCapitalClass::addCapital($capitalData);
  866. //补款给供货商,采购总金额增加
  867. StatCgClass::replace($main, $shop, $currentDebt, 0, true);
  868. //补款给供货商,按供货商分别统计采购量增加
  869. StatCgGhsClass::hdCgGhsReplace(true, $cg, $currentDebt, 0);
  870. }
  871. return ['refund' => $cgRefund];
  872. }
  873. //添加采购 ssh 2021.1.18
  874. public static function addPurchase($data, $ghs)
  875. {
  876. $shopId = $data['shopId'] ?? 0;
  877. $sjId = $data['sjId'] ?? 0;
  878. $mainId = $data['mainId'] ?? 0;
  879. $ghsId = $data['ghsId'] ?? 0;
  880. $book = $data['book'] ?? 0;
  881. $shopAdminId = $data['shopAdminId'] ?? 0;
  882. $customId = $data['customId'] ?? 0;
  883. $snData = ['shopId' => $shopId, 'mainId' => $mainId, 'ghsId' => $ghsId, 'customId' => $customId];
  884. $orderSn = orderSn::getPurchaseSn($snData);
  885. $data['orderSn'] = $orderSn;
  886. $prePrice = 0;
  887. $live = $ghs['live'] ?? 1;
  888. $sendTimeWant = !empty($data['sendTimeWant']) ? $data['sendTimeWant'] : date("Y-m-d");
  889. if ($sendTimeWant < date("Y-m-d")) {
  890. util::fail('您选了过去时间');
  891. }
  892. $data['sendTimeWant'] = $sendTimeWant;
  893. if (empty($data['product'])) {
  894. util::fail('请选择花材17');
  895. }
  896. $productList = $data['product'];
  897. $productList = self::mergeItemInfo($productList);
  898. $data['kindNum'] = count($productList); //多少种花材
  899. //传过来的是供货商的productId,需要转换为零售端的productId
  900. //数据格式 [{"productId":"113","bigNum":1,"smallNum":0,"classId":"-2","hdProductId":1}]
  901. if ($live == 1) {
  902. //花店真实向批发店采购花材,因为拿的供货商的ID,所以需要转化花店的id
  903. $productList = ProductClass::toggleProductList($productList, $shopId, $sjId, $mainId, $ghs);
  904. $ghsProductData = self::getProductMapData($productList, "ghsProductId");
  905. } else {
  906. //虚拟采购用的自己的ID所以不需要转化
  907. $ghsProductData = [];
  908. }
  909. $hdProductData = self::getProductMapData($productList, "productId");
  910. $giveLevel = $ghs['giveLevel'] ?? 0;
  911. $priceMap = CustomClass::$levelPriceKeyMap;
  912. //这个参数应该是要作废的,但下面加的参数是有用的,多处要同步修改,关键词 abandon_add_price_map ,ssh 20260116
  913. $addPriceMap = CustomClass::$levelAddPriceKeyMap;
  914. //但这边加的参数是有用的,给指定客户涨价的
  915. $addPriceMap['risePercent'] = $ghs['risePercent'] ?? 0;
  916. //累计满减
  917. $totalReachDiscount = 0;
  918. //计算价格= 各个productId的price*num(bigNum,smallNum) + sendCost(配送费)
  919. $bigNum = 0; //总共多少扎
  920. $smallNum = 0; //总共多少支
  921. $totalWeight = 0;
  922. foreach ($productList as $key => $product) {
  923. $currentBigNum = $product['bigNum'] ?? 0;
  924. $currentSmallNum = $product['smallNum'] ?? 0;
  925. $bigNum += $product['bigNum'] ?? 0;
  926. $smallNum += $product['smallNum'] ?? 0;
  927. $productList[$key]['orderSn'] = $orderSn;
  928. if ($live == 1) {
  929. $ghsProductId = $product['ghsProductId'];
  930. $hdProductId = $product['productId'];
  931. } else {
  932. $hdProductId = $product['productId'] ?? 0;
  933. $ghsProductId = 0;
  934. }
  935. $unitWeight = $hdProductData[$hdProductId]['weight'] ?? 0;
  936. $variety = $hdProductData[$hdProductId]['variety'] ?? 0;
  937. $ratio = $hdProductData[$hdProductId]['ratio'] ?? 0;
  938. $ratioType = $hdProductData[$hdProductId]['ratioType'] ?? 0;
  939. $itemId = $hdProductData[$hdProductId]['itemId'] ?? 0;
  940. $rank = $hdProductData[$hdProductId]['rank'] ?? 'B';
  941. $stock = $hdProductData[$hdProductId]['stock'] ?? 0;
  942. $kind = $hdProductData[$hdProductId]['kind'] ?? 0;
  943. $stockFormat = ProductClass::formatStock($stock, $ratio);
  944. $limitKey = ProductClass::LIMIT_BUY_KEY . $ghsProductId; // 注意:要使用批发的花材id
  945. $hasNum = Yii::$app->redis->executeCommand('HGET', [$limitKey, $customId]);
  946. $hasBuyNum = $hasNum ?: 0;
  947. $itemNum = ProductClass::mergeItemNum($product['bigNum'], $product['smallNum'], $ratio);
  948. $hasBuyNum = bcadd($itemNum, $hasBuyNum, 2); // 已购买总数量
  949. $weight = $hdProductData[$hdProductId]['weight'] ?? 0;
  950. $currentWeight = bcmul($weight, $itemNum, 2);
  951. $totalWeight = bcadd($currentWeight, $totalWeight, 2);
  952. //1、供货商开单改价 2、花店向虚拟供货商采购录入价格
  953. $userPrice = isset($product['userPrice']) && $product['userPrice'] > 0 ? $product['userPrice'] : 0;
  954. $currentGhsProduct = $ghsProductData[$ghsProductId] ?? [];
  955. if (!empty($currentGhsProduct)) {
  956. //用批发店的花材名称
  957. $itemName = $currentGhsProduct['name'] ?? '';
  958. $cover = $currentGhsProduct['cover'] ?? '';
  959. //如果零售店自己下预订单,预付0.1元,有两个地方要同步修改,搜索关键词 pre0.1
  960. if ($book == 1 && $shopAdminId > 0) {
  961. $price = 0.1;
  962. } else {
  963. //用批发店花材的价格
  964. $price = ProductClass::getFinalPrice($currentGhsProduct, $giveLevel, $priceMap, $addPriceMap, $userPrice, $itemNum, $hasBuyNum);
  965. }
  966. $thisPrice = $price;
  967. $reachNum = $currentGhsProduct['reachNum'] ?? 0;
  968. if ($reachNum > 0) {
  969. if ($itemNum >= $reachNum) {
  970. $reachNumDiscount = $currentGhsProduct['reachNumDiscount'] ?? 0;
  971. $currentReachDiscount = bcmul($reachNumDiscount, $itemNum, 2);
  972. $totalReachDiscount = bcadd($totalReachDiscount, $currentReachDiscount, 2);
  973. }
  974. }
  975. } else {
  976. $currentHdProduct = $hdProductData[$hdProductId] ?? [];
  977. if (empty($currentHdProduct)) {
  978. util::fail('花材有问题哦');
  979. }
  980. $itemName = $currentHdProduct['name'] ?? '';
  981. $cover = $currentHdProduct['cover'] ?? '';
  982. $price = $userPrice;
  983. $thisPrice = $userPrice;
  984. }
  985. if ($currentSmallNum > 0) {
  986. $productTotalPrice = bcmul($currentSmallNum, $price, 2);
  987. } else {
  988. $productTotalPrice = bcmul($currentBigNum, $price, 2);
  989. }
  990. $itemInfo = [
  991. 'itemName' => $itemName,
  992. 'itemCover' => $cover,
  993. 'bigNum' => $product['bigNum'] ?? 0,
  994. 'smallNum' => $product['smallNum'] ?? 0,
  995. 'bigNumStock' => $stockFormat['bigNum'],
  996. 'smallNumStock' => $stockFormat['smallNum'],
  997. 'itemUnit' => $ratio ? 2 : 1,
  998. 'ratio' => $ratio,
  999. 'rank' => $rank,
  1000. 'bigUnit' => $hdProductData[$hdProductId]['bigUnit'],
  1001. 'smallUnit' => $hdProductData[$hdProductId]['smallUnit'],
  1002. ];
  1003. if ($itemNum <= 0) {
  1004. util::fail($itemName . ' 数量要大于零');
  1005. }
  1006. $productList[$key]['itemInfo'] = json_encode($itemInfo);
  1007. $productList[$key]['variety'] = $variety;
  1008. $productList[$key]['itemId'] = $itemId;
  1009. $productList[$key]['preItemNum'] = $itemNum;
  1010. $productList[$key]['itemNum'] = $itemNum;
  1011. $productList[$key]['bigNum'] = $product['bigNum'] ?? 0;
  1012. $productList[$key]['smallNum'] = $product['smallNum'] ?? 0;
  1013. $productList[$key]['price'] = $thisPrice;
  1014. $productList[$key]['ratio'] = $ratio;
  1015. $productList[$key]['ratioType'] = $ratioType;
  1016. $productList[$key]['unitWeight'] = $unitWeight;
  1017. $productList[$key]['totalPrice'] = $productTotalPrice;
  1018. $productList[$key]['preTotalPrice'] = $productTotalPrice;
  1019. $productList[$key]['productId'] = $hdProductId;
  1020. $productList[$key]['ghsProductId'] = $ghsProductId;
  1021. $productList[$key]['smallPrice'] = $price;
  1022. $productList[$key]['mainId'] = $mainId;
  1023. $productList[$key]['ghsId'] = $ghsId;
  1024. $productList[$key]['name'] = $itemName;
  1025. $productList[$key]['cover'] = $cover;
  1026. $productList[$key]['kind'] = $kind;
  1027. $currentBigUnit = $hdProductData[$hdProductId]['bigUnit'] ?? '';
  1028. $currentSmallUnit = $hdProductData[$hdProductId]['smallUnit'] ?? '';
  1029. if ($currentBigNum > 0) {
  1030. $xhNum = $currentBigNum;
  1031. $xhUnitName = $currentBigUnit;
  1032. $xhUnitType = dict::getDict('unitType', 'big');
  1033. } else {
  1034. $xhNum = $currentSmallNum;
  1035. $xhUnitName = $currentSmallUnit;
  1036. $xhUnitType = dict::getDict('unitType', 'small');
  1037. }
  1038. $itemPrice = $price;
  1039. $price = bcmul($itemPrice, $xhNum, 2);
  1040. //客户下单时会出现同时选了扎和支,很奇怪,前端没有找到原因,后端限制
  1041. if ($currentBigNum > 0 && $currentSmallNum > 0) {
  1042. util::fail($itemName . " {$currentBigUnit}和{$currentSmallUnit}只能选一种");
  1043. }
  1044. $productList[$key]['xhNum'] = $xhNum;
  1045. $productList[$key]['xhUnitName'] = $xhUnitName;
  1046. $productList[$key]['xhUnitType'] = $xhUnitType;
  1047. $productList[$key]['xhUnitPrice'] = $itemPrice;
  1048. $productList[$key]['xhPrice'] = $price;
  1049. $productList[$key]['xhPreNum'] = $xhNum;
  1050. $productList[$key]['xhPreUnitName'] = $xhUnitName;
  1051. $productList[$key]['xhPreUnitType'] = $xhUnitType;
  1052. $productList[$key]['xhPreUnitPrice'] = $itemPrice;
  1053. $productList[$key]['xhPrePrice'] = $price;
  1054. $prePrice = bcadd($prePrice, $productTotalPrice, 2);
  1055. }
  1056. $data['itemPrice'] = $prePrice;
  1057. $sendCost = $data['sendCost'] ?? 0.00;
  1058. $prePrice = bcadd($prePrice, $sendCost, 2);
  1059. $packCost = $data['packCost'] ?? 0;
  1060. $prePrice = bcadd($prePrice, $packCost, 2);
  1061. $data['weight'] = $totalWeight;
  1062. //预订单需要增加服务费
  1063. if ($book == 1) {
  1064. $kiloFee = $ghs['kiloFee'] ?? 0;
  1065. $miniKilo = $ghs['miniKilo'] ?? 0;
  1066. $calcWeight = max($totalWeight, $miniKilo);
  1067. $allKiloFee = bcmul($calcWeight, $kiloFee, 2);
  1068. $prePrice = bcadd($prePrice, $allKiloFee, 2);
  1069. $data['allKiloFee'] = $allKiloFee;
  1070. $data['kiloFee'] = $kiloFee;
  1071. $data['miniKilo'] = $miniKilo;
  1072. $data['stockChange'] = 0;
  1073. }
  1074. $actPrice = $prePrice;
  1075. if (isset($data['modifyPrice'])) {
  1076. $modifyPrice = $data['modifyPrice'];
  1077. if ($modifyPrice < $prePrice) {
  1078. //优惠金额
  1079. $data['discountAmount'] = bcsub($prePrice, $modifyPrice, 2);
  1080. $data['discountType'] = dict::getDict('discountType', 'discount');
  1081. }
  1082. if ($modifyPrice > $prePrice) {
  1083. //人工和资材费用
  1084. $data['labourCost'] = bcsub($modifyPrice, $prePrice, 2);
  1085. }
  1086. $actPrice = $modifyPrice;
  1087. if ($book == 1) {
  1088. $actPrice = 0;
  1089. }
  1090. } else {
  1091. //客户自己下单才有整单满减,门店帮忙开单没有,,多个地方要同步修改,关键词 meet_amount_num_reduce
  1092. if ($book == 0) {
  1093. $ghsShopId = $ghs['shopId'] ?? 0;
  1094. $ghsShop = ShopClass::getById($ghsShopId, true);
  1095. if (!empty($ghsShop)) {
  1096. $meetNum = $ghsShop->meetNum ?? 0;
  1097. $meetAmount = $ghsShop->meetAmount ?? 0;
  1098. $cutStyle = $ghsShop->cutStyle ?? 0;
  1099. $cutOption = $ghsShop->cutAmount ?? 0;
  1100. if ($cutStyle == 0) {
  1101. $cutAmount = $cutOption;
  1102. } else {
  1103. $miniOption = bcsub(1, $cutOption, 2);
  1104. $cutAmount = bcmul($actPrice, $miniOption, 2);
  1105. }
  1106. if ($cutAmount > 0 && $meetNum > 0 && $meetAmount > 0) {
  1107. if ($bigNum >= $meetNum && $data['itemPrice'] >= $meetAmount) {
  1108. if ($cutAmount < $actPrice) {
  1109. $actPrice = bcsub($actPrice, $cutAmount, 2);
  1110. $data['orderReachDiscountPrice'] = $cutAmount;
  1111. } else {
  1112. noticeUtil::push('订单金额不足满减金额,ghsShopId:' . $ghsShopId, '15280215347');
  1113. }
  1114. }
  1115. }
  1116. }
  1117. }
  1118. }
  1119. //如果有设置指定客户涨价百分之几,然后又设置了涨价的幅度。【这个功能主要用于客户不收他运费,门店不赚钱,收他运费客户不乐意,所以把运费加到花材里】,多处同步修改,关键词 rise_percent_rang
  1120. if (isset($data['itemPrice'])) {
  1121. if (isset($data['orderReachDiscountPrice'])) {
  1122. $originActPrice = bcadd($actPrice, $data['orderReachDiscountPrice'], 2);
  1123. } else {
  1124. $originActPrice = $actPrice;
  1125. }
  1126. if ($originActPrice >= $data['itemPrice']) {
  1127. if (isset($ghs['risePercent']) && $ghs['risePercent'] > 0) {
  1128. if (isset($ghs['riseRange']) && $ghs['riseRange'] > 0) {
  1129. $risePercent = $ghs['risePercent'];
  1130. $riseRange = $ghs['riseRange'];
  1131. // 计算涨价金额:涨价后金额 * (涨价百分比 / (100 + 涨价百分比))
  1132. $riseAmount = bcmul($data['itemPrice'], bcdiv($risePercent, bcadd(100, $risePercent, 0), 4), 2);
  1133. if ($riseAmount > $riseRange) {
  1134. //应该退回的金额
  1135. $backAmount = bcsub($riseAmount, $riseRange, 2);
  1136. $actPrice = bcsub($actPrice, $backAmount, 2);
  1137. if (isset($data['orderReachDiscountPrice'])) {
  1138. if ($data['orderReachDiscountPrice'] < $backAmount) {
  1139. //前面整单满减的,就不减了,所以这里面加回来
  1140. $actPrice = bcadd($actPrice, $data['orderReachDiscountPrice'], 2);
  1141. //改成减多加钱里面的
  1142. $data['orderReachDiscountPrice'] = $backAmount;
  1143. }
  1144. } else {
  1145. $data['orderReachDiscountPrice'] = $backAmount;
  1146. }
  1147. }
  1148. }
  1149. }
  1150. }
  1151. }
  1152. //这个字段记录每个花材满多少扎减掉的金额,并汇总金额,区别于整单满减的 $cutAmount。保存起来应该是在哪里有用,$totalReachDiscount在这边不影响actPrice,估计因为取花材的价格里::getFinalPrice()已经使用了优惠后的价格,有多处,关键词 reachDiscountPrice_explain ssh 20260116
  1153. $data['reachDiscountPrice'] = $totalReachDiscount;
  1154. $data['prePrice'] = $prePrice;
  1155. $data['bookPrice'] = $actPrice;
  1156. $data['orderPrice'] = $actPrice;
  1157. $data['actPrice'] = $actPrice;
  1158. $data['realPrice'] = $actPrice;
  1159. $data['bigNum'] = $bigNum;
  1160. $data['smallNum'] = $smallNum;
  1161. $data['discount'] = 1;
  1162. $data['status'] = self::STATUS_UN_PAY;
  1163. //采购单有效期
  1164. $currentTime = time();
  1165. $validTime = dict::getDict('order_pay_has_time');
  1166. $current = $currentTime + $validTime;
  1167. $data['deadline'] = $data['deadline'] ?? date("Y-m-d H:i:s", $current);
  1168. if ($book == 1) {
  1169. $fiveTime = bcmul(86400, 5);
  1170. $bookDeadline = bcadd($currentTime, $fiveTime);
  1171. $data['deadline'] = date("Y-m-d H:i:s", $bookDeadline);
  1172. }
  1173. //采购单自动记为欠款单时间
  1174. $localConfirmTime = dict::getDict('local_gys_kd_auto_set_debt_time');
  1175. $currentSet = $currentTime + $localConfirmTime;
  1176. $data['autoSetTime'] = $data['autoSetTime'] ?? date("Y-m-d H:i:s", $currentSet);
  1177. $data['salt'] = $data['salt'] ?? stringUtil::charsShuffleLowerCase(10);
  1178. //保存订单
  1179. $respond = self::add($data, true);
  1180. foreach ($productList as $productVal) {
  1181. //增加采购单的花材
  1182. $returnItem = PurchaseItemClass::add($productVal, true);
  1183. $productId = $productVal['productId'];
  1184. $unitPrice = $returnItem->price ?? 0;
  1185. $currentId = $returnItem->id ?? 0;
  1186. $currentPtItemId = $returnItem->itemId ?? 0;
  1187. if (!empty($data['xj'][$currentPtItemId])) {
  1188. $xjArr = $data['xj'][$currentPtItemId];
  1189. if (is_array($xjArr)) {
  1190. $ids = array_column($xjArr, 'id');
  1191. $sjInfo = XjClass::getByIds($ids, null, 'id');
  1192. $xjData = [];
  1193. foreach ($xjArr as $xjItem) {
  1194. $id = $xjItem['id'] ?? 0;
  1195. $num = $xjItem['num'] ?? 0;
  1196. $name = $sjInfo[$id]['name'] ?? '';
  1197. $cover = $sjInfo[$id]['cover'] ?? '';
  1198. $xjData[] = ['xjId' => $id, 'name' => $name, 'ptItemId' => $currentPtItemId,
  1199. 'num' => $num, 'price' => $unitPrice, 'itemId' => $currentId, 'cover' => $cover];
  1200. }
  1201. CgXjClass::batchAdd($xjData);
  1202. $returnItem->variety = 1;
  1203. $returnItem->save();
  1204. }
  1205. }
  1206. if (!empty($data['treeData'][$currentPtItemId])) {
  1207. $myTreeData = $data['treeData'][$currentPtItemId];
  1208. foreach ($myTreeData as $treeItem) {
  1209. $treeNum = $treeItem['num'] ?? 0;
  1210. $treeParams = [
  1211. 'orderSn' => $orderSn,
  1212. 'num' => $treeNum,
  1213. 'productId' => $productId,
  1214. ];
  1215. CgTreeClass::add($treeParams);
  1216. $dishNum = count($myTreeData);
  1217. $returnItem->dishNum = $dishNum;
  1218. $returnItem->save();
  1219. }
  1220. }
  1221. }
  1222. $shop = ShopClass::getLockById($shopId);
  1223. if (empty($shop)) {
  1224. util::fail('没有找到门店59 ' . $shopId);
  1225. }
  1226. $mainId = $shop->mainId ?? 0;
  1227. $main = MainClass::getLockById($mainId);
  1228. if (empty($main)) {
  1229. util::fail('没有main信息13');
  1230. }
  1231. $main->totalPurchaseOrder += 1;
  1232. $main->cgUnPay += 1;
  1233. $main->save();
  1234. return $respond;
  1235. }
  1236. //添加采购 ssh 2021.1.18
  1237. public static function updatePurchase($purchase, $data)
  1238. {
  1239. util::fail('已删除');
  1240. }
  1241. //组合数据 ssh 2021.1.25
  1242. public static function groupPurchase($list, $showButton = false, $showProduct = false)
  1243. {
  1244. $ghsIds = array_unique(array_filter(array_column($list, 'ghsId')));
  1245. $ghsInfo = GhsClass::getGhsByIds($ghsIds);
  1246. $adminIds = array_unique(array_filter(array_column($list, 'adminId')));
  1247. $adminInfo = AdminClass::getAdminByIds($adminIds, null, 'id');
  1248. $time = time();
  1249. foreach ($list as $key => $val) {
  1250. //剩余支付时间
  1251. $remainPayTime = 0;
  1252. $deadline = $val['deadline'] ?? '';
  1253. if (!empty($deadline)) {
  1254. $deadTime = strtotime($deadline);
  1255. if (($deadTime - $time - 30) > 0) {
  1256. $remainPayTime = $deadTime - $time;
  1257. $remainPayTime = $remainPayTime - 30;
  1258. }
  1259. }
  1260. $list[$key]['remainPayTime'] = $remainPayTime;
  1261. $adminId = $val['adminId'] ?? 0;
  1262. $list[$key]['adminName'] = $adminInfo[$adminId]['name'] ?? '';
  1263. $ghsId = $val['ghsId'] ?? 0;
  1264. $list[$key]['supplierName'] = $ghsInfo[$ghsId]['name'] ?? '';
  1265. $list[$key]['supplierAvatar'] = $ghsInfo[$ghsId]['smallLogoUrl'] ?? '';
  1266. $list[$key]['supplierMobile'] = $ghsInfo[$ghsId]['mobile'] ?? '';
  1267. $list[$key]['supplierAddress'] = $ghsInfo[$ghsId]['address'] ?? '';
  1268. $list[$key]['debtAmount'] = $ghsInfo[$ghsId]['debtAmount'] ?? '';
  1269. //剩余欠款
  1270. $balance = $ghsInfo[$ghsId]['balance'] ?? 0;
  1271. $debtAmount = $ghsInfo[$ghsId]['debtAmount'] ?? 0;
  1272. $ghsSalt = $ghsInfo[$ghsId]['salt'] ?? '';
  1273. $remainDebtAmount = bcsub($debtAmount, $balance, 2);
  1274. $list[$key]['remainDebtAmount'] = floatval($remainDebtAmount);
  1275. $list[$key]['inMyGhsBalance'] = floatval($balance);
  1276. $list[$key]['ghsSalt'] = $ghsSalt;
  1277. $list[$key]['lat'] = $ghsInfo[$ghsId]['lat'] ?? '';
  1278. $list[$key]['long'] = $ghsInfo[$ghsId]['long'] ?? '';
  1279. $list[$key]['supplierId'] = $ghsInfo[$ghsId]['id'] ?? '';
  1280. if ($showButton) {
  1281. $list[$key]['buttonList'] = [
  1282. ['type' => 'pay', 'show' => 1, 'disable' => 1],
  1283. ['type' => 'debtPay', 'show' => 1, 'disable' => 0],
  1284. ];
  1285. }
  1286. $list[$key]['sendProgress'] = [];
  1287. if ($showProduct) {
  1288. $orderSn = $val['orderSn'];
  1289. $orderItem = PurchaseItemClass::getOrderItemDetail($orderSn);
  1290. $itemData = [];
  1291. $xjData = [];
  1292. if ($orderItem) {
  1293. foreach ($orderItem as $v) {
  1294. $info = json_decode($v['itemInfo'], true);
  1295. $tmp = $info;
  1296. unset($v['itemInfo']);
  1297. if (!isset($tmp['rank'])) {
  1298. $tmp['rank'] = 'B';
  1299. }
  1300. $tmp['name'] = $tmp['itemName'] ?? '';
  1301. $tmp = array_merge($tmp, $v);
  1302. $shortCover = $info['itemCover'] ?? '';
  1303. $tmp['cover'] = imgUtil::groupImg($shortCover) . "?x-oss-process=image/resize,m_fill,h_130,w_130";
  1304. if (isset($tmp['variety']) && $tmp['variety'] == 1) {
  1305. $currentItemId = $tmp['id'] ?? 0;
  1306. $xjList = CgXjClass::getAllByCondition(['itemId' => $currentItemId], null, '*');
  1307. if (!empty($xjList)) {
  1308. foreach ($xjList as $xjKey => $xj) {
  1309. $xjBase = $tmp;
  1310. $num = $xj['num'] ?? 0;
  1311. $name = $xj['name'] ?? '';
  1312. $cover = $xj['cover'] ?? '';
  1313. $price = $xj['price'] ?? '';
  1314. $totalPrice = bcmul($num, $price, 2);
  1315. if ($num > 0) {
  1316. $xjBase['cover'] = imgUtil::groupImg($cover) . "?x-oss-process=image/resize,m_fill,h_130,w_130";
  1317. $xjBase['name'] = $name;
  1318. $xjBase['itemNum'] = floatval($num);
  1319. $xjBase['bigNum'] = floatval($num);
  1320. $xjBase['smallNum'] = 0;
  1321. $xjBase['price'] = $price;
  1322. $xjBase['totalPrice'] = $totalPrice;
  1323. $xjBase['xhNum'] = floatval($num);
  1324. $xjAddList[] = $xjBase;
  1325. }
  1326. $xjData[] = $xjBase;
  1327. }
  1328. } else {
  1329. $itemData[] = $tmp;
  1330. }
  1331. } else {
  1332. $itemData[] = $tmp;
  1333. }
  1334. }
  1335. if (!empty($xjData)) {
  1336. $itemData = array_merge($itemData, $xjData);
  1337. }
  1338. }
  1339. $list[$key]['product'] = $itemData;
  1340. }
  1341. }
  1342. return $list;
  1343. }
  1344. //订单取消,变更状态,占用库存释放 ssh 2021.5.8
  1345. public static function cancel($id)
  1346. {
  1347. $purchase = PurchaseClass::getLockById($id);
  1348. $purchase->status = self::STATUS_CANCEL;
  1349. $purchase->cancelTime = date("Y-m-d H:i:s");
  1350. $purchase->save();
  1351. $shopId = $purchase->shopId;
  1352. $orderSn = $purchase->orderSn ?? '';
  1353. $shop = ShopClass::getLockById($shopId);
  1354. if (empty($shop)) {
  1355. util::fail('没有找到门店60');
  1356. }
  1357. $mainId = $shop->mainId ?? 0;
  1358. $main = MainClass::getLockById($mainId);
  1359. if (empty($main)) {
  1360. util::fail('没有main信息14');
  1361. }
  1362. $main->cgUnPay -= 1;
  1363. $main->cgCancel += 1;
  1364. $main->save();
  1365. $ghsId = $purchase->ghsId;
  1366. $ghs = GhsClass::getById($ghsId, true);
  1367. if (empty($ghs)) {
  1368. util::fail('没有找到供货商');
  1369. }
  1370. $ghsShopId = $ghs->shopId ?? 0;
  1371. $ghsShop = ShopClass::getById($ghsShopId, true);
  1372. if (empty($ghsShop)) {
  1373. util::fail('没有找到供货商门店');
  1374. }
  1375. $merchantPrivateKeyPath = Yii::getAlias("@vendor/lakala") . '/production/api_private_key.pem';
  1376. $lklCertificatePath = Yii::getAlias("@vendor/lakala") . '/production/lkl-apigw-v1.cer';
  1377. $params = [
  1378. 'appid' => 'OP00002119',
  1379. 'serial_no' => '018b08cfddbd',
  1380. 'merchant_no' => $ghsShop->lklSjNo,
  1381. 'term_no' => $ghsShop->lklScanTermNo,
  1382. 'merchantPrivateKeyPath' => $merchantPrivateKeyPath,
  1383. 'lklCertificatePath' => $lklCertificatePath,
  1384. ];
  1385. $laResource = new Lakala($params);
  1386. $closeParams = ['orderSn' => $orderSn];
  1387. $response = $laResource->close($closeParams);
  1388. if (!isset($response['code']) || $response['code'] != 'BBS00000') {
  1389. $msg = $response['msg'] ?? '';
  1390. $code = $response['code'] ?? 0;
  1391. //主扫(手机上微信下单拉取微信支付)调用这个方法有效,如果收银机上扫客户收款码的,调用这个方法无效,具体说明看 https://o.lakala.com/#/home/document/detail?id=115 所以在这个取消方法,暂时不考虑关单成功与否 ssh 20250517
  1392. //noticeUtil::push('花店采购 ' . $orderSn . ' 关单没有成功哦' . $msg . ' ' . $code, '15280215347');
  1393. }
  1394. //收银台关单
  1395. $closeParams = ['orderSn' => $orderSn];
  1396. $response = $laResource->cashClose($closeParams);
  1397. if (!isset($response['code']) || $response['code'] != '000000') {
  1398. $msg = $response['msg'] ?? '';
  1399. $code = $response['code'] ?? 0;
  1400. //聚合收银台(APP发起的微信和支付支付)调用这个方法有效,说明 https://o.lakala.com/#/home/document/detail?id=722,其他情况调用无法,所以在这个取消方法,暂时不考虑关单成功与否 ssh 20250517
  1401. //noticeUtil::push('花店采购 ' . $orderSn . ' 收银台关单的提示:' . $msg . ' ' . $code, '15280215347');
  1402. }
  1403. return $purchase;
  1404. }
  1405. //采购统计2021-05-08
  1406. //采购数,采购金额统计(根据时间,今日,昨天,7天,30天)
  1407. public static function statOrderInfo($shopId, $statType)
  1408. {
  1409. $start = '';
  1410. $end = '';
  1411. switch ($statType) {
  1412. case "today":
  1413. $start = date('Y-m-d');
  1414. $end = $start;
  1415. break;
  1416. case "yesterday" :
  1417. $start = date('Y-m-d', strtotime("-1 day"));
  1418. $end = $start;
  1419. break;
  1420. case "seven":
  1421. $start = date('Y-m-d', strtotime("-6 day"));
  1422. $end = date('Y-m-d');
  1423. break;
  1424. case "thirty":
  1425. $start = date('Y-m-d', strtotime("-29 day"));
  1426. $end = date('Y-m-d');
  1427. break;
  1428. default:
  1429. }
  1430. $where = [];
  1431. $where['shopId'] = $shopId;
  1432. $where['addTime'] = ['between', [$start, $end]];
  1433. $res = self::getAllByCondition($where, null, "id,actPrice");
  1434. $totalAmount = 0;
  1435. $totalNum = count($res);
  1436. foreach ($res as $v) {
  1437. $totalAmount = bcadd($totalAmount, $v['actPrice'], 2);
  1438. }
  1439. return [
  1440. 'totalAmount' => $totalAmount,
  1441. 'totalNum' => $totalNum,
  1442. ];
  1443. }
  1444. //采购单完成 ssh 2021.5.15
  1445. public static function complete($purchase)
  1446. {
  1447. $purchase->status = self::STATUS_COMPLETE;
  1448. $purchase->save();
  1449. $shopId = $purchase->shopId;
  1450. $shop = ShopClass::getLockById($shopId);
  1451. if (empty($shop)) {
  1452. util::fail('没有找到门店61');
  1453. }
  1454. $mainId = $shop->mainId ?? 0;
  1455. $main = MainClass::getLockById($mainId);
  1456. if (empty($main)) {
  1457. util::fail('没有main信息15');
  1458. }
  1459. $main->cgSending -= 1;
  1460. $main->cgFinish += 1;
  1461. $main->save();
  1462. /********订单完成后加库存 lqh 2021-05-10*********/
  1463. $orderSn = $purchase->orderSn;
  1464. $purchaseItem = PurchaseItemClass::getAllByCondition(['orderSn' => $orderSn], null, "*");
  1465. foreach ($purchaseItem as $v) {
  1466. $stockInfo = ProductClass::addStockByItemNum($v['productId'], $v['itemNum']);
  1467. //记录库存流水
  1468. $recordData = [];
  1469. $recordData['sjId'] = $purchase->sjId;
  1470. $recordData['shopId'] = $purchase->shopId;
  1471. $recordData['mainId'] = $purchase->mainId;
  1472. $recordData['itemId'] = $v['itemId'] ?? 0;
  1473. $recordData['itemNum'] = $v['itemNum'];
  1474. $recordData['oldStock'] = $stockInfo['oldStock'];
  1475. $recordData['newStock'] = $stockInfo['newStock'];
  1476. $recordData['productId'] = $v['productId'];
  1477. $recordData['orderSn'] = $orderSn;
  1478. StockRecordClass::addPurchaseOrderRecord($recordData);
  1479. }
  1480. }
  1481. //订单信息变更为配送中 ssh 2021.5.15
  1482. public static function sending($purchaseId)
  1483. {
  1484. $purchase = PurchaseClass::getById($purchaseId, true);
  1485. if (empty($purchase)) {
  1486. util::fail('没有采购单信息');
  1487. }
  1488. $purchase->status = PurchaseClass::STATUS_SENDING;
  1489. $purchase->save();
  1490. $shopId = $purchase->shopId;
  1491. $shop = ShopClass::getLockById($shopId);
  1492. if (empty($shop)) {
  1493. util::fail('没有找到门店62');
  1494. }
  1495. $shop->cgUnSend -= 1;
  1496. $shop->cgSending += 1;
  1497. $shop->save();
  1498. //自动完成订单时不需要通知
  1499. $noNeedWxNotice = isset(Yii::$app->params['noNeedWxNotice']) ? Yii::$app->params['noNeedWxNotice'] : 0;
  1500. if ($noNeedWxNotice == 0) {
  1501. WxMessageClass::cgOrderHasSend($shop, $purchase);
  1502. }
  1503. }
  1504. public static function valid($cg, $shopId)
  1505. {
  1506. if (isset($cg->shopId) == false || $cg->shopId != $shopId) {
  1507. util::fail('无法访问,编号1255');
  1508. }
  1509. }
  1510. }