MReceive.Class.php 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. <?php
  2. /**
  3. * 应收单管理模块
  4. * Created by PhpStorm.
  5. * User: wxj
  6. * Date: 2019/10/30
  7. * Time: 14:02
  8. */
  9. namespace JinDouYun\Model\Finance;
  10. use JinDouYun\Dao\Finance\DReceived;
  11. use JinDouYun\Dao\Finance\DReceiveOffset;
  12. use JinDouYun\Model\Order\MOrder;
  13. use function FastRoute\TestFixtures\empty_options_cached;
  14. use JinDouYun\Model\MBaseModel;
  15. use Mall\Framework\Core\ErrorCode;
  16. use Mall\Framework\Core\StatusCode;
  17. use Mall\Framework\Core\ResultWrapper;
  18. use JinDouYun\Dao\Finance\DReceive;
  19. use JinDouYun\Dao\Finance\DReceiveReceiptIndex;
  20. use JinDouYun\Model\Finance\MCustomerBalanceDetail;
  21. use JinDouYun\Model\Finance\MCustomerBalance;
  22. use JinDouYun\Cache\FinanceCache;
  23. class MReceive extends MBaseModel
  24. {
  25. private $objDReceive;
  26. private $objDReceiveReceiptIndex;
  27. private $objMCustomerBalanceDetail;
  28. private $objMCustomerBalance;
  29. private $objFinanceCache;
  30. private $objDReceived;
  31. private $objDReceiveOffset;
  32. private $enterpriseId;
  33. private $userCenterId;
  34. public function __construct($enterpriseId, $userCenterId)
  35. {
  36. parent::__construct($enterpriseId, $userCenterId);
  37. $this->enterpriseId = $enterpriseId;
  38. $this->userCenterId = $userCenterId;
  39. $this->objMCustomerBalanceDetail = new MCustomerBalanceDetail($enterpriseId, $userCenterId);
  40. $this->objMCustomerBalance = new MCustomerBalance($enterpriseId, $userCenterId);
  41. $this->objDReceive = new DReceive('finance');
  42. $this->objDReceiveReceiptIndex = new DReceiveReceiptIndex('finance');
  43. $this->objFinanceCache = new FinanceCache();
  44. $this->objDReceived = new DReceived('finance');
  45. $this->objDReceiveOffset = new DReceiveOffset('finance');
  46. $this->objDReceiveOffset->setTable('qianniao_receive_offset_'. $enterpriseId);
  47. $this->objDReceive->setTable('qianniao_receive_receipt_' . $enterpriseId . '_' . date('Y') . '_' . ceil(date('m') / 3));
  48. $this->objDReceiveReceiptIndex->setTable('qianniao_receive_receipt_index_' . $enterpriseId);
  49. $this->objDReceive->setSearchIndex('should_receive_receipt_search')->setType('should_receive_receipt');
  50. }
  51. /**
  52. * 临时财务脚本解决索引表id重复问题
  53. */
  54. public function tmp()
  55. {
  56. // 查询应收索引表
  57. $result = $this->objDReceiveReceiptIndex->select('id > 82');
  58. if ($result === false) {
  59. return ResultWrapper::fail($this->objDReceiveReceiptIndex->error(), ErrorCode::$dberror);
  60. }
  61. foreach ($result as $key => $value){
  62. $suffix = date('Y', $value['createTime']) . '_' . ceil(date('m', $value['createTime']) / 3);
  63. $this->objDReceive->setTable('qianniao_receive_receipt_' . $this->enterpriseId . '_' . $suffix);
  64. $dbResult = $this->objDReceive->get($value['receiveReceiptId']);
  65. if ($dbResult === false) {
  66. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  67. }
  68. // 把应收单id改成索引表的自增id
  69. $dbResult = $this->objDReceive->update(['id'=>$value['id']], $value['receiveReceiptId']);
  70. if ($dbResult === false) {
  71. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  72. }
  73. // 把索引表应收id改成空
  74. $result = $this->objDReceiveReceiptIndex->update(['receiveReceiptId'=>0], $value['id']);
  75. if ($result === false) {
  76. return ResultWrapper::fail($this->objDReceiveReceiptIndex->error(), ErrorCode::$dberror);
  77. }
  78. echo $value['id'].'操作完成'.PHP_EOL;
  79. }
  80. return ResultWrapper::success('全部更新完成');
  81. }
  82. /**
  83. * 添加应收单
  84. *
  85. * @param array $params 应收单数据
  86. *
  87. * @return ResultWrapper
  88. */
  89. public function addReceive($params)
  90. {
  91. $this->objDReceive->beginTransaction();
  92. // 生成编号
  93. $dbResult = $this->objDReceive->get('createTime >='.strtotime(date('Ymd'.'0:0:0')), 'no', 'createTime desc');
  94. if ($dbResult === false) {
  95. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  96. }
  97. if(empty($dbResult)){
  98. $params['no'] = createSerialNumberByDate('');
  99. }else{
  100. $params['no'] = createSerialNumberByDate($dbResult['no']);
  101. }
  102. //索引表数据
  103. $indexData = [
  104. 'receiveReceiptId' => 0,
  105. 'customerId' => $params['customerId'],
  106. 'sourceNo' => $params['sourceNo'],
  107. 'originId' => $params['originId'],
  108. 'auditStatus' => $params['auditStatus'],
  109. 'offsetStatus' =>($params['receiveMoney']<0) ? 5 : 4,
  110. 'financeTypeId' => $params['financeTypeId'],
  111. 'financeType' => $params['financeType'],
  112. 'shopId' => $params['shopId'],
  113. 'createTime' => $params['createTime'],
  114. 'updateTime' => $params['updateTime'],
  115. ];
  116. $receiveReceiptId = $this->objDReceiveReceiptIndex->insert($indexData);
  117. if ($receiveReceiptId === false) {
  118. $this->objDReceive->rollBack();
  119. return ResultWrapper::fail($this->objDReceiveReceiptIndex->error(), ErrorCode::$dberror);
  120. }
  121. //应付单检测重复数据
  122. $allResult = $this->objDReceive->get(['sourceNo'=>$params['sourceNo'],'receiveMoney'=>$params['receiveMoney']]);
  123. if( $allResult === false ){
  124. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  125. }
  126. if( !empty($allResult) ){
  127. return ResultWrapper::fail('应收单已经创建过了',ErrorCode::$notAllowAccess);
  128. }
  129. $params['id'] = $receiveReceiptId;
  130. $ReceiveId = $this->objDReceive->insert($params);
  131. if ($ReceiveId === false) {
  132. $this->objDReceive->rollBack();
  133. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  134. }
  135. $this->objDReceive->commit();
  136. /*
  137. $_id = self::createEsDocumentId($ReceiveId, $params['createTime']);
  138. $esData = $params;
  139. $esData['id'] = $ReceiveId;
  140. $esData['enterpriseId'] = $this->enterpriseId;
  141. $result = $this->objDReceive->addUpSearchIndexDocument($esData, $_id);
  142. if (isset($result['_shards']) && isset($result['_shards']['successful']) && $result['_shards']['successful'] == 1) {
  143. //echo "es操作成功";die;
  144. }else {
  145. file_put_contents('/www/wwwroot/logs/api.junhailan.com/elasticsearch.log',date('Y-m-d H:i:s').'生成应收单es错误,错误原因'.var_export($result,true).PHP_EOL,FILE_APPEND);
  146. }*/
  147. return ResultWrapper::success($receiveReceiptId);
  148. }
  149. /**
  150. * 生成es的文档id
  151. * @param $receiveId
  152. * @param $time
  153. * @return string
  154. */
  155. private function createEsDocumentId($receiveId, $time)
  156. {
  157. $t = date('Y', $time) . '_' . ceil(date('m', $time) / 3);
  158. return 'EnterpriseId_' . $this->enterpriseId . '_' . $t . '_receiveId_' . $receiveId;
  159. }
  160. /**
  161. * 获取应收单数据
  162. * @param $params
  163. * @return ResultWrapper
  164. */
  165. public function getReceiveInfo($params) {
  166. $suffix = date('Y', $params['createTime']) . '_' . ceil(date('m', $params['createTime']) / 3);
  167. $this->objDReceive->setTable('qianniao_receive_receipt_' . $this->enterpriseId . '_' . $suffix);
  168. $dbResult = $this->objDReceive->get($params['id']);
  169. if ($dbResult === false) {
  170. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  171. }
  172. if(!empty($dbResult)){
  173. $dbResult['no'] = StatusCode::$noPrefix[16] . '-' . $dbResult['no'];
  174. $dbResult['sourceNo'] = StatusCode::$noPrefix[1] .'-'.$dbResult['sourceNo'];
  175. $dbResult['customerCode'] = createCode(StatusCode::$code['customer']['prefix'], $dbResult['customerId'], StatusCode::$code['customer']['length']);
  176. }
  177. return ResultWrapper::success($dbResult);
  178. }
  179. /**
  180. * 更新应收单核销状态
  181. * @param $id
  182. * @param $offsetMoney
  183. * @param $createTime
  184. * @return ResultWrapper
  185. */
  186. public function updateOffsetStatus($id,$offsetMoney,$createTime)
  187. {
  188. $suffix = date('Y', $createTime) . '_' . ceil(date('m', $createTime) / 3);
  189. $this->objDReceive->setTable('qianniao_receive_receipt_' . $this->enterpriseId . '_' . $suffix);
  190. $shouldReceiveData = $this->objDReceive->get($id);
  191. if ($shouldReceiveData === false) {
  192. $this->objDReceive->rollBack();
  193. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  194. }
  195. if( empty($shouldReceiveData) ){
  196. return ResultWrapper::fail('要审核的单据不存在', ErrorCode::$contentNotExists);
  197. }
  198. // $notOffsetMoney = bcsub($shouldReceiveData['receiveMoney'], $offsetMoney, 4);
  199. //判断该单据是否
  200. $updateData = [
  201. 'offsetMoney' => bcadd(abs($offsetMoney), abs($shouldReceiveData['offsetMoney']),4),
  202. 'notOffsetMoney' => bcsub($shouldReceiveData['notOffsetMoney'], abs($offsetMoney),4),
  203. 'offsetStatus' => StatusCode::$delete
  204. ];
  205. switch (true)
  206. {
  207. case $updateData['notOffsetMoney'] == 0;
  208. $updateData['offsetStatus'] = StatusCode::$standard;
  209. break;
  210. case $updateData['notOffsetMoney'] == $shouldReceiveData['receiveMoney'];
  211. $updateData['offsetStatus'] = StatusCode::$delete;
  212. break;
  213. case $updateData['notOffsetMoney'] > 0 && $updateData['notOffsetMoney'] < $shouldReceiveData['receiveMoney'];
  214. $updateData['offsetStatus'] = StatusCode::$partion;
  215. break;
  216. }
  217. $beginTransactionStatus = $this->objDReceive->beginTransaction();
  218. unset($dbResult);
  219. $dbResult = $this->objDReceive->update($updateData, $id);
  220. if ($dbResult === false) {
  221. $this->objDReceive->rollBack();
  222. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  223. }
  224. //修改索引表状态
  225. unset($dbResult);
  226. $dbResult = $this->objDReceiveReceiptIndex->update(['offsetStatus' => $updateData['offsetStatus']], $id);
  227. if ($dbResult === false) {
  228. $this->objDReceive->rollBack();
  229. return ResultWrapper::fail($this->objDReceiveReceiptIndex->error(), ErrorCode::$dberror);
  230. }
  231. if($beginTransactionStatus){
  232. $this->objDReceive->commit();
  233. }
  234. return ResultWrapper::success($dbResult);
  235. }
  236. /**
  237. * 应收单审核
  238. * @param array $params
  239. * @return ResultWrapper
  240. * @throws \Exception
  241. */
  242. public function updateReceiveStatus($params)
  243. {
  244. // 根据创建时间切表
  245. $suffix = date('Y', $params['createTime']) . '_' . ceil(date('m', $params['createTime']) / 3);
  246. $this->objDReceive->setTable('qianniao_receive_receipt_' . $this->enterpriseId . '_' . $suffix);
  247. // 判断是否已审核
  248. $shouldReceiveData = $this->objDReceive->get($params['id']);
  249. if( $shouldReceiveData === false ){
  250. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  251. }
  252. if(empty($shouldReceiveData)){
  253. return ResultWrapper::fail('要审核的单据不存在', ErrorCode::$contentNotExists);
  254. }
  255. if ($shouldReceiveData['auditStatus'] == StatusCode::$auditStatus['auditPass']) {
  256. return ResultWrapper::fail('单据已审核', ErrorCode::$actionIsDo);
  257. }
  258. $beginTransactionStatus = $this->objDReceive->beginTransaction();
  259. // 修改应收单审核状态
  260. $dbResult = $this->objDReceive->update(['auditStatus' => StatusCode::$auditStatus['auditPass']], $params['id']);
  261. if ($dbResult === false) {
  262. $this->objDReceive->rollBack();
  263. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  264. }
  265. // 修改应收单索引表审核状态
  266. $dbResult = $this->objDReceiveReceiptIndex->update(['auditStatus' => StatusCode::$auditStatus['auditPass']], ['id' => $params['id']]);
  267. if ($dbResult === false) {
  268. $this->objDReceive->rollBack();
  269. return ResultWrapper::fail($this->objDReceiveReceiptIndex->error(), ErrorCode::$dberror);
  270. }
  271. // 获取客户余额
  272. $customerBalance = $this->objMCustomerBalance->getCustomerBalance($shouldReceiveData['customerId']);
  273. // 自动核销
  274. $autoOffset = self::autoOffset($customerBalance,$params['id'],$params['createTime']);
  275. if (!$autoOffset->isSuccess()) {
  276. $this->objDReceive->rollBack();
  277. return ResultWrapper::fail($autoOffset->getData(), $autoOffset->getErrorCode());
  278. }
  279. $detailData = [
  280. 'customerId' => $shouldReceiveData['customerId'],//'客户id',
  281. 'receiptTime' => $shouldReceiveData['createTime'],//'单据日期',
  282. 'sourceId' => $shouldReceiveData['id'],//'单据编号',
  283. 'sourceNo' => $shouldReceiveData['no'],//'单据编号',
  284. 'financeType' => $shouldReceiveData['financeType'],//'财务类型名称',
  285. 'financeTypeId' => $shouldReceiveData['financeTypeId'],//'财务类型id',
  286. 'originId' => $shouldReceiveData['originId'], // 订单id
  287. 'originNo' => $shouldReceiveData['sourceNo'], // 订单编号
  288. 'salesAmount' => bcadd($shouldReceiveData['receiveMoney'], $shouldReceiveData['discountMoney'], 4),//TODO:
  289. 'discountMoney' => $shouldReceiveData['discountMoney'],// '优惠金额',
  290. 'customerAmount' => $shouldReceiveData['receiveMoney'],// '客户承担金额',
  291. 'receivableAmount' => $shouldReceiveData['receiveMoney'],// '应收金额',
  292. 'actualReceivableAmount' => 0.00,//'实际收款金额',
  293. 'receivableBalance' => $customerBalance + $shouldReceiveData['receiveMoney'],//'应收款余额',
  294. 'remark' => '应收单审核通过,本单据应收'.$shouldReceiveData['receiveMoney'].'元',//'备注',
  295. 'createTime' => time(),//'创建日期',
  296. 'updateTime' => time(),//'修改日期',
  297. ];
  298. //添加客户余额明细
  299. $result = $this->objMCustomerBalanceDetail->addCustomerBalanceDetail($detailData);
  300. if ($result->isSuccess() === false) {
  301. $this->objDReceive->rollBack();
  302. return ResultWrapper::fail($result->getData(), $result->getErrorCode());
  303. }
  304. //编辑客户余额
  305. $result = $this->objMCustomerBalance->addCustomerBalance($shouldReceiveData['customerId'], $shouldReceiveData['receiveMoney']);
  306. if ($result->isSuccess() === false) {
  307. $this->objDReceive->rollBack();
  308. return ResultWrapper::fail($result->getData(), $result->getErrorCode());
  309. }
  310. // 判断该单据是否有已生成的应付单(根据orderId查找并且付款金额大于零)
  311. // if ($shouldReceiveData['receiveMoney']<0 && $shouldReceiveData['offsetMoney'] == 0){
  312. // $whereSql = ' WHERE orderId = ' . $shouldReceiveData['orderId'] . ' AND receiveMoney > 0';
  313. // $sql = 'SELECT * FROM ' .$this->objDReceive->get_Table().$whereSql;
  314. // $repeatReceiveData = $this->objDReceive->query($sql);
  315. // if ($repeatReceiveData === false) {
  316. // return ResultWrapper::fail('退款应付单不存在', ErrorCode::$dberror);
  317. // }
  318. // if(!empty($repeatReceiveData)){
  319. // foreach ($repeatReceiveData as $key =>$value){
  320. // $value['notOffsetMoney'] = bcadd($value['notOffsetMoney'], $shouldReceiveData['receiveMoney'],4);
  321. // $value['offsetMoney'] = abs($shouldReceiveData['receiveMoney']);
  322. // //更新源应付单核销金额,未核销金额
  323. // $updateDate = $this->objDReceive->update(['notOffsetMoney'=>$value['notOffsetMoney'],'offsetMoney'=>$value['offsetMoney']],['id'=>$value['id']]);
  324. // if ($updateDate === false) {
  325. // $this->objDReceive->rollBack();
  326. // return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  327. // }
  328. // }
  329. // }
  330. // }
  331. if ($beginTransactionStatus){
  332. $this->objDReceive->commit();
  333. }
  334. //修改订单支付状态
  335. $objMOrder = new MOrder($this->userCenterId, $this->enterpriseId);
  336. $offsetDbResult = $this->objDReceiveOffset->select(['receiveReceiptId'=>$params['id'],'type'=>StatusCode::$delete]);
  337. if ($offsetDbResult === false) {
  338. return ResultWrapper::fail($this->objDReceiveOffset->error(), ErrorCode::$dberror);
  339. }
  340. if(!empty($offsetDbResult)){
  341. foreach ($offsetDbResult as $offsetDbResultKey => $offsetDbResultValue){
  342. $orderIdDbResult = $this->objDReceive->get(['id' => $offsetDbResult[$offsetDbResultKey]['receiveReceiptId']]);
  343. if ($orderIdDbResult === false) {
  344. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  345. }
  346. if (empty($orderIdDbResult)) {
  347. return ResultWrapper::fail('应付单不存在', ErrorCode::$notAllowAccess);
  348. }
  349. //判断核销金额,未核销金额,来计算payStatus的状态
  350. $updateOrderPayData1 = ['payStatus' => StatusCode::$standard, 'payTime' => time()];
  351. $updateOrderPayData2 = ['id' => $orderIdDbResult['originId']];
  352. switch (true) {
  353. case $orderIdDbResult['offsetMoney'] == $orderIdDbResult['receiveMoney'];
  354. $updateOrderPayData1['payStatus'] = StatusCode::$standard;
  355. break;
  356. case $orderIdDbResult['offsetMoney'] == 0;
  357. $updateOrderPayData1['payStatus'] = StatusCode::$delete;
  358. break;
  359. case $orderIdDbResult['offsetMoney'] > 0 && $orderIdDbResult['offsetMoney'] < $orderIdDbResult['receiveMoney'];
  360. $updateOrderPayData1['payStatus'] = StatusCode::$partion;
  361. $updateOrderPayData1['notPayMoney'] = $orderIdDbResult['notOffsetMoney'];
  362. }
  363. $orderDbResult = $objMOrder->updateOrderPayData($updateOrderPayData1, $updateOrderPayData2);
  364. if ($orderDbResult->isSuccess() === false) {
  365. return ResultWrapper::fail($orderDbResult->getData(), $orderDbResult->getErrorCode());
  366. }
  367. }
  368. }
  369. //更新es的审核状态
  370. //$_id = self::createEsDocumentId($params['id'], $params['createTime']);
  371. //$this->objDReceive->esupdateTypeFieldVaule(['auditStatus'=>StatusCode::$auditStatus['auditPass']], $_id);
  372. /*
  373. $_id = self::createEsDocumentId($params['id'], $params['createTime']);
  374. $this->objDReceive->esupdateTypeFieldVaule(['auditStatus'=>StatusCode::$auditStatus['auditPass']], $_id);*/
  375. $this->objFinanceCache->delSalesOutReceive($this->enterpriseId, $params['id']);
  376. return ResultWrapper::success($dbResult);
  377. }
  378. /**
  379. * 获取所有应收单数据
  380. * @param array $selectParams 过滤条件
  381. * @return ResultWrapper
  382. * @throws \Exception
  383. */
  384. public function getAllReceive($selectParams, $isExport = false)
  385. {
  386. $limit = $selectParams['limit'];
  387. $offset = $selectParams['offset'];
  388. unset($selectParams['limit']);
  389. unset($selectParams['offset']);
  390. if($isExport){
  391. $limit = 9999;
  392. $offset = 0;
  393. }
  394. $whereSql = '';
  395. if (isset($selectParams['customerId']) && !empty($selectParams['customerId'])) {
  396. $where = empty($whereSql) ? ' WHERE ' : ' AND ';
  397. $whereSql .= $where . ' customerId = ' . $selectParams['customerId'];
  398. }
  399. if (isset($selectParams['offsetStatus']) && !empty($selectParams['offsetStatus'])) {
  400. // 数组转字符串
  401. $selectParams['offsetStatus'] = implode(',',$selectParams['offsetStatus']);
  402. $where = empty($whereSql) ? ' WHERE ' : ' AND ';
  403. $whereSql .= $where . ' offsetStatus in( ' . $selectParams['offsetStatus'].')';
  404. }
  405. if (isset($selectParams['receiveReceiptIds']) && !empty($selectParams['receiveReceiptIds'])) {
  406. $where = empty($whereSql) ? ' WHERE ' : ' AND ';
  407. $whereSql .= $where . ' receiveReceiptId in (' . implode(',', $selectParams['receiveReceiptIds']).')';
  408. }
  409. if (isset($selectParams['auditStatus']) && !empty($selectParams['auditStatus'])) {
  410. $where = empty($whereSql) ? ' WHERE ' : ' AND ';
  411. $whereSql .= $where . ' auditStatus = ' . $selectParams['auditStatus'];
  412. }
  413. if (isset($selectParams['shopId']) && !empty($selectParams['shopId'])) {
  414. $where = empty($whereSql) ? ' WHERE ' : ' AND ';
  415. $whereSql .= $where . ' shopId = ' . $selectParams['shopId'];
  416. }
  417. if ( (isset($selectParams['start']) && !empty($selectParams['start']))&&(isset($selectParams['end']) && !empty($selectParams['end'])) ) {
  418. $where = empty($whereSql) ? ' WHERE ' : ' AND ';
  419. $whereSql .= $where . ' createTime BETWEEN ' . $selectParams['start'] . ' AND '. $selectParams['end'];
  420. }
  421. $sql = 'SELECT * FROM ' .$this->objDReceiveReceiptIndex->get_Table().$whereSql . ' ORDER BY createTime DESC LIMIT ' . $offset . ' , ' . $limit;
  422. $receiveReceiptIndexResult = $this->objDReceiveReceiptIndex->query($sql);
  423. if ($receiveReceiptIndexResult === false) {
  424. return ResultWrapper::fail($this->objDReceiveReceiptIndex->error(), ErrorCode::$dberror);
  425. }
  426. $tableSuffix = [];
  427. foreach ($receiveReceiptIndexResult as $receiveReceiptIndex) {
  428. $k = date('Y', $receiveReceiptIndex['createTime']) . '_' . ceil(date('m', $receiveReceiptIndex['createTime']) / 3);
  429. $tableSuffix[$k][] = $receiveReceiptIndex['id'];
  430. }
  431. $receiveReceiptResult = [];
  432. foreach ($tableSuffix as $suffix => $receiveReceiptIds) {
  433. $this->objDReceive->setTable('qianniao_receive_receipt_' . $this->enterpriseId . '_' . $suffix);
  434. if($isExport){
  435. $dbResult = $this->objDReceive->exportSelect($receiveReceiptIds, '*', 'createTime desc');
  436. $tmpArray = [];
  437. foreach($dbResult as $key => $value){
  438. $tmpArray[] = $value;
  439. }
  440. $dbResult = $tmpArray;
  441. }else{
  442. $dbResult = $this->objDReceive->select($receiveReceiptIds, '*', 'createTime desc');
  443. }
  444. if ($dbResult === false) {
  445. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  446. }
  447. if(!empty($dbResult)){
  448. $receiveReceiptResult = array_merge($receiveReceiptResult, self::format($dbResult));
  449. }
  450. }
  451. $totalSql = 'SELECT COUNT(1) as count FROM ' .$this->objDReceiveReceiptIndex->get_Table() . $whereSql;
  452. $dbTotalResult = $this->objDReceive->query($totalSql);
  453. $return = [
  454. 'data' => $receiveReceiptResult,
  455. 'total' => ($dbTotalResult[0]['count']) ? intval($dbTotalResult[0]['count']) : 0,
  456. ];
  457. if($isExport){
  458. self::export($return['data']);
  459. }
  460. return ResultWrapper::success($return);
  461. }
  462. /**
  463. * 审核成功调用(预充余额)
  464. * @param array $params
  465. * @return ResultWrapper
  466. * @throws \Exception
  467. */
  468. public function autoOffset($customerBalance, $receiveId, $createTime)
  469. {
  470. // 切换应收单表
  471. $suffix = date('Y', $createTime) . '_' . ceil(date('m', $createTime) / 3);
  472. $this->objDReceive->setTable('qianniao_receive_receipt_' . $this->enterpriseId . '_' . $suffix);
  473. // 获取应收单数据
  474. $shouldReceiveData = $this->objDReceive->get($receiveId);
  475. if ($shouldReceiveData === false) {
  476. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  477. }
  478. if (empty($shouldReceiveData)) {
  479. return ResultWrapper::fail('应收单id'.$receiveId.'数据为空', ErrorCode::$dberror);
  480. }
  481. // 查询这笔应收对应的订单是否有收款记录
  482. $this->objDReceived->setTable('qianniao_received_' . $this->enterpriseId . '_' . date('Y', $createTime) . '_' . ceil(date('m', $createTime) / 3));
  483. $receivedDbResult = $this->objDReceived->query('select * from '.$this->objDReceived->get_Table().' where sourceId ='.$shouldReceiveData['originId'].' and sourceId !=0 limit 1');
  484. if ($receivedDbResult === false) {
  485. $this->objDReceive->rollBack();
  486. return ResultWrapper::fail($this->objDReceived->error(), ErrorCode::$dberror);
  487. }
  488. if (!empty($receivedDbResult)){ //说明该应收是在线支付 现货后款
  489. $receiveOffsetMoney = $shouldReceiveData['receiveMoney'];
  490. foreach ($receivedDbResult as $receivedKey => $receivedValue){
  491. switch (true){
  492. case bcsub($receiveOffsetMoney,$receivedValue['totalFinalMoney'],2) == 0; // 应收金额 = 收款金额
  493. $receiveOffsetDate = [
  494. 'offsetMoney' =>$receiveOffsetMoney,
  495. 'notOffsetMoney' =>0,
  496. 'offsetStatus' =>StatusCode::$standard
  497. ];
  498. $receiveIndexOffsetDate = [
  499. 'offsetStatus' => StatusCode::$standard
  500. ];
  501. $receivedOffsetDate = [
  502. 'offsetMoney' =>$receiveOffsetMoney,
  503. 'notOffsetMoney' =>0,
  504. 'offsetStatus' =>StatusCode::$standard
  505. ];
  506. break;
  507. case bcsub($receiveOffsetMoney,$receivedValue['totalFinalMoney'],2) > 0; // 应收金额 > 收款金额
  508. $receiveOffsetDate = [
  509. 'offsetMoney' =>$receivedValue['totalFinalMoney'],
  510. 'notOffsetMoney' =>bcsub($receiveOffsetMoney,$receivedValue['totalFinalMoney'],2),
  511. 'offsetStatus' =>StatusCode::$partion
  512. ];
  513. $receiveIndexOffsetDate = [
  514. 'offsetStatus' => StatusCode::$partion
  515. ];
  516. $receivedOffsetDate = [
  517. 'offsetMoney' =>$receivedValue['totalFinalMoney'],
  518. 'notOffsetMoney' =>0,
  519. 'offsetStatus' =>StatusCode::$standard
  520. ];
  521. break;
  522. case bcsub($receiveOffsetMoney,$receivedValue['totalFinalMoney'],2) < 0; // 应收金额 < 收款金额
  523. $receiveOffsetDate = [
  524. 'offsetMoney' =>$receiveOffsetMoney,
  525. 'notOffsetMoney' =>0,
  526. 'offsetStatus' =>StatusCode::$standard
  527. ];
  528. $receiveIndexOffsetDate = [
  529. 'offsetStatus' => StatusCode::$standard
  530. ];
  531. $receivedOffsetDate = [
  532. 'offsetMoney' =>$receiveOffsetMoney,
  533. 'notOffsetMoney' =>bcsub($receivedValue['totalFinalMoney'],$receiveOffsetMoney,2),
  534. 'offsetStatus' =>StatusCode::$partion
  535. ];
  536. }
  537. $updateOffsetStatus = $this->objDReceive->update($receiveOffsetDate,['id'=>$receiveId]);
  538. if ($updateOffsetStatus === false) {
  539. $this->objDReceive->rollBack();
  540. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  541. }
  542. $dbResult = $this->objDReceiveReceiptIndex->update($receiveIndexOffsetDate, ['id' => $receiveId,'createTime'=>$createTime]);
  543. if ($dbResult === false) {
  544. $this->objDReceive->rollBack();
  545. return ResultWrapper::fail($this->objDReceiveReceiptIndex->error(), ErrorCode::$dberror);
  546. }
  547. //在线支付的收款单直接核销
  548. $updateReceivedOffset = $this->objDReceived->update($receivedOffsetDate,['id'=>$receivedValue['id']]);
  549. if ($updateReceivedOffset === false) {
  550. $this->objDReceive->rollBack();
  551. return ResultWrapper::fail($this->objDReceived->error(), ErrorCode::$dberror);
  552. }
  553. // 记录核销明细
  554. //核销完成,记录核销明细
  555. $updateOffset = [
  556. 'receiveReceiptId' => $receiveId,
  557. 'receivedId' => $receivedValue['id'],
  558. 'offsetMoney' => $receiveOffsetDate['offsetMoney'],
  559. 'receiveCreateTime' => $shouldReceiveData['createTime'],
  560. 'type' => StatusCode::$delete
  561. ];
  562. $result = $this->objDReceiveOffset->insert($updateOffset);
  563. if ($result === false) {
  564. $this->objDReceived->rollBack();
  565. return ResultWrapper::fail($this->objDReceiveOffset->error(), ErrorCode::$dberror);
  566. }
  567. }
  568. }else{
  569. $offsetMoney = 0;
  570. $notOffsetMoney = 0;
  571. $offsetStatus = 5;
  572. if ($customerBalance < 0 && $shouldReceiveData['receiveMoney'] > 0){//说明客户是预收款进行自动核销
  573. switch (true)
  574. {
  575. case bcsub(abs($customerBalance),$shouldReceiveData['receiveMoney'],4) > 0;//说明预收款完全核销应收单金额
  576. $offsetMoney = $shouldReceiveData['receiveMoney'];
  577. break;
  578. case bcsub(abs($customerBalance),$shouldReceiveData['receiveMoney'],4) == 0;//说明预收款刚好完全核销
  579. $offsetMoney = $shouldReceiveData['receiveMoney'];
  580. break;
  581. case bcsub(abs($customerBalance),$shouldReceiveData['receiveMoney'],4) < 0;//说明预收款不够核销应收单金额
  582. $offsetMoney = abs($customerBalance);
  583. $notOffsetMoney = bcadd($customerBalance,$shouldReceiveData['receiveMoney'],4);
  584. $offsetStatus = StatusCode::$partion;
  585. }
  586. //更新应付单核销状态
  587. $updateOffsetStatus = $this->objDReceive->update(['offsetMoney'=>$offsetMoney,'notOffsetMoney'=>$notOffsetMoney,'offsetStatus'=>$offsetStatus],['id'=>$receiveId]);
  588. if ($updateOffsetStatus === false) {
  589. $this->objDReceive->rollBack();
  590. return ResultWrapper::fail($this->objDReceive->error(), ErrorCode::$dberror);
  591. }
  592. //更新应付单索引表核销状态
  593. unset($dbResult);
  594. $dbResult = $this->objDReceiveReceiptIndex->update(['offsetStatus' => $offsetStatus], ['id' => $receiveId,'createTime'=>$createTime]);
  595. if ($dbResult === false) {
  596. $this->objDReceive->rollBack();
  597. return ResultWrapper::fail($this->objDReceiveReceiptIndex->error(), ErrorCode::$dberror);
  598. }
  599. unset($dbResult);
  600. // 查询收款单,根据收款单找能核销的
  601. // $dbResult = $this->objDReceived->select(['offsetStatus'!=StatusCode::$standard],'*','createTime asc');
  602. $dbResult = $this->objDReceived->query('select * from '.$this->objDReceived->get_Table().' where customerId = '.$shouldReceiveData['customerId'].' and offsetStatus !='.StatusCode::$standard.' order by createTime asc');
  603. if ($dbResult === false) {
  604. return ResultWrapper::fail($this->objDReceived->error(), ErrorCode::$dberror);
  605. }
  606. $receiveOffsetMoney = $shouldReceiveData['receiveMoney'];
  607. foreach ($dbResult as $key => $value){
  608. if($receiveOffsetMoney>0){
  609. switch (true){
  610. case bcsub($value['notOffsetMoney'],$shouldReceiveData['receiveMoney'],2)>0: // 说明收款单能完全核销应收
  611. $receivedOffset = [
  612. 'offsetMoney' => bcadd($receiveOffsetMoney,$value['offsetMoney'],2),
  613. 'notOffsetMoney' => bcsub($value['notOffsetMoney'],$receiveOffsetMoney,2),
  614. 'offsetStatus' => StatusCode::$partion,
  615. ];
  616. $receiveOffsetMoney = abs(bcsub($receiveOffsetMoney,$receivedOffset['offsetMoney'],2));
  617. break;
  618. case bcsub($value['notOffsetMoney'],$shouldReceiveData['receiveMoney'],2) == 0: // 说明收款单能完全核销应收
  619. $receivedOffset = [
  620. 'offsetMoney' => $value['totalFinalMoney'],
  621. 'notOffsetMoney' => 0,
  622. 'offsetStatus' => StatusCode::$standard,
  623. ];
  624. $receiveOffsetMoney = abs(bcsub($value['totalFinalMoney'],$receivedOffset['offsetMoney'],2));
  625. break;
  626. case bcsub($value['notOffsetMoney'],$shouldReceiveData['receiveMoney'],2) < 0: // 说明收款单不能完全核销应收
  627. $receivedOffset = [
  628. 'offsetMoney' => $value['totalFinalMoney'],
  629. 'notOffsetMoney' => 0,
  630. 'offsetStatus' => StatusCode::$standard,
  631. ];
  632. $receiveOffsetMoney = abs(bcsub($value['totalFinalMoney'],$receivedOffset['offsetMoney'],2));
  633. }
  634. // 更新核销
  635. $updateReceivedOffset = $this->objDReceived->update($receivedOffset,['id'=>$value['id']]);
  636. if ($updateReceivedOffset === false) {
  637. $this->objDReceive->rollBack();
  638. return ResultWrapper::fail($this->objDReceived->error(), ErrorCode::$dberror);
  639. }
  640. //记录核销明细
  641. $updateOffset = [
  642. 'receiveReceiptId' => $receiveId,
  643. 'receivedId' => $value['id'],
  644. 'offsetMoney' => $offsetMoney,
  645. 'receiveCreateTime' => $shouldReceiveData['createTime'],
  646. 'type' => StatusCode::$delete
  647. ];
  648. $result = $this->objDReceiveOffset->insert($updateOffset);
  649. if ($result === false) {
  650. $this->objDReceived->rollBack();
  651. return ResultWrapper::fail($this->objDReceiveOffset->error(), ErrorCode::$dberror);
  652. }
  653. }
  654. }
  655. return ResultWrapper::success($dbResult);
  656. }
  657. }
  658. return ResultWrapper::success([]);
  659. }
  660. /**
  661. * 导出方法
  662. * @param $exportData
  663. */
  664. private static function export($exportData)
  665. {
  666. //导出到本地
  667. header("Content-type:application/vnd.ms-excel");
  668. header("Content-Disposition:filename=应收单列表.csv");
  669. header('Cache-Control: max-age=0');
  670. $fp = fopen('php://output', 'a');
  671. $head = ['ID', '应收单编号', '客户名称', '源订单号', '创建时间', '应收类型', '优惠金额', '实际应收金额', '商铺', '状态']; //定义标题
  672. foreach ($head as $i => $v) {
  673. $head[$i] = mb_convert_encoding($v, 'GBK', 'utf-8'); //将中文标题转换编码,否则乱码
  674. }
  675. fputcsv($fp, $head);
  676. $limit = 10000;
  677. $num = 0;//计数器
  678. foreach ($exportData as $v) {
  679. //循环数据
  680. $num++;
  681. if ($num == $limit) {
  682. ob_flush();//释放内存
  683. flush();
  684. }
  685. $rows['id'] = $v['id'];
  686. $rows['no'] = $v['no'];
  687. $rows['customerName'] = $v['customerName'];
  688. $rows['sourceNo'] = $v['sourceNo'];
  689. $rows['createTime'] = date('Y-m-d H:i:s', $v['createTime']);
  690. $rows['financeType'] = $v['financeType'];
  691. $rows['discountMoney'] = $v['discountMoney'];
  692. $rows['receiveMoney'] = $v['receiveMoney'];
  693. $rows['shopName'] = $v['shopName'];
  694. $rows['auditStatus'] = StatusCode::$auditStatus[$v['auditStatus']];
  695. foreach ($rows as $kk => $vv) {
  696. $rs[$kk] = mb_convert_encoding($vv, 'GBK', 'utf-8'); //转译编码
  697. }
  698. fputcsv($fp, $rs);
  699. $rows = [];
  700. }
  701. exit;
  702. }
  703. /**
  704. * @param $data
  705. * @return mixed
  706. */
  707. public function format($data)
  708. {
  709. foreach ($data as $k => $v) {
  710. $data[$k]['customerCode'] = createCode(StatusCode::$code['customer']['prefix'], $v['customerId'], StatusCode::$code['customer']['length']);
  711. $data[$k]['no'] = StatusCode::$noPrefix[16] . '-' . $v['no'];
  712. switch ($v['financeType']){
  713. case '销售退货单':
  714. $data[$k]['originNo'] = StatusCode::$noPrefix[6].'-'.$v['originNo'];
  715. break;
  716. case '销售单':
  717. $data[$k]['originNo'] = StatusCode::$noPrefix[1].'-'.$v['originNo'];
  718. break;
  719. }
  720. }
  721. return $data;
  722. }
  723. //搜索的where条件拼接
  724. public function setWhere($selectParams)
  725. {
  726. $defaultDSL = [
  727. 'from' => $selectParams['offset'],
  728. 'size' => $selectParams['limit'],
  729. 'sort' => [
  730. 'createTime' => [
  731. 'order' => 'desc'
  732. ],
  733. ],
  734. ];
  735. $dsl = [];
  736. $dsl['query']['bool']['must'][] = [
  737. 'term' => ['enterpriseId' => $this->enterpriseId],
  738. ];
  739. if (isset($selectParams['keyword'])) {
  740. if (!empty($selectParams['keyword'])) {
  741. $dsl['query']['bool']['must'][] = [
  742. 'multi_match' => [
  743. 'fields' => ['no', 'sourceNo', 'customerName'],
  744. 'query' => $selectParams['keyword'],
  745. 'fuzziness' => 'AUTO',
  746. ]
  747. ];
  748. }
  749. }
  750. if (!empty($selectParams['shopId'])) {
  751. $dsl['query']['bool']['must'][] = [
  752. 'term' => ['shopId' => $selectParams['shopId']],
  753. ];
  754. }
  755. if (!empty($selectParams['start']) && !empty($selectParams['end'])) {
  756. $dsl['query']['bool']['must'][] = [
  757. 'range' => [
  758. 'createTime' => [
  759. 'gte' => $selectParams['start'],
  760. 'lte' => strtotime(date('Y-m-d',$selectParams['end']).'23:59:59'),
  761. ]
  762. ]
  763. ];
  764. } else {
  765. if (!empty($selectParams['start'])) {
  766. $dsl['query']['bool']['must'][] = [
  767. 'range' => [
  768. 'createTime' => [
  769. 'gte' => $selectParams['start'],
  770. ]
  771. ]
  772. ];
  773. }
  774. if (!empty($selectParams['end'])) {
  775. $dsl['query']['bool']['must'][] = [
  776. 'range' => [
  777. 'createTime' => [
  778. 'lte' => strtotime(date('Y-m-d',$selectParams['end']).'23:59:59'),
  779. ]
  780. ]
  781. ];
  782. }
  783. }
  784. if (isset($selectParams['receiptTypeId'])) {
  785. if (!empty($selectParams['receiptTypeId'])) {
  786. $dsl['query']['bool']['filter'][] =
  787. ['term' => ['receiptTypeId' => $selectParams['receiptTypeId']]];
  788. }
  789. }
  790. if (isset($selectParams['auditStatus'])) {
  791. if (!empty($selectParams['auditStatus'])) {
  792. $dsl['query']['bool']['filter'][] =
  793. ['term' => ['auditStatus' => $selectParams['auditStatus']]];
  794. }
  795. }
  796. $dsl = array_merge($defaultDSL, $dsl);
  797. return $dsl;
  798. }
  799. public function search($selectParams)
  800. {
  801. $is_export = $selectParams['isExport'];
  802. unset($selectParams['isExport']);
  803. if($is_export){
  804. unset($selectParams['limit']);
  805. unset($selectParams['offset']);
  806. }
  807. $dsl = $this->setWhere($selectParams);
  808. //导出
  809. if ($is_export) self::exportSearch($dsl);
  810. $result = $this->objDReceive->getSearchQueryDsl($dsl);
  811. if (isset($result['status']) && $result['status'] == 400) {
  812. if ($result['error']['reason'] == 'all shards failed') {
  813. return ResultWrapper::success([
  814. 'data' => [],
  815. 'total' => 0
  816. ]);
  817. }
  818. return ResultWrapper::fail('获取应收数据失败' . $result['error']['reason'], ErrorCode::$apiNotResult);
  819. }
  820. if (!isset($result['hits']) || $result['hits']['total'] == 0) {
  821. return ResultWrapper::success([
  822. 'data' => [],
  823. 'total' => 0
  824. ]);
  825. }
  826. $total = $result['hits']['total'];
  827. $dbResult = $result['hits']['hits'];
  828. $list = [];
  829. foreach ($dbResult as $key => &$value) {
  830. $data = [];
  831. $data = $value['_source'];
  832. $list[] = $data;
  833. }
  834. $return = [
  835. 'data' => self::format($list),
  836. 'total' => ($total) ? intval($total) : 0,
  837. ];
  838. return ResultWrapper::success($return);
  839. }
  840. /**
  841. * 检索导出(ES)
  842. *
  843. * @param $dsl
  844. * @return ResultWrapper
  845. * @throws \Exception
  846. */
  847. private function exportSearch($dsl)
  848. {
  849. $result = $this->objDReceive->getScrollSearchQueryDsl($dsl);
  850. if (isset($result['status']) && $result['status'] == 400) {
  851. return ResultWrapper::fail('获取数据失败' . $result['error']['reason'], ErrorCode::$apiNotResult);
  852. }
  853. if (!isset($result['hits']) && $result['hits']['total'] == 0) {
  854. return ResultWrapper::fail('导出数据为空' . $result['error']['reason'], ErrorCode::$apiNotResult);
  855. }
  856. $dbResult = $result['hits']['hits'];
  857. $list = [];
  858. foreach ($dbResult as $key => &$value) {
  859. $list[] = $value['_source'];
  860. }
  861. self::export($list);
  862. }
  863. }