InvoiceItem.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <?php
  2. namespace app\cxinv\controller;
  3. use app\cxinv\model\InvoiceGood;
  4. use app\cxinv\model\InvoiceOrder;
  5. use app\cxinv\model\OrderCategory;
  6. use app\cxinv\model\PayInfo;
  7. use app\cxinv\model\PayInvoice;use think\App;
  8. use think\facade\Validate;
  9. class InvoiceItem extends Base{
  10. public function __construct(App $app) {
  11. parent::__construct($app);
  12. $this->model = new \app\cxinv\model\InvoiceItem();
  13. }
  14. //查询
  15. public function cgdListByPayNo(){
  16. $param = $this->request->param(["payNo"=>[],"merge_code"=>"","inv_good_name"=>"",'good_name'=>''],"post","trim");
  17. $where=[["a.status","=",1],["a.is_del","=",0]];
  18. if($param["payNo"]!=="") $where[]=["a.payNo","in",$param["payNo"]];
  19. if($param["merge_code"]!=="") $where[]=["c.merge_code","like","%{$param['merge_code']}%"];
  20. if($param["inv_good_name"]!=="") $where[]=["c.inv_good_name","like","%{$param["inv_good_name"]}%"];
  21. if($param["good_name"]!=="") $where[]=["b.goodName","like","%{$param["good_name"]}%"];
  22. $list = PayInfo::alias('a')
  23. ->join('cgd_info b','a.cgdNo=b.sequenceNo',"left")
  24. ->join('order_category c','b.sequenceNo=c.code and b.goodNo=c.spuCode and c.order_type=2',"left")
  25. ->where($where)
  26. ->field("b.sequenceNo,b.goodNo,b.goodName,(b.goodNum-thNum) as goodNum,b.goodPrice,b.totalPrice,
  27. b.ainv_fee,b.winv_fee,b.apay_fee,b.wpay_fee,c.merge_code,c.cat_code,c.cat_name,c.short_name,c.tax,c.inv_good_name")
  28. ->select();
  29. return success('获取成功',$list);
  30. }
  31. //查询
  32. public function qrdListByInvNo(){
  33. $param = $this->request->param(["invNo"=>"","merge_code"=>"","inv_good_name"=>""],"post","trim");
  34. $where=[["a.goodNum",">",0],["a.is_del","=",0]];
  35. if($param["invNo"]!=="") $where[]=["a.invNo","=",$param["invNo"]];
  36. if($param["merge_code"]!=="") $where[]=["c.merge_code","=",$param["merge_code"]];
  37. if($param["inv_good_name"]!=="") $where[]=["c.inv_good_name","like","%{$param["inv_good_name"]}%"];
  38. $list= InvoiceGood::alias('a')
  39. ->join('qrd_info b','a.orderCode=b.sequenceNo','left')
  40. ->join('order_category c','b.sequenceNo=c.code and b.goodNo=c.spuCode and c.order_type=1','left')
  41. ->where($where)
  42. ->field("b.sequenceNo,b.goodNo,b.goodName,a.goodNum,a.goodPrice,a.totalPrice,
  43. c.merge_code,c.cat_code,c.cat_name,c.short_name,c.tax,c.inv_good_name")
  44. ->select();
  45. return success('获取成功',$list);
  46. }
  47. //添加发票明细对应关系
  48. public function create(){
  49. $param = $this->request->param(["itemId"=>"","orderArr"=>[]],"post","trim");
  50. $valid=Validate::rule([
  51. 'itemId|发票明细id' => 'require|number|gt:0',
  52. 'orderArr|订单信息' => 'require|array',
  53. ]);
  54. if(!$valid->check($param)) return error($valid->getError());
  55. $valids=Validate::rule([
  56. 'code|订单号' => 'require|max:255',
  57. 'spuCode|商品编码' => 'require|max:255',
  58. 'good_name|商品名称' => 'require|max:255',
  59. 'num|数量' => 'require|float|gt:0',
  60. 'good_price|商品价格' => 'require|float|gt:0',
  61. 'total_amount|总金额' => 'require|float|gt:0',
  62. 'remark|备注' => 'max:255',
  63. ]);
  64. $item = $this->model->where(['id'=>$param["itemId"]])->findOrEmpty();
  65. if($item->isEmpty()) return error("发票明细不存在");
  66. $save=[];
  67. $amount = $item['balance_amount'];
  68. foreach ($param["orderArr"] as $k=>$v){
  69. if(!$valids->check($v)) return error($valids->getError());
  70. $taxInfo = OrderCategory::where(['code'=>$v['code'],'spuCode'=>$v['spuCode']])->findOrEmpty();
  71. if($taxInfo->isEmpty()) return error("商品编码{$v['spuCode']}税目信息不存在");
  72. $balance="0";
  73. if($amount<$v['total_amount']){
  74. $balance = bcsub($v['total_amount'],$amount,2);
  75. $amount="0";
  76. }else{
  77. $balance = "0";
  78. $amount = bcsub($amount,$v['total_amount'],2);
  79. }
  80. $diff=[];
  81. $tax_diff=1;
  82. $cat_diff=1;
  83. if(str_replace("%","",$item['tax'])!=$taxInfo['tax']){
  84. $diff["tax"] = [
  85. "inv_tax"=>str_replace('%','',$item['tax']),
  86. "order_tax"=>$taxInfo['tax'],
  87. ];
  88. $tax_diff=2;
  89. }
  90. if($item['cat_code']!=$taxInfo['merge_code']){
  91. $diff["cat_code"] = [
  92. "inv_cat_code"=>$item['cat_code'],
  93. "order_cat_code"=>$taxInfo['merge_code'],
  94. ];
  95. $cat_diff=2;
  96. }
  97. $save[]=[
  98. "itemId"=>$param["itemId"],
  99. "code"=>$v["code"],
  100. "spuCode"=>$v["spuCode"],
  101. "good_name"=>$v['good_name'],
  102. "num"=>$v["num"],
  103. "good_price"=>$v["good_price"],
  104. "total_amount"=>$v["total_amount"],
  105. "tax_diff"=> $tax_diff,
  106. "cat_diff"=>$cat_diff,
  107. "balance_amount"=>$balance,
  108. "diff_info"=>$diff,
  109. "status"=>$balance>0?2:1,
  110. "remark"=>$v["remark"],
  111. "apply_id"=>$this->uid,
  112. "apply_name"=>$this->uname
  113. ];
  114. }
  115. $item->startTrans();
  116. try{
  117. $res=(new InvoiceOrder)->saveAll($save);
  118. if($res){
  119. $item->balance_amount = $amount;
  120. $item->status = $amount>0?2:1; //已关联数据 $amont=0 2 还有余额则为1
  121. $item->save();
  122. }else throw new \Exception("添加失败");
  123. $item->commit();
  124. }catch (\Exception $e){
  125. $item->rollback();
  126. return error($e->getMessage());
  127. }
  128. return success('添加成功');
  129. }
  130. //删除发票明细对应关系
  131. public function delete(){
  132. $param = $this->request->param(["id"=>""],"post","trim");
  133. $valid=Validate::rule([
  134. 'id|发票明细对应id' => 'require|number|gt:0',
  135. ]);
  136. if(!$valid->check($param)) return error($valid->getError());
  137. $info = InvoiceOrder::where(['id'=>$param["id"]])->findOrEmpty();
  138. if($info->isEmpty()) return error("发票明细对应关系不存在");
  139. $item = $this->model->where(['id'=>$info['itemId']])->findOrEmpty();
  140. if($item->isEmpty()) return error("发票明细不存在");
  141. InvoiceOrder::startTrans();
  142. try{
  143. $res = $info->delete();
  144. if($res){
  145. $count = InvoiceOrder::where(['itemId'=>$info['itemId']])->count();
  146. $item->balance_amount = bcadd($item['balance_amount'],bcsub($info['total_amount'],$info['balance_amount'],2),2);
  147. $item->status = ($count==0) ? 0 : ($item->balance_amount==$item->total_amount?0:($item->balance_amount>0?2:1));
  148. $item->save();
  149. }else throw new \Exception("删除失败");
  150. InvoiceOrder::commit();
  151. }catch (\Exception $e){
  152. InvoiceOrder::rollback();
  153. return error($e->getMessage());
  154. }
  155. return success('删除成功');
  156. }
  157. public function addRemark(){
  158. $param = $this->request->param(['id'=>''],'post','trim');
  159. $valid=Validate::rule([
  160. 'id|发票明细对应id' => 'require|number|gt:0',
  161. 'remark|备注' => 'require|max:255',
  162. ]);
  163. if(!$valid->check($param)) return error($valid->getError());
  164. $info = InvoiceOrder::where(['id'=>$param['id']])->findOrEmpty();
  165. if($info->isEmpty()) return error('发票明细对应关系不存在');
  166. $item = $this->model->where(['id'=>$info['itemId']])->findOrEmpty();
  167. if($item->isEmpty()) return error('发票明细不存在');
  168. $info->startTrans();
  169. try{
  170. $info->remark = $param['remark'] ?? '';
  171. $res = $info->save();
  172. if($res==false)throw new \Exception('备注添加失败');
  173. $info->commit();
  174. }catch (\Exception $e){
  175. $info->rollback();
  176. return error($e->getMessage());
  177. }
  178. return success('备注添加成功');
  179. }
  180. /**
  181. * 发票明细正负数合并保留整数
  182. * @param $main_id 正数id
  183. * $voice_id 负数id
  184. */
  185. public function mergeItem(){
  186. $data=$this->request->post("data",[]);
  187. if(empty($data)) return error('参数错误');
  188. $valid=Validate::rule([
  189. 'main_id|正数id' => 'require|number|gt:0',
  190. 'voice_id|负数id' => 'require|number|gt:0',
  191. ]);
  192. $mainArr = $this->model->where(['id'=>array_column($data,"main_id")])->column("id,amount,invoiceCode,total_amount,balance_amount","id");
  193. $voiceArr = $this->model->where(['id'=>array_column($data,"voice_id")])->column("id,invoiceCode,amount,total_amount,balance_amount","id");
  194. $inoviceCode = array_unique(array_merge(array_column($voiceArr,"invoiceCode"),array_column($mainArr,'invoiceCode')));
  195. if(count($inoviceCode)>1) return error("正负数发票明细回票申请编号不一致");
  196. $temop=[];
  197. $remove=[];
  198. foreach ($data as $k=>$v){
  199. if(!$valid->check($v)) return error($valid->getError());
  200. if(!isset($mainArr[$v['main_id']])) return error("正数发票明细不存在");
  201. if(!isset($voiceArr[$v['voice_id']])) return error("负数发票明细不存在");
  202. if($mainArr[$v['main_id']]['amount']<0) return error("正数发票明细金额必须大于0");
  203. if($voiceArr[$v['voice_id']]['amount']>=0) return error("负数发票明细金额必须小于0");
  204. if($mainArr[$v['main_id']]['invoiceCode']!=$voiceArr[$v['voice_id']]['invoiceCode']) return error("正负数发票明细回票申请编号不一致");
  205. if(abs($voiceArr[$v['voice_id']]['amount'])> $mainArr[$v['main_id']]['amount']) return error("负数发票明细金额不能大于正数发票明细金额");
  206. $temop[]=[
  207. "id"=>$v['main_id'],
  208. "amount"=>bcadd($mainArr[$v['main_id']]['amount'],$voiceArr[$v['voice_id']]['amount'],2),
  209. "balance_amount"=>bcadd($mainArr[$v['main_id']]['balance_amount'],$voiceArr[$v['voice_id']]['balance_amount'],2),
  210. "total_amount"=> bcadd($mainArr[$v['main_id']]['total_amount'],$voiceArr[$v['voice_id']]['total_amount'],2),
  211. "status"=>bcadd($mainArr[$v['main_id']]['total_amount'],$voiceArr[$v['voice_id']]['total_amount'],2)==0?1:0
  212. ];
  213. $remove[]=$v['voice_id'];
  214. }
  215. $pinv= PayInvoice::where('hpNo',$inoviceCode[0])->findOrEmpty();
  216. if($pinv->isEmpty()) return error('未找到关联的回票申请');
  217. if($pinv['status']!=14) return error('回票申请状态必须为待确认');
  218. $this->model->startTrans();
  219. try{
  220. $up=$this->model->saveAll($temop);
  221. if($up==false) throw new \Exception("更新失败");
  222. $delte=$this->model->whereIn('id',$remove)->select()->delete();
  223. if($delte==false) throw new \Exception("删除失败");
  224. $ist = $this->model->where([['invoiceCode',"=",$inoviceCode[0]],["amount","<",0]])->count();
  225. if($ist==0){
  226. $pinv->status=11;
  227. $save=$pinv->save();
  228. if($save==false) throw new \Exception("回票申请状态修改失败");
  229. }
  230. $this->model->commit();
  231. }catch (\Exception $e){
  232. $this->model->rollback();
  233. return error($e->getMessage());
  234. }
  235. return success('合并成功');
  236. }
  237. /**
  238. * 删除无效发票明细
  239. */
  240. public function removeItem(){
  241. $param=$this->request->param(["id"=>""],"post","trim");
  242. $valid=Validate::rule([
  243. 'id|发票明细id' => 'require|number|gt:0',
  244. ]);
  245. if(!$valid->check($param)) return error($valid->getError());
  246. $info = $this->model->where(['id'=>$param['id']])->findOrEmpty();
  247. if($info->isEmpty()) return error("发票明细不存在");
  248. $pinv= PayInvoice::where("hpNo",$info['invoiceCode'])->findOrEmpty();
  249. if($pinv->isEmpty()) return error("未找到关联的回票申请");
  250. if($pinv['status']!=14) return error("回票申请状态必须为待确认");
  251. $this->model->startTrans();
  252. try{
  253. $info->delete();
  254. $this->model->commit();
  255. }catch (\Exception $e){
  256. $this->model->rollback();
  257. return error($e->getMessage());
  258. }
  259. }
  260. public function getListByCode(){
  261. $param=$this->request->param(["code"=>"","status"=>"","size"=>100]);
  262. $where=[];
  263. if($param["code"]!=="") $where[]=["invoiceCode","=",$param["code"]];
  264. if($param["status"]!=="") $where[]=["status","=",$param["status"]];
  265. $list= $this->model->with(["OrderInfo"])
  266. ->where($where)
  267. ->limit($param["size"])
  268. ->select();
  269. return success('获取成功',$list);
  270. }
  271. public function importOrder(){
  272. $param=$this->request->param([ "order_type"=>"","list"=>[]],"post","trim");
  273. $valid = Validate::rule([
  274. 'order_type|订单类型' => 'require|in:1,2',
  275. 'list|发票明细' => 'require|array',
  276. ]);
  277. if(!$valid->check($param)) return error($valid->getError());
  278. $listValid = Validate::rule([
  279. "itemId|发票明细ID"=>'require|number|gt:0',
  280. 'code|订单编码' => 'require|max:20',
  281. 'num|数量' => 'float|egt:0',
  282. 'good_price|商品价格' => 'float|egt:0',
  283. 'total_amount|总金额' => 'require|float|gt:0',
  284. 'remark|备注' =>'max:255',
  285. ]);
  286. $itemArr= $this->model->whereIn('id',array_column($param['list'],"itemId"))->column("id,invoiceCode,order_type,balance_amount,cat_code,tax","id");
  287. $cgdInfo = PayInfo::alias('a')
  288. ->join('cgd_info b','a.cgdNo=b.sequenceNo','left')
  289. ->join('order_category c','b.sequenceNo=c.code and b.goodNo=c.spuCode and c.order_type=2','left')
  290. ->where([['a.status','=',1],['a.is_del','=',0],['a.cgdNo','in',array_column($param['list'],'code')]])
  291. ->column('b.sequenceNo,b.goodNo,b.goodName,(b.goodNum-thNum) as goodNum,b.goodPrice,b.totalPrice,b.ainv_fee,b.winv_fee,b.apay_fee,b.wpay_fee,
  292. c.merge_code,c.cat_code,c.cat_name,c.short_name,c.tax,c.inv_good_name',"b.sequenceNo");
  293. $orderItem=[];
  294. foreach($param["list"] as $v){
  295. if(!$listValid->check($v)) return error($listValid->getError());
  296. if(!isset($itemArr[$v['itemId']])) return error("发票明细不存在");
  297. if(!isset($cgdInfo[$v['code']]))return error("订单{$v['code']}信息不存在或未对账");
  298. if($cgdInfo[$v['code']]['winv_fee']<$v['total_amount']) return error("{$v["code"]}订单金额不足");
  299. if($itemArr[$v['itemId']]['balance_amount']<=0) return error("发票明细ID {$v["itemId"]} 可关联金额不足");
  300. if($cgdInfo[$v['code']]['merge_code']=="") return error("{$v["code"]}订单税目信息不存在");
  301. if($itemArr[$v['itemId']]['balance_amount']<$v['total_amount']){
  302. $balance = bcsub($v['total_amount'],$itemArr[$v['itemId']]['balance_amount'],2);
  303. $itemArr[$v['itemId']]['balance_amount']='0';
  304. }else{
  305. $balance = '0';
  306. $itemArr[$v['itemId']]['balance_amount'] = bcsub($itemArr[$v['itemId']]['balance_amount'],$v['total_amount'],2);
  307. }
  308. $cgdInfo[$v['code']]['winv_fee'] =bcsub( $cgdInfo[$v['code']]['winv_fee'],bcsub($v['total_amount'],$balance,2),2);
  309. $tax = $cgdInfo[$v['code']]['tax'];
  310. $merge_code = $cgdInfo[$v['code']]['merge_code'];
  311. $diff=[];
  312. $tax_diff=1;
  313. $cat_diff=1;
  314. if(str_replace('%','',$itemArr[$v['itemId']]['tax'])!=$tax ){
  315. $diff['tax'] = [
  316. 'inv_tax'=>str_replace('%','',$itemArr[$v['itemId']]['tax']),
  317. 'order_tax'=>$tax ,
  318. ];
  319. $tax_diff=2;
  320. }
  321. if($itemArr[$v['itemId']]['cat_code']!=$merge_code){
  322. $diff['cat_code'] = [
  323. 'inv_cat_code'=>$itemArr[$v['itemId']]['cat_code'],
  324. 'order_cat_code'=>$merge_code,
  325. ];
  326. $cat_diff=2;
  327. }
  328. $itemArr[$v['itemId']]['status'] = ($itemArr[$v['itemId']]['balance_amount']>0?2:1);
  329. $orderItem[]=[
  330. 'itemId'=>$v['itemId'],
  331. 'code'=>$v['code'],
  332. 'spuCode'=>$cgdInfo[$v['code']]['goodNo'],
  333. 'good_name'=>$cgdInfo[$v['code']]['goodName'],
  334. 'num'=>$v['num']??0,
  335. 'good_price'=>$v['good_price']??0,
  336. 'total_amount'=>$v['total_amount'],
  337. 'tax_diff'=> $tax_diff,
  338. 'cat_diff'=>$cat_diff,
  339. 'balance_amount'=>$balance,
  340. 'diff_info'=>$diff,
  341. 'status'=>$balance>0?2:1,
  342. 'remark'=>$v['remark'],
  343. 'apply_id'=>$this->uid,
  344. 'apply_name'=>$this->uname
  345. ];
  346. }
  347. $orderItemModel = new \app\cxinv\model\InvoiceItem();
  348. $orderItemModel->startTrans();
  349. try{
  350. $num=$orderItemModel->saveAll(array_values($itemArr));
  351. if(count($num)>0){
  352. (new InvoiceOrder())->saveAll($orderItem);
  353. }else throw new \Exception("导入失败");
  354. }catch (\Exception $e){
  355. $orderItemModel->rollback();
  356. return error($e->getMessage());
  357. }
  358. $orderItemModel->commit();
  359. return success("导入成功");
  360. }
  361. }