FinancialManager.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. <?php
  2. namespace app\cxinv\controller;
  3. use app\cxinv\model\FinancialCheck;
  4. use app\cxinv\model\ManagerProduct;
  5. use app\cxinv\model\ProductFz;
  6. use think\App;
  7. class FinancialManager extends Base{
  8. public function __construct(App $app) {
  9. parent::__construct($app);
  10. $this->model=new \app\cxinv\model\FinancialManager();
  11. }
  12. public function List(){
  13. $param = $this->request->param(["code"=>"","type"=>[],"seller_code"=>"","buyer_code"=>"","orderCode"=>"","cxCode"=>"",
  14. "goodNo"=>"","inv_number"=>"","inv_buyer_code"=>"",'inv_seller_code'=>"",'channel'=>[],'status'=>"","start"=>"","end"=>"",
  15. "page"=>1,"size"=>15],"post","trim");
  16. $where=[];
  17. if($param['code']!="") $where[]= ["code","=","%{$param['code']}%"];
  18. if(!empty($param['type'])) $where[]= ["type","in",$param['type']];
  19. if(!empty($param['channel'])) $where[]= ["channel","in",$param['channel']];
  20. if($param['status']!="") $where[]= ["status","in",$param['status']];
  21. if($param['start']!="") $where[]= ["create_time",">=",startTime($param['start'])];
  22. if($param['end']!="") $where[]= ["create_time","<=",endTime($param['end'])];
  23. if($param['seller_code']!="") $where[]= ["seller_code","=",$param['seller_code']];
  24. if($param['buyer_code']!="") $where[]= ["buyer_code","=",$param['buyer_code']];
  25. if($param['orderCode']!="") $where[]= ["orderCode","like", "%{$param['orderCode']}%"];
  26. if($param['cxCode']!="") $where[]= ["cxCode","like","%{$param['cxCode']}%"];
  27. if($param['goodNo']!="") $where[]= ["goodNo","like","%{$param['goodNo']}%"];
  28. if($param['inv_number']!="") $where[]= ["inv_number","like","%{$param['inv_number']}%"];
  29. if($param['inv_buyer_code']!="") $where[]= ["inv_buyer_code","=",$param['inv_buyer_code']];
  30. if($param['inv_seller_code']!="") $where[]= ["inv_seller_code","=",$param['inv_seller_code']];
  31. $list = $this->model->with(['ProductRela'=>["product"]])
  32. ->where($where)
  33. ->order("id desc")
  34. ->paginate(['page'=>$param['page'],'list_rows'=>$param['size']]);
  35. return success('获取成功',['list'=>$list->items(),'count'=>$list->total()]);
  36. }
  37. // 'code'=>'string',//订单或记录的唯一标识符
  38. // 'type'=>'int',//记录类型 1入库 2出库 3入库红冲 4出库红冲
  39. // 'source'=>'int',//数据来源,1结算 2 线下订单
  40. // channel=>'int',//渠道,1订单 2 线下订单 3 toC订单
  41. // 'seller_code'=>'string',//卖方代码
  42. // 'seller_name'=>'string',//卖方名称
  43. // 'buyer_code'=>'string',//买方代码
  44. // 'buyer_name'=>'string',//买方名称
  45. // 'orderCode'=>'string',//订单编号
  46. // 'cxCode'=>'string',//客户编号
  47. // 'poCode'=>'string',//采购订单编号
  48. // 'platform_type'=>'int',//平台类型,1ToB 2ToC
  49. // 'goodNo'=>'string',//商品编号
  50. // 'goodName'=>'string',//商品名称
  51. // 'unit'=>'string',//商品单位
  52. // 'num'=>'int',//商品数量
  53. // 'goodPrice'=>'decimal',//商品单价
  54. // 'totalPrice'=>'decimal',//商品总价
  55. // 'cat_code'=>'string',//商品分类代码
  56. // 'cat_name'=>'string',//商品分类名称
  57. // 'tax'=>'decimal',//税率或税费
  58. // 'inv_fee'=>'decimal',//发票费用
  59. // 'inv_seller_code'=>'string',//发票卖方代码
  60. // 'inv_seller_name'=>'string',//发票卖方名称
  61. // 'inv_buyer_code'=>'string',//发票买方代码
  62. // 'inv_buyer_name'=>'string',//发票买方名称
  63. // 'inv_number'=>'string',//发票编号
  64. // 'inv_type'=>'string',//发票类型
  65. // 'inv_item_id'=>'int',//发票项目ID
  66. // 'inv_good_name'=>'string',//发票商品名称
  67. // 'inv_cat_code'=>'string',//发票商品分类代码
  68. // 'inv_spec'=>'string',//发票商品规格
  69. // 'inv_unit'=>'string',//发票商品单位
  70. // 'inv_num'=>'int',//发票商品数量
  71. // 'inv_subprice'=>'decimal',//发票商品子项单价
  72. // 'inv_subtotal'=>'decimal',//发票商品子项总价
  73. // 'inv_tax'=>'decimal',//发票税额
  74. // 'inv_tax_total'=>'decimal',//发票总税额
  75. // 'inv_price'=>'decimal',//发票单价
  76. // 'inv_total'=>'decimal',//发票总价
  77. // 'cat_diff'=>'int',//分类差异
  78. // 'tax_diff'=>'int',//税费差异
  79. // 'remark'=>'string',//备注或说明
  80. public function create(){
  81. $list=$this->request->post("list",[],"trim");
  82. if(empty($list)) return error("请传入数据");
  83. foreach ($list as $key=>&$item){
  84. $valid = $this->validate($item,[
  85. 'type|单据类型'=>'require|in:1,2,3,4',
  86. 'source|单据来源'=>'require|in:1,2',
  87. "channel|渠道"=>'require|in:1,2,3',
  88. 'invoiceCode|发票代码'=>'max:255',
  89. 'seller_code|卖方公司纳税识别号'=>'require|max:255',
  90. 'seller_name|卖方公司名称'=>'require|max:255',
  91. 'buyer_code|买方公司纳税识别号'=>'require|max:255',
  92. 'buyer_name|买方公司名称'=>'require|max:255',
  93. 'orderCode|订单号'=>'max:255',
  94. 'cxCode|主订单号'=>'max:255',
  95. 'poCode|Po订单号'=>'max:255',
  96. 'platform_type|平台类型'=>'require|in:1,2',
  97. 'goodType|商品类型'=>'require|in:1,2,3',
  98. 'goodNo|商品编号'=>'require|max:255',
  99. 'goodName|商品名称'=>'require|max:255',
  100. 'unit|商品单位'=>'require|max:255',
  101. 'num|商品数量'=>'require|integer',
  102. 'goodPrice|商品单价'=>'require|float',
  103. 'totalPrice|商品总价'=>'require|float',
  104. 'cat_code|商品分类代码'=>'require|max:255',
  105. 'cat_name|商品分类名称'=>'require|max:255',
  106. 'tax|税率或税费'=>'require|float',
  107. 'inv_fee|发票关联费用'=>'float',
  108. 'inv_seller_code|发票卖方代码'=>'max:255',
  109. 'inv_seller_name|发票卖方名称'=>'max:255',
  110. 'inv_buyer_code|发票买方代码'=>'max:255',
  111. 'inv_buyer_name|发票买方名称'=>'max:255',
  112. 'inv_number|发票编号'=>'max:255',
  113. 'inv_type|发票类型'=>'max:255',
  114. 'inv_open_date|发票开票日期'=>'max:255',
  115. 'inv_item_id|发票项目ID'=>'integer',
  116. 'inv_good_name|发票商品名称'=>'max:255',
  117. 'inv_cat_code|发票商品分类代码'=>'max:255',
  118. 'inv_spec|发票商品规格'=>'max:255',
  119. 'inv_unit|发票商品单位'=>'max:255',
  120. 'inv_num|发票商品数量'=>'float',
  121. 'inv_subprice|发票商品税后单价'=>'float',
  122. 'inv_subtotal|发票商品税后总价'=>'float',
  123. 'inv_tax|发票税额'=>'max:255',
  124. 'inv_tax_total|发票总税额'=>'float',
  125. 'inv_price|发票单价'=>'float',
  126. 'inv_total|发票总价'=>'float',
  127. 'cat_diff|分类差异'=>'max:255',
  128. 'tax_diff|税费差异'=>'max:255',
  129. 'remark|备注'=>'max:255',
  130. 'relaArr|关联数据'=>'array',
  131. 'fz_date|入账月份'=>'max:255'
  132. ]);
  133. if($valid!==true)return error($valid);
  134. if($item['channel']==1){
  135. $check = $this->model->CheckDatas($item);
  136. if(!empty($check)) return error($key+1 ."行数据校验不通过",1004,$check);
  137. }
  138. if($item['tax']!='' && $item['inv_tax']!=''){
  139. $item['inv_tax'] = str_replace("%","",$item['inv_tax']);
  140. $item['tax_diff'] = $item['tax']==$item['inv_tax']?1:2;
  141. }
  142. if($item['cat_code']!='' && $item['inv_cat_code']!=''){
  143. $item['cat_diff'] = $item['cat_code']==$item['inv_cat_code']?1:2;
  144. }
  145. $companyCode= in_array($item['type'],['2','4'])?$item['seller_code']:$item['buyer_code'];
  146. $fz_date = ProductFz::where(['company_code'=>$companyCode,'fz_date'=>$item['fz_date']])->findOrEmpty();
  147. if($fz_date->isEmpty()) return error($companyCode."--[{$item['fz_date']}]请生成封账单");
  148. if($fz_date->status!=0) return error($companyCode."--{$item['fz_date']}封账状态不可用");
  149. $item['apply_id']=$this->uid;
  150. $item['apply_name']=$this->uname;
  151. $item['code']= makeNo("PM", count($list)==1?"":str_pad(strval($key),4,0,STR_PAD_LEFT));
  152. }
  153. $this->model->startTrans();
  154. try{
  155. foreach ($list as $val){
  156. (new \app\cxinv\model\FinancialManager)->CreateData($val);
  157. }
  158. $this->model->commit();
  159. }catch (\Exception $e){
  160. $this->model->rollback();
  161. return error($e->getMessage());
  162. }
  163. return success("操作成功");
  164. }
  165. public function info(){
  166. $id=$this->request->param("id",0,"intval");
  167. $info=$this->model->with(['ProductRela'=>["product"],'FinancialTz'=>["ProductTz"]])->findOrEmpty($id);
  168. if($info->isEmpty()) return error("数据不存在");
  169. $ProductMap=[];
  170. if($info['status']==3){
  171. $map = $info->FinancialTz->ProductTz->toArray();
  172. foreach ($map as $k=>$v){
  173. if($v['type']==1) $ProductMap[] = $v['product_id'];
  174. }
  175. }
  176. foreach ($info['ProductRela'] as $key=>$val){
  177. if(in_array($val['product_id'],$ProductMap)){
  178. $info['ProductRela'][$key]['is_check']=1;
  179. }else{
  180. $info['ProductRela'][$key]['is_check']=0;
  181. }
  182. }
  183. return success("获取成功",$info);
  184. }
  185. //处理待确认数据
  186. public function CheckSure(){
  187. $params = $this->request->param(['manager_id'=>'','relaArr'=>[],"fz_date","is_checkOrder"=>0],'post','trim');
  188. $valid = $this->validate($params,[
  189. 'manager_id|出库明细ID'=>'require|integer',
  190. 'relaArr|关联数据'=>'require|array',
  191. 'fz_date|封账月份'=>'max:255',
  192. 'is_checkOrder|是否生成计提单子'=>'require|in:0,1'
  193. ]);
  194. if($valid!==true) return error($valid);
  195. $manager = $this->model->findOrEmpty($params['manager_id']);
  196. if($manager->isEmpty()) return error('待确认数据不存在');
  197. if($manager['status']!=1 && $manager['status']!=4) return error('当前待确认数据状态不允许操作');
  198. $manager->relaArr=$params['relaArr'];
  199. $manager->fz_date=$params['fz_date']??$manager->fz_date;
  200. $companyCode= in_array($manager['type'],['2','4'])?$manager['seller_code']:$manager['buyer_code'];
  201. $fz_date = ProductFz::where(['company_code'=>$companyCode,'fz_date'=>$manager['fz_date']])->findOrEmpty();
  202. if($fz_date->isEmpty()) return error("请先生成封账单");
  203. if($fz_date->status!=0) return error("{$manager['fz_date']}封账状态不可用");
  204. $this->model->startTrans();
  205. try{
  206. $manager->cl_uid=$this->uid; //调整单需要创建人
  207. $manager->cl_uname=$this->uname;//调整单需要创建人
  208. if($manager->type==1 || $manager->type==4)$check = $this->model->inProduct($manager);
  209. else {
  210. if($params['is_checkOrder']==1)$check = $this->model->OutKet($manager);
  211. else$check = $this->model->outProduct($manager);
  212. }
  213. if(empty($check)) return error('待确认数据处理失败');
  214. if($manager->balance_num!=0) return error('待确认数据数量未处理完不可提交');
  215. ManagerProduct::AddProduct($manager->id,$check);
  216. $manager->save();
  217. $this->model->commit();
  218. }catch (\Exception $e){
  219. $this->model->rollback();
  220. return error($e->getMessage());
  221. }
  222. return success('操作成功');
  223. }
  224. //待确认数据 c端订单确认处理
  225. public function CheckSureByOther(){
  226. $params = $this->request->param(['manager_id'=>[],'relaArr'=>[],"fz_date","is_checkOrder"=>0],'post','trim');
  227. $valid = $this->validate($params,[
  228. 'manager_id|出库明细ID'=>'require|array',
  229. 'relaArr|关联数据'=>'require|array',
  230. 'fz_date|封账月份'=>'max:255',
  231. 'is_checkOrder|是否生成计提单子'=>'require|in:0,1'
  232. ]);
  233. if($valid!==true) return error($valid);
  234. $manager = $this->model->whereIn('id',$params['manager_id'])->select();
  235. if($manager->isEmpty()) return error('待确认数据不存在');
  236. $goodNos = array_unique(array_column($manager->toArray(),'goodNo'));
  237. if(count($goodNos)!=1) return error('待确认数据商品编码不一致');
  238. if($params['is_checkOrder']==1){
  239. $totalnum = array_sum(array_column($manager->toArray(),'balance_num'));
  240. $relaNum = array_sum(array_column($params['relaArr'],'num'));
  241. if($totalnum!=$relaNum) return error('待确认数据数量不一致');
  242. }
  243. $this->model->startTrans();
  244. try{
  245. foreach ($manager as $item){
  246. $item->relaArr=[];
  247. $relaArr= array_map(function (&$val) use ($item){
  248. $temp=$val;
  249. $temp['id']=$val['id'];
  250. $temp['num']=$item->balance_num;
  251. $val['num']= bcsub($val['num'],$item->balance_num,8);
  252. return $temp;
  253. },$params['relaArr']);
  254. $item->relaArr= $relaArr;
  255. $item->fz_date=$params['fz_date']??$item->fz_date;
  256. $item->cl_uid=$this->uid;
  257. $item->cl_uname=$this->uname;
  258. $companyCode= in_array($item['type'],['2','4'])?$item['seller_code']:$item['buyer_code'];
  259. $fz_date = ProductFz::where(['company_code'=>$companyCode,'fz_date'=>$item['fz_date']])->findOrEmpty();
  260. if($fz_date->isEmpty()) throw new \Exception("请先生成封账单");
  261. if($fz_date->status!=0) throw new \Exception("{$manager['fz_date']}封账状态不可用");
  262. if($item->type==1 || $item->type==4)$check = $this->model->inProduct($item);
  263. else {
  264. if($params['is_checkOrder']==1)$check = $this->model->OutKet($item);
  265. else$check = $this->model->outProduct($item);
  266. }
  267. if(empty($check)) throw new \Exception('待确认数据处理失败');
  268. if($item->balance_num!=0) throw new \Exception('待确认数据数量未处理完不可提交');
  269. ManagerProduct::AddProduct($item->id,$check);
  270. $item->save();
  271. }
  272. $this->model->commit();
  273. }catch (\Exception $e){
  274. $this->model->rollback();
  275. return error($e->getMessage());
  276. }
  277. return success('操作成功');
  278. }
  279. // 删除待确认数据
  280. public function delete(){
  281. $ids = $this->request->param('id',[]);
  282. $info=$this->model->whereIn('id',$ids)->select();
  283. if($info->isEmpty()) return error("数据不存在");
  284. foreach ($info as $item){
  285. if($item->status!=1 && $item->status!=4) return error("当前数据[$item->id]状态不允许删除");
  286. if($item->balance_num!=$item->total_num) return error("数据[$item->id]数量已处理过不可删除");
  287. }
  288. $info->delete();
  289. return success("删除成功");
  290. }
  291. //调整单列表
  292. public function CheckList(){
  293. $params = $this->request->param(["page"=>1,"size"=>20,"goodType"=>'',"goodNo"=>'',"company_code"=>'',"start_time"=>"","end_time"=>"","keywords"=>""],"post","trim");
  294. $where=[];
  295. if($params['goodType']!='') $where[]=['goodType','=',$params['goodType']];
  296. if($params['goodNo']!='') $where[]=['goodNo','=',$params['goodNo']];
  297. if($params['company_code']!='') $where[]=['company_code','=',$params['company_code']];
  298. if($params['keywords']!="") $where[]=['goodName|goodNo','like',"%".$params['keywords']."%"];
  299. if($params['start_time']!="" && $params['end_time']!=""){
  300. $where[]=['create_time','between',[$params['start_time'],$params['end_time']]];
  301. }
  302. $list = FinancialCheck::where($where)
  303. ->order('id desc')
  304. ->paginate(['page'=>$params['page'],'list_rows'=>$params['size']]);
  305. return success('获取成功',['list'=>$list->items(),'count'=>$list->total()]);
  306. }
  307. //调整单数据删除
  308. public function CheckDelete(){
  309. $ids = $this->request->param('id',[]);
  310. if(empty($ids)) return error("请选择数据");
  311. $info=FinancialCheck::whereIn('id',$ids)->select();
  312. if($info->isEmpty()) return error("数据不存在");
  313. $info->delete();
  314. return success("删除成功");
  315. }
  316. public function CheckInfo(){
  317. $id = $this->request->param('id',0);
  318. $info = FinancialCheck::with(['FinancialTz'=>['ProductTz'=>['Product']],'ProductCheck'=>['Product']])->where('id',$id)->findOrEmpty();
  319. if($info->isEmpty()) return error("数据不存在");
  320. return success("获取成功",$info);
  321. }
  322. //导出数据manager异常数据
  323. public function export(){
  324. $param = $this->request->param(["code"=>"","type"=>[],"seller_code"=>"","buyer_code"=>"","orderCode"=>"","cxCode"=>"",
  325. "goodNo"=>"","inv_number"=>"","inv_buyer_code"=>"",'inv_seller_code'=>"",'channel'=>[1],'status'=>"","start"=>"","end"=>"",
  326. "page"=>1,"size"=>15],"post","trim");
  327. $where=[];
  328. $headeIndex =0;
  329. if($param['code']!="") $where[]= ["code","=","%{$param['code']}%"];
  330. if(!empty($param['type'])) $where[]= ["type","in",$param['type']];
  331. if(!empty($param['channel'])) {
  332. $where[]= ["channel","in",$param['channel']];
  333. if(in_array(3,$param['channel'])) $headeIndex =2;
  334. }
  335. if($param['status']!="") $where[]= ["status","in",$param['status']];
  336. if($param['start']!="") $where[]= ["create_time",">=",startTime($param['start'])];
  337. if($param['end']!="") $where[]= ["create_time","<=",endTime($param['end'])];
  338. if($param['seller_code']!="") $where[]= ["seller_code","=",$param['seller_code']];
  339. if($param['buyer_code']!="") $where[]= ["buyer_code","=",$param['buyer_code']];
  340. if($param['orderCode']!="") $where[]= ["orderCode","like", "%{$param['orderCode']}%"];
  341. if($param['cxCode']!="") $where[]= ["cxCode","like","%{$param['cxCode']}%"];
  342. if($param['goodNo']!="") $where[]= ["goodNo","like","%{$param['goodNo']}%"];
  343. if($param['inv_number']!="") $where[]= ["inv_number","like","%{$param['inv_number']}%"];
  344. if($param['inv_buyer_code']!="") $where[]= ["inv_buyer_code","=",$param['inv_buyer_code']];
  345. if($param['inv_seller_code']!="") $where[]= ["inv_seller_code","=",$param['inv_seller_code']];
  346. $heade=[
  347. ["业务编号","类型","订单来源","订单购买方纳税号","订单购买方公司名称","订单销售方纳税号","订单销售方公司名称","订单编号","订单主单号",
  348. "商品类型","商品编号","商品名称","订单单位","商品数量","商品单价","订单总金额","税目","税目名称","订单税率","关联金额","购买方纳税号",
  349. "购买方名称","发票号码","开票日期","发票类型","销售方纳税号","销售方公司","发票明细ID","货物或应税劳务、服务名称","类目编号","规格型号",
  350. "单位","数量","税前单价","税前总价","税率","税额","税后单价","税后总额","类目编号状态","税率状态","备注"],
  351. ["业务编号","类型","订单来源","购买方公司纳税号","购买方公司","发票号码","开票日期","发票类型","销售方公司纳税号","销售方公司","发票明细ID",
  352. "货物或应税劳务、服务名称","类目编号","规格型号","单位","数量","税前单价","税前总价","税率","税额","税后单价","税后总额"],
  353. ["业务编号","类型","订单来源","订单购买方纳税号","订单购买方公司名称","订单销售方纳税号","订单销售方公司名称","订单编号","订单主单号",
  354. "商品类型","商品编号","商品名称","订单单位","商品数量","商品单价","订单总金额","税目","税目名称","订单税率"]
  355. ];
  356. $fields=[
  357. ["invoiceCode","type",'source','seller_code','seller_name','buyer_code','buyer_name','orderCode','cxCode','goodType',
  358. 'goodNo','goodName','unit','num','goodPrice','totalPrice','cat_code','cat_name','tax','inv_fee','inv_buyer_code',
  359. 'inv_buyer_name','inv_number','inv_open_date','inv_type','inv_seller_code','inv_seller_name','inv_item_id','inv_good_name',
  360. 'inv_cat_code','inv_spec','inv_unit','inv_num','inv_subprice','inv_subtotal','inv_tax','inv_tax_total','inv_price','inv_total',
  361. 'if(cat_diff=1,"一致",if(cat_diff=2,"不一致","")) cat_diff','if(tax_diff=1,"一致",if(tax_diff=2,"不一致","")) tax_diff','remark'],
  362. ["invoiceCode","type",'source','seller_code','seller_name','inv_number','inv_open_date','inv_type','inv_seller_code','inv_seller_name',
  363. 'inv_item_id','inv_good_name','inv_cat_code','inv_spec','inv_unit','inv_num','inv_subprice','inv_subtotal','inv_tax','inv_tax_total'],
  364. [
  365. "invoiceCode","type",'source','seller_code','seller_name','buyer_code','buyer_name','orderCode','cxCode','goodType',
  366. 'goodNo','goodName','unit','num','goodPrice','totalPrice',"cat_code","cat_name","tax"]
  367. ];
  368. $list = $this->model
  369. ->field($fields[$headeIndex])
  370. ->where($where)
  371. ->order("id desc")
  372. ->select()->each(function (&$item){
  373. $item['type'] = \app\cxinv\model\FinancialManager::$ManagerType[$item['type']]??"";
  374. $item['source'] = \app\cxinv\model\FinancialManager::$ManagerSource[$item['source']]??"";
  375. $item['goodType'] = \app\cxinv\model\FinancialManager::$ManagerGoodType[$item['goodType']]??"";
  376. if(isset($item['inv_type'])) $item['inv_type'] =\app\cxinv\model\Invoice::$invoiceType[$item['inv_type']]??"";
  377. })->toArray();
  378. exportExcel($list,$heade[$headeIndex],"manager");
  379. }
  380. }