TPlusServerService.php 124 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571
  1. <?php
  2. namespace App\Service;
  3. use App\Jobs\ProcessDataJob;
  4. use App\Model\Depart;
  5. use App\Model\Employee;
  6. use App\Model\EmployeeDepartPermission;
  7. use App\Model\EmployeeIndex;
  8. use App\Model\Freight;
  9. use App\Model\FreightFee;
  10. use App\Model\ItemReport;
  11. use App\Model\ItemReportRoad;
  12. use App\Model\Product;
  13. use App\Model\RevenueCost;
  14. use App\Model\RevenueCostTotal;
  15. use App\Model\SalaryEmployee;
  16. use Illuminate\Database\Schema\Blueprint;
  17. use Illuminate\Support\Facades\DB;
  18. use Illuminate\Support\Facades\Schema;
  19. class TPlusServerService extends Service
  20. {
  21. /**
  22. * @var TPlusDatabaseServerService
  23. */
  24. protected $databaseService;
  25. /**
  26. * @var string|null
  27. */
  28. protected $error;
  29. /**
  30. * TPlusServerService constructor.
  31. */
  32. public function __construct()
  33. {
  34. $service = new TPlusDatabaseServerService();
  35. $this->databaseService = $service->db;
  36. $this->error = $service->error;
  37. }
  38. /**
  39. * 获取错误信息
  40. *
  41. * @return string|null
  42. */
  43. public function getError()
  44. {
  45. return $this->error;
  46. }
  47. private $table = "tmp_revenue_cost_data";
  48. private $table_2 = "tmp_salary_employee";
  49. private $table_3 = "tmp_freight_fee";
  50. private $table_4 = "tmp_item_road";
  51. private $table_5 = "tmp_item_cost";
  52. /**
  53. * 同步人员部门
  54. *
  55. * @param array $data
  56. * @param array $user
  57. * @return array
  58. */
  59. public function synPersonDepart($data, $user)
  60. {
  61. try {
  62. $this->databaseService->table('AA_Department')
  63. ->select('id','idparent as parent_id','name as title','code','disabled as is_use')
  64. ->chunkById(100, function ($data) {
  65. DB::transaction(function () use ($data) {
  66. $dataArray = Collect($data)->map(function ($object) {
  67. return (array)$object;
  68. })->toArray();
  69. $d_id = Depart::whereIn('id', array_column($dataArray,'id'))
  70. ->pluck('id')
  71. ->toArray();
  72. $insert = $update = [];
  73. foreach ($dataArray as $value){
  74. $is_use = $value['is_use'] ? 0 : 1;
  75. if(in_array($value['id'], $d_id)){
  76. $update[] = [
  77. 'id' => $value['id'],
  78. 'parent_id' => $value['parent_id'],
  79. 'title' => $value['title'],
  80. 'code' => $value['code'],
  81. 'is_use' => $is_use
  82. ];
  83. }else{
  84. $insert[] = [
  85. 'id' => $value['id'],
  86. 'parent_id' => $value['parent_id'],
  87. 'title' => $value['title'],
  88. 'code' => $value['code'],
  89. 'is_use' => $is_use
  90. ];
  91. }
  92. }
  93. if(! empty($insert)) Depart::insert($insert);
  94. if(! empty($update)) {
  95. foreach ($update as $value){
  96. Depart::where('id', $value['id'])
  97. ->update($value);
  98. }
  99. }
  100. });
  101. });
  102. $this->databaseService->table('AA_Person')
  103. ->select('id','code as number','name as emp_name','mobilePhoneNo as mobile','iddepartment as depart_id','disabled as state')
  104. ->chunkById(100, function ($data) {
  105. DB::transaction(function () use ($data) {
  106. $dataArray = Collect($data)->map(function ($object) {
  107. return (array)$object;
  108. })->toArray();
  109. $employee_id = Employee::whereIn('id', array_column($dataArray,'id'))
  110. ->pluck('id')
  111. ->toArray();
  112. $insert = $update = $depart_update = [];
  113. foreach ($dataArray as $value){
  114. $state = $value['state'] ? Employee::NOT_USE : Employee::USE;
  115. if(in_array($value['id'], $employee_id)){
  116. $update[] = [
  117. 'id' => $value['id'],
  118. 'number' => $value['number'],
  119. 'emp_name' => $value['emp_name'],
  120. 'mobile' => $value['mobile'],
  121. 'state' => $state
  122. ];
  123. }else{
  124. $insert[] = [
  125. 'id' => $value['id'],
  126. 'number' => $value['number'],
  127. 'emp_name' => $value['emp_name'],
  128. 'mobile' => $value['mobile'],
  129. 'state' => $state
  130. ];
  131. }
  132. $depart_update[] = [
  133. 'employee_id' => $value['id'],
  134. 'depart_id' => $value['depart_id']
  135. ];
  136. }
  137. if(! empty($insert)) Employee::insert($insert);
  138. if(! empty($update)) {
  139. foreach ($update as $value){
  140. Employee::where('id', $value['id'])
  141. ->update($value);
  142. }
  143. }
  144. if(! empty($depart_update)){
  145. EmployeeDepartPermission::whereIn('employee_id',array_column($depart_update,'employee_id'))->delete();
  146. EmployeeDepartPermission::insert($depart_update);
  147. }
  148. });
  149. });
  150. } catch (\Throwable $e) {
  151. return [false, $e->getMessage()];
  152. }
  153. return [true, ''];
  154. }
  155. /**
  156. * 收入成本统计同步
  157. *
  158. * @param array $data
  159. * @param array $user
  160. * @return array
  161. */
  162. public function synRevenueCost($data, $user){
  163. if(empty($data['crt_time'][0]) || empty($data['crt_time'][1])) return [false, '同步时间不能为空'];
  164. list($start_time, $end_time) = $this->changeDateToTimeStampAboutRange($data['crt_time'],false);
  165. if ($start_time === null || $end_time === null || $start_time > $end_time) return [false, "同步时间:时间区间无效"];
  166. list($bool, $bool_msg) = $this->isWithinMonths($start_time, $end_time);
  167. if(! $bool) return [false, $bool_msg];
  168. $data['start_timeStamp'] = $start_time;
  169. $data['end_timeStamp'] = $end_time;
  170. $start = date('Y-m-d H:i:s.000', $start_time);
  171. $end = date('Y-m-d H:i:s.000', $end_time);
  172. $data['start_time'] = $start;
  173. $data['end_time'] = $end;
  174. $data['operation_time'] = time();
  175. if(empty($data['type'])) return [false, '同步类型不能为空'];
  176. if(in_array($data['type'],[1,2,3,4])){
  177. list($status,$msg) = $this->limitingSendRequest($this->table);
  178. if(! $status) return [false, '收入成本相关信息同步正在后台运行,请稍后'];
  179. // //同步
  180. // list($status, $msg) = $this->synRevenueCostFromTPlus($data, $user);
  181. // if(! $status) {
  182. // return [false, $msg];
  183. // }
  184. //队列
  185. ProcessDataJob::dispatch($data, $user)->onQueue(RevenueCost::job);
  186. }else{
  187. return [false, '同步类型错误'];
  188. }
  189. return [true, '收入成本相关信息同步已进入后台任务'];
  190. }
  191. public function synRevenueCostFromTPlus($data, $user){
  192. //创建临时表 如果不存在
  193. $this->createTmpTable();
  194. //清理临时表 如果内容不为空
  195. $this->clearTmpTable();
  196. $type = $data['type'];
  197. //写入临时数据
  198. if($type == 1){
  199. list($status, $msg) = $this->xhdTPlus($data, $user);
  200. if(! $status) return [false, $msg];
  201. list($status, $msg) = $this->xsfpTPlus($data, $user);
  202. if(! $status) return [false, $msg];
  203. list($status, $msg) = $this->hkdTPlus($data, $user);
  204. if(! $status) return [false, $msg];
  205. }elseif ($type == 2){
  206. list($status, $msg) = $this->xhdTPlus($data, $user);
  207. if(! $status) return [false, $msg];
  208. }elseif ($type == 3){
  209. list($status, $msg) = $this->xsfpTPlus($data, $user);
  210. if(! $status) return [false, $msg];
  211. }elseif ($type == 4){
  212. list($status, $msg) = $this->hkdTPlus($data, $user);
  213. if(! $status) return [false, $msg];
  214. }
  215. //更新数据
  216. list($status,$msg) = $this->updateRevenueCost($data);
  217. if(! $status) return [false, $msg];
  218. // //更新主表数据
  219. // list($status,$msg) = $this->updateRevenueCostTotal($data);
  220. // if(! $status) return [false, $msg];
  221. //都成功后 清理临时表
  222. $this->clearTmpTable();
  223. //释放redis
  224. $this->delTableKey();
  225. return [true, '同步成功'];
  226. }
  227. private function xhdTPlus($data, $user){
  228. try {
  229. $table = $this->table;
  230. $limit = 500;
  231. $lastId = 0;
  232. do {
  233. $rows = $this->databaseService->table('SA_SaleDelivery_b as sd_b')
  234. ->join('SA_SaleDelivery as sd', 'sd_b.idSaleDeliveryDTO', '=', 'sd.ID')
  235. ->leftJoin('AA_Partner as pn', 'sd.idsettlecustomer', '=', 'pn.ID')
  236. ->leftJoin('AA_Person as ps', 'sd.idclerk', '=', 'ps.ID')
  237. ->leftJoin('AA_Person as ps2', 'pn.idsaleman', '=', 'ps2.ID')
  238. ->leftJoin('AA_Inventory as it', 'sd_b.idinventory', '=', 'it.ID')
  239. ->leftJoin('AA_Unit as ui', 'sd_b.idbaseunit', '=', 'ui.ID')
  240. ->where('sd.voucherdate', '>=', $data['start_time'])
  241. ->where('sd.voucherdate', '<=', $data['end_time'])
  242. ->where('sd_b.ID', '>', $lastId) // 用真实字段
  243. ->orderBy('sd_b.ID')
  244. ->limit($limit)
  245. ->selectRaw("
  246. COALESCE(sd.ID, 0) as order_id,
  247. COALESCE(sd.code, '') as order_number,
  248. sd.voucherdate as order_time,
  249. sd.voucherState as order_state,
  250. COALESCE(ps.name, '') as employee_id_1_title,
  251. COALESCE(sd.idclerk, 0) as employee_id_1,
  252. COALESCE(ps2.name, '') as employee_id_2_title,
  253. COALESCE(pn.idsaleman, 0) as employee_id_2,
  254. COALESCE(pn.code, '') as customer_code,
  255. COALESCE(pn.name, '') as customer_title,
  256. COALESCE(pn.priuserdefnvc14, '') as customer_profit_rate,
  257. COALESCE(sd.pubuserdefnvc11, '') as channel_finance,
  258. COALESCE(sd.pubuserdefnvc12, '') as channel_details,
  259. COALESCE(it.code, '') as product_code,
  260. COALESCE(it.name, '') as product_title,
  261. COALESCE(it.specification, '') as product_size,
  262. COALESCE(ui.name, '') as unit,
  263. COALESCE(sd_b.quantity, 0) as quantity,
  264. COALESCE(sd_b.taxPrice, 0) as price_3,
  265. COALESCE(sd_b.taxAmount, 0) as price_3_total,
  266. COALESCE(sd_b.ID, 0) as id_detail,
  267. COALESCE(sd_b.pubuserdefdecm9, 0) as is_activity
  268. ")
  269. ->get();
  270. if ($rows->isEmpty()) break;
  271. $dataArray = Collect($rows)->map(function ($object) {
  272. return (array)$object;
  273. })->toArray();
  274. //存货档案
  275. $product = Product::where('del_time', 0)
  276. ->whereIn('code', array_unique(array_column($dataArray, 'product_code')))
  277. ->select('code', 'write_off_price', 'freight_price', 'business_cost')
  278. ->get()->toArray();
  279. $product_map = array_column($product, null, 'code');
  280. //组织数据
  281. foreach ($dataArray as $key => $value) {
  282. $customer_profit_rate = rtrim($value['customer_profit_rate'],'%');
  283. if(is_numeric($customer_profit_rate)){
  284. $customer_profit_rate = bcdiv($customer_profit_rate,100,3);
  285. }else{
  286. $customer_profit_rate = 0;
  287. }
  288. $dataArray[$key]['customer_profit_rate'] = $customer_profit_rate;
  289. $p_tmp = $product_map[$value['product_code']] ?? [];
  290. $dataArray[$key]['order_type'] = RevenueCost::ORDER_ONE;
  291. $dataArray[$key]['order_time'] = strtotime($value['order_time']);
  292. $write_off_price = $p_tmp['write_off_price'] ?? 0;
  293. $dataArray[$key]['price_1'] = $write_off_price;
  294. $dataArray[$key]['price_1_total'] = bcmul($write_off_price, $value['quantity'], 2);
  295. $freight_price = $p_tmp['freight_price'] ?? 0;
  296. $dataArray[$key]['price_2'] = $freight_price;
  297. $dataArray[$key]['price_2_total'] = bcmul($freight_price, $value['quantity'], 2);
  298. $business_cost = $p_tmp['business_cost'] ?? 0;
  299. $dataArray[$key]['price_4'] = $business_cost;
  300. $price_4_total = bcmul($business_cost, $value['quantity'], 2);
  301. $dataArray[$key]['price_4_total'] = bcmul($business_cost, $value['quantity'], 2);
  302. $profit = bcsub($value['price_3_total'], $price_4_total, 2);
  303. $dataArray[$key]['profit'] = $profit;
  304. $dataArray[$key]['profit_rate'] = $value['price_3_total'] > 0 ? bcdiv($profit, $value['price_3_total'], 2) : 0;
  305. }
  306. DB::table($table)->insert($dataArray);
  307. // 更新 lastId 继续下一批
  308. $lastId = end($dataArray)['id_detail'] ?? $lastId;
  309. } while (count($rows) === $limit);
  310. }catch (\Throwable $exception){
  311. return [false, "销货单同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  312. }
  313. return [true, ''];
  314. }
  315. private function xsfpTPlus($data, $user){
  316. try {
  317. $table = $this->table;
  318. $limit = 500;
  319. $lastId = 0;
  320. do {
  321. $rows = $this->databaseService->table('SA_SaleInvoice_b as si_b')
  322. ->join('SA_SaleInvoice as si', 'si_b.idSaleInvoiceDTO', '=', 'si.ID')
  323. ->leftJoin('SA_SaleDelivery_b as sd_b', 'si_b.sourceVoucherDetailId', '=', 'sd_b.ID')
  324. ->leftJoin('AA_Partner as pn', 'si.idsettlecustomer', '=', 'pn.ID')
  325. ->leftJoin('AA_Person as ps', 'si.idclerk', '=', 'ps.ID')
  326. ->leftJoin('AA_Person as ps2', 'pn.idsaleman', '=', 'ps2.ID')
  327. ->leftJoin('AA_Inventory as it', 'si_b.idinventory', '=', 'it.ID')
  328. ->leftJoin('AA_Unit as ui', 'si_b.idbaseunit', '=', 'ui.ID')
  329. ->where('si.voucherdate','>=',$data['start_time'])
  330. ->where('si.voucherdate','<=',$data['end_time'])
  331. ->where('si_b.ID', '>', $lastId) // 用真实字段
  332. ->orderBy('si_b.ID')
  333. ->limit($limit)
  334. ->selectRaw("
  335. COALESCE(si.ID, 0) as order_id,
  336. COALESCE(si.code, '') as order_number,
  337. si.voucherdate as order_time,
  338. si.voucherState as order_state,
  339. COALESCE(pn.code, '') as customer_code,
  340. COALESCE(pn.name, '') as customer_title,
  341. COALESCE(pn.priuserdefnvc14, '') as customer_profit_rate,
  342. COALESCE(si.idclerk, 0) as employee_id_1,
  343. COALESCE(ps.name, '') as employee_id_1_title,
  344. COALESCE(pn.idsaleman, 0) as employee_id_2,
  345. COALESCE(ps2.name, '') as employee_id_2_title,
  346. COALESCE(it.code, '') as product_code,
  347. COALESCE(it.name, '') as product_title,
  348. COALESCE(it.specification, '') as product_size,
  349. COALESCE(ui.name, '') as unit,
  350. COALESCE(si_b.quantity, 0) as quantity,
  351. COALESCE(si_b.taxPrice, 0) as price_1,
  352. COALESCE(si_b.taxAmount, 0) as price_1_total,
  353. COALESCE(si_b.ID, 0) as id_detail,
  354. COALESCE(si_b.sourceVoucherDetailId, 0) as id_detail_upstream,
  355. COALESCE(si_b.sourceVoucherCode, '') as order_number_upstream,
  356. COALESCE(sd_b.pubuserdefdecm9, 0) as is_activity
  357. ")
  358. ->get();
  359. if ($rows->isEmpty()) break;
  360. $dataArray = Collect($rows)->map(function ($object) {
  361. return (array)$object;
  362. })->toArray();
  363. //存货档案
  364. $product = Product::where('del_time',0)
  365. ->whereIn('code', array_unique(array_column($dataArray,'product_code')))
  366. ->select('code','business_cost')
  367. ->get()->toArray();
  368. $product_map = array_column($product,null,'code');
  369. //组织数据
  370. foreach ($dataArray as $key => $value){
  371. $customer_profit_rate = rtrim($value['customer_profit_rate'],'%');
  372. if(is_numeric($customer_profit_rate)){
  373. $customer_profit_rate = bcdiv($customer_profit_rate,100,3);
  374. }else{
  375. $customer_profit_rate = 0;
  376. }
  377. $dataArray[$key]['customer_profit_rate'] = $customer_profit_rate;
  378. $p_tmp = $product_map[$value['product_code']] ?? [];
  379. $dataArray[$key]['order_type'] = RevenueCost::ORDER_TWO;
  380. $dataArray[$key]['order_time'] = strtotime($value['order_time']);
  381. $business_cost = $p_tmp['business_cost'] ?? 0;
  382. $dataArray[$key]['price_4'] = $business_cost;
  383. $price_4_total = bcmul($business_cost, $value['quantity'],2);
  384. $dataArray[$key]['price_4_total'] = bcmul($business_cost, $value['quantity'],2);
  385. $profit = bcsub($value['price_1_total'], $price_4_total,2);
  386. $dataArray[$key]['profit'] = $profit;
  387. $dataArray[$key]['profit_rate'] = $value['price_1_total'] > 0 ? bcdiv($profit, $value['price_1_total'],2) : 0;
  388. }
  389. DB::table($table)->insert($dataArray);
  390. // 更新 lastId 继续下一批
  391. $lastId = end($dataArray)['id_detail'] ?? $lastId;
  392. } while (count($rows) === $limit);
  393. }catch (\Throwable $exception){
  394. return [false, "销售发票同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  395. }
  396. return [true, ''];
  397. }
  398. private function hkdTPlus($data, $user){
  399. try{
  400. $table = $this->table;
  401. $limit = 500;
  402. $lastId = 0;
  403. do {
  404. $rows = $this->databaseService->table('ARAP_ReceivePayment_b as rp_b')
  405. ->join('ARAP_ReceivePayment as rp', 'rp_b.idArapReceivePaymentDTO', '=', 'rp.ID')
  406. // ->leftJoin('SA_SaleInvoice_b as si_b', 'rp_b.voucherDetailID', '=', 'si_b.ID')
  407. // ->leftJoin('SA_SaleInvoice as si', 'si_b.idSaleInvoiceDTO', '=', 'si.ID')
  408. // ->leftJoin('SA_SaleDelivery_b as sd_b', 'si_b.sourceVoucherDetailId', '=', 'sd_b.ID')
  409. // 发票子表关联(仅限 idvouchertype = 20)
  410. ->leftJoin('SA_SaleInvoice_b as si_b', function ($join) {
  411. $join->on('rp_b.voucherDetailID', '=', 'si_b.ID')
  412. ->where('rp_b.idvouchertype', '=', 20);
  413. })
  414. ->leftJoin('SA_SaleInvoice as si', function ($join) {
  415. $join->on('si_b.idSaleInvoiceDTO', '=', 'si.ID')
  416. ->where('rp_b.idvouchertype', '=', 20);
  417. })
  418. ->leftJoin('SA_SaleDelivery_b as sd_b', function ($join) {
  419. $join->on('si_b.sourceVoucherDetailId', '=', 'sd_b.ID')
  420. ->where('rp_b.idvouchertype', '=', 20);
  421. })
  422. ->leftJoin('AA_Partner as pn', 'si.idsettlecustomer', '=', 'pn.ID')
  423. ->leftJoin('AA_Person as ps', 'rp.idperson', '=', 'ps.ID')
  424. ->leftJoin('AA_Person as ps2', 'pn.idsaleman', '=', 'ps2.ID')
  425. ->leftJoin('AA_Inventory as it', 'si_b.idinventory', '=', 'it.ID')
  426. ->leftJoin('AA_Unit as ui', 'si_b.idbaseunit', '=', 'ui.ID')
  427. ->where('rp.voucherdate','>=',$data['start_time'])
  428. ->where('rp.voucherdate','<=',$data['end_time'])
  429. // ->where('rp_b.idvouchertype','=', 20) // 销售发票
  430. ->where('rp.isReceiveFlag','=', 1)
  431. ->where('rp_b.ID', '>', $lastId)
  432. ->orderBy('rp_b.ID')
  433. ->limit($limit)
  434. // ->selectRaw("
  435. // COALESCE(rp.ID, 0) as order_id,
  436. // COALESCE(rp.code, '') as order_number,
  437. // rp.voucherdate as order_time,
  438. // COALESCE(pn.code, '') as customer_code,
  439. // COALESCE(pn.name, '') as customer_title,
  440. // COALESCE(pn.priuserdefnvc14, '') as customer_profit_rate,
  441. // COALESCE(it.code, '') as product_code,
  442. // COALESCE(it.name, '') as product_title,
  443. // COALESCE(rp.idperson, 0) as employee_id_1,
  444. // COALESCE(ps.name, '') as employee_id_1_title,
  445. // COALESCE(pn.idsaleman, 0) as employee_id_2,
  446. // COALESCE(ps2.name, '') as employee_id_2_title,
  447. // COALESCE(it.specification, '') as product_size,
  448. // COALESCE(ui.name, '') as unit,
  449. // COALESCE(si_b.quantity, 0) as quantity,
  450. // COALESCE(si_b.taxPrice, 0) as price_1,
  451. // COALESCE(si_b.taxAmount, 0) as price_1_total,
  452. // COALESCE(rp_b.amount, 0) as payment_amount,
  453. // COALESCE(rp_b.ID, 0) as id_detail,
  454. // COALESCE(rp_b.voucherDetailID, 0) as id_detail_upstream,
  455. // COALESCE(rp_b.voucherCode, '') as order_number_upstream,
  456. // COALESCE(sd_b.pubuserdefdecm9, 0) as is_activity
  457. // ")
  458. ->selectRaw("
  459. COALESCE(rp.ID, 0) as order_id,
  460. COALESCE(rp.code, '') as order_number,
  461. rp.voucherdate as order_time,
  462. rp.voucherstate as order_state,
  463. COALESCE(rp.pubuserdefnvc11, '') as channel_finance,
  464. COALESCE(rp.pubuserdefnvc12, '') as channel_details,
  465. COALESCE(pn.code, '') as customer_code,
  466. COALESCE(pn.name, '') as customer_title,
  467. COALESCE(pn.priuserdefnvc14, '') as customer_profit_rate,
  468. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(it.code, '') ELSE '' END as product_code,
  469. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(it.name, '') ELSE '' END as product_title,
  470. COALESCE(rp.idperson, 0) as employee_id_1,
  471. COALESCE(ps.name, '') as employee_id_1_title,
  472. COALESCE(pn.idsaleman, 0) as employee_id_2,
  473. COALESCE(ps2.name, '') as employee_id_2_title,
  474. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(it.specification, '') ELSE '' END as product_size,
  475. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(ui.name, '') ELSE '' END as unit,
  476. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(si_b.quantity, 0) ELSE 0 END as quantity,
  477. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(si_b.taxPrice, 0) ELSE 0 END as price_1,
  478. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(si_b.taxAmount, 0) ELSE 0 END as price_1_total,
  479. COALESCE(rp_b.origCurrentAmount, 0) as payment_amount,
  480. COALESCE(rp_b.ID, 0) as id_detail,
  481. COALESCE(rp_b.voucherDetailID, 0) as id_detail_upstream,
  482. COALESCE(rp_b.voucherCode, '') as order_number_upstream,
  483. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(sd_b.pubuserdefdecm9, 0) ELSE 0 END as is_activity,
  484. rp_b.idvouchertype as voucher_type
  485. ")
  486. ->get();
  487. // COALESCE(rp_b.amount, 0) as payment_amount,
  488. if ($rows->isEmpty()) break;
  489. $dataArray = Collect($rows)->map(function ($object) {
  490. return (array)$object;
  491. })->toArray();
  492. //存货档案
  493. $product = Product::where('del_time',0)
  494. ->whereIn('code', array_unique(array_column($dataArray,'product_code')))
  495. ->select('code','business_cost')
  496. ->get()->toArray();
  497. $product_map = array_column($product,null,'code');
  498. //组织数据
  499. foreach ($dataArray as $key => $value){
  500. $customer_profit_rate = rtrim($value['customer_profit_rate'],'%');
  501. if(is_numeric($customer_profit_rate)){
  502. $customer_profit_rate = bcdiv($customer_profit_rate,100,3);
  503. }else{
  504. $customer_profit_rate = 0;
  505. }
  506. $dataArray[$key]['customer_profit_rate'] = $customer_profit_rate;
  507. $p_tmp = $product_map[$value['product_code']] ?? [];
  508. $dataArray[$key]['order_type'] = RevenueCost::ORDER_THREE;
  509. $dataArray[$key]['order_time'] = strtotime($value['order_time']);
  510. $business_cost = $p_tmp['business_cost'] ?? 0;
  511. $dataArray[$key]['price_4'] = $business_cost;
  512. $price_4_total = bcmul($business_cost, $value['quantity'],2);
  513. $dataArray[$key]['price_4_total'] = $price_4_total;
  514. $profit = bcsub($value['price_1_total'], $price_4_total,2);
  515. $dataArray[$key]['profit'] = $profit;
  516. $dataArray[$key]['profit_rate'] = $value['price_1_total'] > 0 ? bcdiv($profit, $value['price_1_total'],2) : 0;
  517. }
  518. DB::table($table)->insert($dataArray);
  519. // 更新 lastId 继续下一批
  520. $lastId = end($dataArray)['id_detail'] ?? $lastId;
  521. } while (count($rows) === $limit);
  522. }catch (\Throwable $exception){
  523. return [false, "回款单同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  524. }
  525. return [true, ''];
  526. }
  527. private function updateRevenueCost($data){
  528. try {
  529. $start_timeStamp = $data['start_timeStamp'];
  530. $end_timeStamp = $data['end_timeStamp'];
  531. $tmpTable = $this->table;
  532. $time = time();
  533. $ergs = $data;
  534. DB::transaction(function () use ($start_timeStamp, $end_timeStamp, $tmpTable,$time, $ergs) {
  535. // 1. 先软删除旧数据(你已有)
  536. RevenueCost::where('del_time', 0)
  537. ->where('order_time', '>=', $start_timeStamp)
  538. ->where('order_time', '<=', $end_timeStamp)
  539. ->update(['del_time' => $time]);
  540. // 2. 分批从临时表插入新数据
  541. $batchSize = 500;
  542. $lastId = 0;
  543. do {
  544. $chunk = DB::table($tmpTable)
  545. ->where('id', '>', $lastId)
  546. ->orderBy('id')
  547. ->limit($batchSize)
  548. ->get();
  549. if ($chunk->isEmpty()) {
  550. break;
  551. }
  552. $data = $chunk->map(function ($item) use($time){
  553. return [
  554. 'order_id' => $item->order_id,
  555. 'order_number' => $item->order_number,
  556. 'order_time' => $item->order_time,
  557. 'order_state' => $item->order_state,
  558. 'employee_id_1_title' => $item->employee_id_1_title,
  559. 'employee_id_1' => $item->employee_id_1 ?? 0,
  560. 'employee_id_2' => $item->employee_id_2 ?? 0,
  561. 'employee_id_2_title' => $item->employee_id_2_title ?? "",
  562. 'customer_code' => $item->customer_code,
  563. 'customer_title' => $item->customer_title,
  564. 'channel_finance' => $item->channel_finance,
  565. 'channel_details' => $item->channel_details,
  566. 'product_code' => $item->product_code,
  567. 'product_title' => $item->product_title,
  568. 'product_size' => $item->product_size,
  569. 'unit' => $item->unit,
  570. 'quantity' => $item->quantity,
  571. 'price_1' => $item->price_1,
  572. 'price_1_total' => $item->price_1_total,
  573. 'price_2' => $item->price_2,
  574. 'price_2_total' => $item->price_2_total,
  575. 'price_3' => $item->price_3,
  576. 'price_3_total' => $item->price_3_total,
  577. 'price_4' => $item->price_4,
  578. 'price_4_total' => $item->price_4_total,
  579. 'profit' => $item->profit,
  580. 'profit_rate' => $item->profit_rate,
  581. 'id_detail' => $item->id_detail,
  582. 'order_type' => $item->order_type,
  583. 'payment_amount' => $item->payment_amount ?? 0,
  584. 'id_detail_upstream' => $item->id_detail_upstream?? 0,
  585. 'order_number_upstream' => $item->order_number_upstream ?? "",
  586. 'is_activity' => $item->is_activity ?? 0,
  587. 'customer_profit_rate' => $item->customer_profit_rate ?? '',
  588. 'voucher_type' => $item->voucher_type ?? 0,
  589. 'crt_time' => $time,
  590. ];
  591. })->toArray();
  592. // 每批单独插入(可选:加小事务)
  593. RevenueCost::insert($data);
  594. // 更新 lastId
  595. $lastId = $chunk->last()->id;
  596. } while ($chunk->count() == $batchSize);
  597. // 3. 更新主表
  598. list($status, $msg) = $this->updateRevenueCostTotal($ergs);
  599. if (! $status) {
  600. throw new \Exception($msg);
  601. }
  602. });
  603. }catch (\Throwable $exception){
  604. return [false, "单据明细同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  605. }
  606. return [true, ''];
  607. }
  608. private function updateRevenueCostTotal($data){
  609. try {
  610. $start_timeStamp = $data['start_timeStamp'];
  611. $end_timeStamp = $data['end_timeStamp'];
  612. $time = time();
  613. //组织写入数据
  614. $return = [];
  615. $update_stamp = [];
  616. DB::table('revenue_cost')
  617. ->where('del_time',0)
  618. ->where('order_time', '>=', $start_timeStamp)
  619. ->where('order_time', '<=', $end_timeStamp)
  620. ->select(RevenueCost::$field)
  621. ->chunkById(100, function ($data) use(&$return,&$update_stamp){
  622. $dataArray = Collect($data)->map(function ($object){
  623. return (array)$object;
  624. })->toArray();
  625. foreach ($dataArray as $value){
  626. //变成每个月第一天的时间戳
  627. $time = date("Y-m-01", $value['order_time']);
  628. $stamp = strtotime($time);
  629. if(! in_array($stamp, $update_stamp)) $update_stamp[] = $stamp;
  630. if($value['order_type'] == RevenueCost::ORDER_ONE){
  631. $income = $value['price_3_total'];
  632. }elseif ($value['order_type'] == RevenueCost::ORDER_TWO){
  633. $income = $value['price_1_total'];
  634. }else{
  635. $income = $value['payment_amount'];
  636. }
  637. $adjust = $income < 0 ? $income : 0;
  638. $business = $value['price_4_total'];
  639. if(isset($return[$stamp][$value['order_type']][$value['employee_id_1']])){
  640. $income_total = bcadd($return[$stamp][$value['order_type']][$value['employee_id_1']]['income'], $income,2);
  641. $adjust_total = bcadd($return[$stamp][$value['order_type']][$value['employee_id_1']]['adjust'], $adjust,2);
  642. $business_total = bcadd($return[$stamp][$value['order_type']][$value['employee_id_1']]['business'], $business,2);
  643. $return[$stamp][$value['order_type']][$value['employee_id_1']]['income'] = $income_total;
  644. $return[$stamp][$value['order_type']][$value['employee_id_1']]['adjust'] = $adjust_total;
  645. $return[$stamp][$value['order_type']][$value['employee_id_1']]['business'] = $business_total;
  646. }else{
  647. $return[$stamp][$value['order_type']][$value['employee_id_1']] = [
  648. 'income' => $income,
  649. 'adjust' => $adjust,
  650. 'business' => $business,
  651. 'order_time' => $stamp,
  652. 'employee_id_1_title' => $value['employee_id_1_title'],
  653. ];
  654. }
  655. }
  656. });
  657. $insert = [];
  658. foreach ($return as $value){
  659. foreach ($value as $order_type => $val){
  660. foreach ($val as $employee_id => $v){
  661. $profit = bcsub($v['income'], $v['business'],2);
  662. $profit_rate = $v['income'] > 0 ? bcdiv($profit, $v['income'],2) : 0;
  663. $v['profit'] = $profit;
  664. $v['profit_rate'] = $profit_rate;
  665. $v['order_type'] = $order_type;
  666. $v['employee_id_1'] = $employee_id;
  667. $v['crt_time'] = $time;
  668. $insert[] = $v;
  669. }
  670. }
  671. }
  672. RevenueCostTotal::where('del_time', 0)
  673. ->whereIn('order_time', $update_stamp)
  674. ->update(['del_time' => $time]);
  675. RevenueCostTotal::insert($insert);
  676. }catch (\Throwable $exception){
  677. return [false, "主表同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  678. }
  679. return [true, ''];
  680. }
  681. private function createTmpTable(){
  682. $table = $this->table;
  683. if (! Schema::hasTable($table)) {
  684. // 可以通过 migration 创建,或程序启动时检查
  685. Schema::create($table, function (Blueprint $table) {
  686. $table->bigIncrements('id'); // BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY
  687. $table->integer('order_type')->default(0);
  688. $table->bigInteger('order_id')->default(0);
  689. $table->string('order_number', 50)->default('');
  690. $table->integer('order_time')->nullable();
  691. $table->integer('order_state')->default(0);
  692. $table->string('employee_id_1_title', 100)->default('');
  693. $table->bigInteger('employee_id_1')->default(0);
  694. $table->bigInteger('employee_id_2')->default(0);
  695. $table->string('employee_id_2_title', 100)->default('');
  696. $table->string('customer_code', 50)->default('');
  697. $table->string('customer_title', 100)->default('');
  698. $table->string('channel_finance', 50)->nullable();
  699. $table->string('channel_details', 50)->nullable();
  700. $table->string('product_code', 50)->default('');
  701. $table->string('product_title', 100)->default('');
  702. $table->string('product_size', 100)->nullable();
  703. $table->string('unit', 20)->nullable();
  704. $table->decimal('quantity', 12, 2)->default(0);
  705. $table->decimal('price_1', 12, 2)->default(0); // 销项成本
  706. $table->decimal('price_1_total', 12, 2)->default(0);
  707. $table->decimal('price_2', 12, 2)->default(0); // 运费
  708. $table->decimal('price_2_total', 12, 2)->default(0);
  709. $table->decimal('price_3', 12, 2)->default(0); // 含税单价
  710. $table->decimal('price_3_total', 12, 2)->default(0); // 含税金额
  711. $table->decimal('price_4', 12, 2)->default(0); // 业务成本
  712. $table->decimal('price_4_total', 12, 2)->default(0);
  713. $table->decimal('profit', 12, 2)->default(0);
  714. $table->decimal('payment_amount', 12, 2)->default(0);
  715. $table->decimal('profit_rate', 10, 3)->default(0);
  716. $table->bigInteger('id_detail')->default(0);
  717. $table->bigInteger('id_detail_upstream')->default(0);
  718. $table->string('order_number_upstream', 100)->nullable();
  719. $table->decimal('is_activity', 2, 0)->default(0);
  720. $table->string('customer_profit_rate', 20)->default('');
  721. $table->bigInteger('voucher_type')->default(0);
  722. });
  723. }
  724. }
  725. public function clearTmpTable($type = 1){
  726. if($type == 1){
  727. if (Schema::hasTable($this->table)) DB::table($this->table)->truncate();
  728. }elseif ($type == 2){
  729. if (Schema::hasTable($this->table_2)) DB::table($this->table_2)->truncate();
  730. }elseif ($type == 3){
  731. if (Schema::hasTable($this->table_3)) DB::table($this->table_3)->truncate();
  732. }elseif ($type == 4){
  733. if (Schema::hasTable($this->table_4)) DB::table($this->table_4)->truncate();
  734. if (Schema::hasTable($this->table_5)) DB::table($this->table_5)->truncate();
  735. }
  736. // elseif ($type == 5){
  737. // if (Schema::hasTable($this->table_5)) DB::table($this->table_5)->truncate();
  738. // }
  739. }
  740. public function delTableKey($type = 1){
  741. $key = $this->table;
  742. if($type == 2) $key = $this->table_2;
  743. if($type == 3) $key = $this->table_3;
  744. if($type == 4) $key = $this->table_4;
  745. $this->dellimitingSendRequest($key);
  746. }
  747. public function synSalaryEmployee($data, $user){
  748. if(empty($data['crt_time'][0]) || empty($data['crt_time'][1])) return [false, '同步时间不能为空'];
  749. list($start_time, $end_time) = $this->changeDateToTimeStampAboutRange($data['crt_time'],false);
  750. if ($start_time === null || $end_time === null || $start_time > $end_time) return [false, "同步时间:时间区间无效"];
  751. list($bool, $bool_msg) = $this->isWithinMonths($start_time, $end_time);
  752. if(! $bool) return [false, $bool_msg];
  753. $data['start_timeStamp'] = $start_time;
  754. $data['end_timeStamp'] = $end_time;
  755. $data['start_time'] = strtotime(date("Y-m-01",$data['start_timeStamp']));
  756. $data['end_time'] = strtotime(date("Y-m-01"),$data['end_timeStamp']);
  757. $data['operation_time'] = time();
  758. $data['type'] = 5;
  759. list($status,$msg) = $this->limitingSendRequest($this->table_2);
  760. if(! $status) return [false, '业务员工资同步正在后台运行,请稍后'];
  761. //同步
  762. // list($status, $msg) = $this->synSalaryEmployeeFromMine($data, $user);
  763. // if(! $status) {
  764. // $this->dellimitingSendRequest($this->table_2);
  765. // return [false, $msg];
  766. // }
  767. //队列
  768. ProcessDataJob::dispatch($data, $user, 2)->onQueue(RevenueCost::job2);
  769. return [true, '业务员工资相关信息同步已进入后台任务'];
  770. }
  771. public function synSalaryEmployeeFromMine($data, $user){
  772. //创建临时表 如果不存在
  773. $this->createTmpTable2();
  774. //清理临时表 如果内容不为空
  775. $this->clearTmpTable(2);
  776. //写入临时表
  777. DB::table('revenue_cost')
  778. ->where('del_time', 0)
  779. ->where('order_type', RevenueCost::ORDER_THREE)
  780. ->where('order_time','>=',$data['start_timeStamp'])
  781. ->where('order_time','<=',$data['end_timeStamp'])
  782. ->select([
  783. 'employee_id_1',
  784. 'employee_id_1_title',
  785. 'order_time as time',
  786. DB::raw("DATE_FORMAT(FROM_UNIXTIME(order_time), '%Y-%m-01') as order_time"),
  787. DB::raw("SUM(payment_amount) as payment_amount"),
  788. DB::raw("SUM(CASE WHEN is_activity = 0 THEN payment_amount ELSE 0 END) as payment_amount_not_include_activity"),
  789. DB::raw("SUM(CASE WHEN is_activity = 1 THEN payment_amount ELSE 0 END) as payment_amount_activity"),
  790. DB::raw("SUM(CASE WHEN profit_rate < customer_profit_rate and is_activity = 0 THEN payment_amount ELSE 0 END) as payment_amount_lower_than_rate"),
  791. DB::raw("SUM(CASE WHEN profit_rate >= customer_profit_rate and is_activity = 0 THEN payment_amount ELSE 0 END) as payment_amount_greater_than_rate"),
  792. DB::raw("SUM(CASE WHEN profit_rate >= customer_profit_rate and is_activity = 0 THEN price_4_total ELSE 0 END) as business"),
  793. DB::raw("ROW_NUMBER() OVER (ORDER BY MIN(id)) as fake_id")
  794. ])
  795. ->groupBy('employee_id_1', DB::raw("DATE_FORMAT(FROM_UNIXTIME(order_time), '%Y-%m-01')"))
  796. ->orderBy('order_time', 'desc')
  797. ->chunkById(500, function ($data){
  798. $dataArray = Collect($data)->map(function ($object){
  799. return (array)$object;
  800. })->toArray();
  801. $indexes = $this->getEmployeeIndex($dataArray);
  802. foreach ($dataArray as $key => $value){
  803. $value['index_' . EmployeeIndex::TYPE_ONE] = 0;
  804. $value['index_' . EmployeeIndex::TYPE_SIX] = 0;
  805. $value['index_' . EmployeeIndex::TYPE_EIGHT] = 0;
  806. $this->findIndex($indexes, $value);
  807. $dataArray[$key]['order_type'] = RevenueCost::ORDER_THREE;
  808. $dataArray[$key]['order_time'] = strtotime($value['order_time']);
  809. $dataArray[$key]['sale_bonus'] = $value['index_' . EmployeeIndex::TYPE_EIGHT];
  810. $dataArray[$key]['index_' . EmployeeIndex::TYPE_ONE] = $value['index_' . EmployeeIndex::TYPE_ONE];
  811. $rate = bcdiv($value['index_' . EmployeeIndex::TYPE_ONE],100,2);
  812. $pay_in_advance = bcmul($rate, $value['payment_amount_greater_than_rate'],2);
  813. $dataArray[$key]['pay_in_advance'] = $pay_in_advance;
  814. $dataArray[$key]['basic_salary'] = $value['index_' . EmployeeIndex::TYPE_SIX];
  815. $dataArray[$key]['should_pay'] = bcadd(bcadd($value['index_' . EmployeeIndex::TYPE_EIGHT], $pay_in_advance,2),$value['index_' . EmployeeIndex::TYPE_SIX],2);
  816. unset($dataArray[$key]['fake_id']);
  817. unset($dataArray[$key]['time']);
  818. }
  819. DB::table($this->table_2)->insert($dataArray);
  820. }, 'fake_id');
  821. //更新数据
  822. list($status,$msg) = $this->updateSalaryEmployee($data);
  823. if(! $status) return [false, $msg];
  824. //清理临时表 如果内容不为空
  825. $this->clearTmpTable(2);
  826. //释放redis
  827. $this->delTableKey(2);
  828. return [true, '同步成功'];
  829. }
  830. private function getEmployeeIndex($existingData)
  831. {
  832. if (empty($existingData)) {
  833. return collect();
  834. }
  835. // 取出所有涉及的 employee_id 和时间区间
  836. $employeeIds = array_column($existingData, 'employee_id_1');
  837. $time = array_column($existingData, 'time');
  838. $minStart = ! empty($time) ? min($time) : 0;
  839. $maxEnd = ! empty($time) ? max($time) : 0;
  840. // 一次性查出这些员工在最大区间范围内的所有指标
  841. $results = EmployeeIndex::where('del_time', 0)
  842. ->whereIn('type', [EmployeeIndex::TYPE_ONE, EmployeeIndex::TYPE_EIGHT, EmployeeIndex::TYPE_SIX])
  843. ->whereIn('employee_id', $employeeIds)
  844. ->where('start_time', '<=', $maxEnd)
  845. ->where('end_time', '>=', $minStart)
  846. ->select('start_time','end_time','employee_id','index','type')
  847. ->get();
  848. return $results;
  849. }
  850. private function findIndex($indexes, &$value){
  851. // 找到所有符合条件的 index(可能多个 type)
  852. $matchedIndexes = $indexes->filter(function ($item) use ($value) {
  853. return $item['employee_id'] == $value['employee_id_1']
  854. && $item['start_time'] <= $value['time']
  855. && $item['end_time'] >= $value['time'];
  856. });
  857. // 按 type 去重,只保留第一次出现的
  858. $uniqueByType = [];
  859. foreach ($matchedIndexes as $item) {
  860. $index = "index_" . $item['type'];
  861. if (! isset($uniqueByType[$index])) {
  862. $uniqueByType[$index] = $item['index'];
  863. }
  864. }
  865. $value = array_merge($value, $uniqueByType);
  866. }
  867. private function createTmpTable2(){
  868. $table = $this->table_2;
  869. if (! Schema::hasTable($table)) {
  870. // 可以通过 migration 创建,或程序启动时检查
  871. Schema::create($table, function (Blueprint $table) {
  872. $table->bigIncrements('id'); // BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY
  873. $table->integer('order_type')->default(0);
  874. $table->integer('order_time')->default(0);
  875. $table->string('employee_id_1_title', 100)->default('');
  876. $table->bigInteger('employee_id_1')->default(0);
  877. $table->decimal('payment_amount', 12, 2)->default(0);
  878. $table->decimal('payment_amount_not_include_activity', 12, 2)->default(0);
  879. $table->decimal('payment_amount_activity', 12, 2)->default(0);
  880. $table->decimal('payment_amount_lower_than_rate', 12, 2)->default(0);
  881. $table->decimal('payment_amount_greater_than_rate', 12, 2)->default(0);
  882. $table->decimal('business', 12, 2)->default(0);
  883. $table->decimal('sale_bonus', 12, 2)->default(0);
  884. $table->decimal('index_1', 10, 2)->default(0);
  885. $table->decimal('pay_in_advance', 12, 2)->default(0);
  886. $table->decimal('basic_salary', 12, 2)->default(0);
  887. $table->decimal('should_pay', 12, 2)->default(0);
  888. });
  889. }
  890. }
  891. private function updateSalaryEmployee($data){
  892. try {
  893. $start_timeStamp = $data['start_time'];
  894. $end_timeStamp = $data['end_time'];
  895. $tmpTable = $this->table_2;
  896. $time = time();
  897. $ergs = $data;
  898. DB::transaction(function () use ($start_timeStamp, $end_timeStamp, $tmpTable,$time, $ergs) {
  899. // 1. 先软删除旧数据(你已有)
  900. SalaryEmployee::where('del_time', 0)
  901. ->where('order_time', '>=', $start_timeStamp)
  902. ->where('order_time', '<=', $end_timeStamp)
  903. ->update(['del_time' => $time]);
  904. // 2. 分批从临时表插入新数据
  905. $batchSize = 500;
  906. $lastId = 0;
  907. do {
  908. $chunk = DB::table($tmpTable)
  909. ->where('id', '>', $lastId)
  910. ->orderBy('id')
  911. ->limit($batchSize)
  912. ->get();
  913. if ($chunk->isEmpty()) {
  914. break;
  915. }
  916. $data = $chunk->map(function ($item) use($time){
  917. return [
  918. 'order_type' => $item->order_type,
  919. 'order_time' => $item->order_time,
  920. 'employee_id_1_title' => $item->employee_id_1_title,
  921. 'employee_id_1' => $item->employee_id_1 ?? 0,
  922. 'payment_amount' => $item->payment_amount,
  923. 'payment_amount_not_include_activity' => $item->payment_amount_not_include_activity,
  924. 'payment_amount_activity' => $item->payment_amount_activity,
  925. 'payment_amount_lower_than_rate' => $item->payment_amount_lower_than_rate,
  926. 'payment_amount_greater_than_rate' => $item->payment_amount_greater_than_rate,
  927. 'business' => $item->business,
  928. 'sale_bonus' => $item->sale_bonus,
  929. 'index_1' => $item->index_1,
  930. 'pay_in_advance' => $item->pay_in_advance,
  931. 'basic_salary' => $item->basic_salary,
  932. 'should_pay' => $item->should_pay,
  933. 'crt_time' => $time,
  934. ];
  935. })->toArray();
  936. // 每批单独插入(可选:加小事务)
  937. SalaryEmployee::insert($data);
  938. // 更新 lastId
  939. $lastId = $chunk->last()->id;
  940. } while ($chunk->count() == $batchSize);
  941. });
  942. }catch (\Throwable $exception){
  943. return [false, "单据明细同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  944. }
  945. return [true, ''];
  946. }
  947. public function synFreightFee($data, $user){
  948. if(empty($data['crt_time'][0]) || empty($data['crt_time'][1])) return [false, '同步时间不能为空'];
  949. list($start_time, $end_time) = $this->changeDateToTimeStampAboutRange($data['crt_time'],false);
  950. if ($start_time === null || $end_time === null || $start_time > $end_time) return [false, "同步时间:时间区间无效"];
  951. list($bool, $bool_msg) = $this->isWithinMonths($start_time, $end_time);
  952. if(! $bool) return [false, $bool_msg];
  953. $data['start_timeStamp'] = $start_time;
  954. $data['end_timeStamp'] = $end_time;
  955. $start = date('Y-m-d H:i:s.000', $start_time);
  956. $end = date('Y-m-d H:i:s.000', $end_time);
  957. $data['start_time'] = $start;
  958. $data['end_time'] = $end;
  959. $data['operation_time'] = time();
  960. $data['type'] = 6;
  961. // list($status, $msg) = $this->synFreightFeeFromMine($data, $user);dd($status, $msg);
  962. list($status,$msg) = $this->limitingSendRequest($this->table_3);
  963. if(! $status) return [false, '运费统计同步正在后台运行,请稍后'];
  964. //同步
  965. // list($status, $msg) = $this->synFreightFeeFromMine($data, $user);
  966. // if(! $status) {
  967. // $this->dellimitingSendRequest($this->table_3);
  968. // return [false, $msg];
  969. // }
  970. //队列
  971. ProcessDataJob::dispatch($data, $user, 3)->onQueue(RevenueCost::job3);
  972. return [true, '运费统计同步已进入后台任务'];
  973. }
  974. public function synFreightFeeFromMine($data, $user){
  975. //创建临时表 如果不存在
  976. $this->createTmpTable3();
  977. //清理临时表 如果内容不为空
  978. $this->clearTmpTable(3);
  979. //生成临时数据
  980. list($status, $msg) = $this->getFreightData($data);
  981. if(! $status) return [false, $msg];
  982. //写入
  983. list($status, $msg) = $this->updateFreightFeeFromMine($data);
  984. if(! $status) return [false, $msg];
  985. //清理临时表 如果内容不为空
  986. $this->clearTmpTable(3);
  987. //释放redis
  988. $this->delTableKey(3);
  989. return [true, '同步成功'];
  990. }
  991. private function createTmpTable3(){
  992. $table = $this->table_3;
  993. if (! Schema::hasTable($table)) {
  994. // 可以通过 migration 创建,或程序启动时检查
  995. Schema::create($table, function (Blueprint $table) {
  996. // 主键
  997. $table->bigIncrements('id');
  998. // 原始字段
  999. $table->bigInteger('order_id')->default(0)->comment('订单ID');
  1000. $table->string('order_number')->default('')->comment('订单编号');
  1001. $table->dateTime('order_time')->nullable()->comment('订单时间');
  1002. $table->integer('order_state')->default(0)->comment('订单状态');
  1003. $table->string('employee_id_1_title')->default('')->comment('业务员1名称');
  1004. $table->bigInteger('employee_id_1')->default(0)->comment('业务员1 ID');
  1005. $table->string('employee_id_2_title')->default('')->comment('上级管理人员名称');
  1006. $table->bigInteger('employee_id_2')->default(0)->comment('上级管理人员ID');
  1007. $table->string('customer_code')->default('')->comment('客户编码');
  1008. $table->string('customer_title')->default('')->comment('客户名称');
  1009. $table->decimal('customer_store_price', 10, 2)->default(0)->comment('客户卸货费单价');
  1010. $table->string('product_code')->default('')->comment('产品编码');
  1011. $table->string('product_title')->default('')->comment('产品名称');
  1012. $table->string('product_size')->default('')->comment('产品规格');
  1013. $table->decimal('product_box_size', 10, 2)->default(0)->comment('装箱数');
  1014. $table->decimal('product_weight', 10, 3)->default(0)->comment('单件重量(kg)');
  1015. $table->decimal('product_store_price', 10, 2)->default(0)->comment('门店卸货费单价');
  1016. $table->decimal('product_store_price2', 10, 2)->default(0)->comment('到货装卸费单价');
  1017. $table->string('product_category')->default('')->comment('货类');
  1018. $table->string('unit')->default('')->comment('单位');
  1019. $table->decimal('quantity', 12, 3)->default(0)->comment('数量');
  1020. $table->decimal('price_3', 12, 2)->default(0)->comment('含税单价');
  1021. $table->decimal('price_3_total', 14, 2)->default(0)->comment('含税金额');
  1022. $table->bigInteger('id_detail')->default(0)->comment('明细ID');
  1023. $table->boolean('is_present')->default(false)->comment('是否赠品');
  1024. $table->string('mark')->default('')->comment('订单备注');
  1025. $table->string('item_mark')->default('')->comment('明细备注');
  1026. $table->bigInteger('warehouse_id')->default(0)->comment('仓库ID');
  1027. $table->string('warehouse_name')->default('')->comment('仓库名称');
  1028. $table->bigInteger('business_type_id')->default(0)->comment('业务类型ID');
  1029. $table->string('business_type_title')->default('')->comment('业务类型名称');
  1030. $table->string('address')->default('')->comment('送货地址');
  1031. $table->string('area_hs')->default('')->comment('区域');
  1032. $table->string('delivery_mode')->default('')->comment('配送方式');
  1033. $table->decimal('sl_fee', 10, 2)->default(0)->comment('上楼费');
  1034. // 新增的计算字段
  1035. $table->integer('xs')->default(0)->comment('箱数');
  1036. $table->decimal('weight', 12, 4)->default(0)->comment('总重量(kg)');
  1037. $table->tinyInteger('area_range')->default(1)->comment('运价区间 (1: <5kg, 2: >=5kg)');
  1038. $table->decimal('freight_unit_price', 10, 2)->default(0)->comment('配送费单价');
  1039. $table->decimal('freight_amount', 12, 4)->default(0)->comment('配送费金额');
  1040. $table->decimal('js_single_amount', 12, 4)->default(0)->comment('结算金额');
  1041. $table->decimal('min_freight_amount', 12, 2)->default(0)->comment('地区最低运价');
  1042. $table->decimal('customer_store_zx_fee', 12, 4)->default(0)->comment('门店卸货费');
  1043. $table->decimal('dh_fee', 12, 4)->default(0)->comment('到货装卸费');
  1044. });
  1045. }
  1046. }
  1047. private function getFreightData($data){
  1048. //写入临时表
  1049. try {
  1050. $table = $this->table_3;
  1051. $limit = 500;
  1052. $lastId = 0;
  1053. do {
  1054. $rows = $this->databaseService->table('SA_SaleDelivery_b as sd_b')
  1055. ->join('SA_SaleDelivery as sd', 'sd_b.idSaleDeliveryDTO', '=', 'sd.ID')
  1056. ->leftJoin('AA_Partner as pn', 'sd.idcustomer', '=', 'pn.ID') // 客户
  1057. ->leftJoin('AA_Person as ps', 'sd.idclerk', '=', 'ps.ID') // 业务员
  1058. ->leftJoin('AA_Person as ps2', 'pn.idsaleman', '=', 'ps2.ID')
  1059. ->leftJoin('AA_Inventory as it', 'sd_b.idinventory', '=', 'it.ID')
  1060. ->leftJoin('AA_Unit as ui', 'sd_b.idbaseunit', '=', 'ui.ID')
  1061. ->leftJoin('AA_Warehouse as wa', 'sd_b.idwarehouse', '=', 'wa.id')
  1062. ->leftJoin('AA_Busitype as bs', 'sd.idbusinesstype', '=', 'bs.id')
  1063. ->where('sd.voucherdate', '>=', $data['start_time'])
  1064. ->where('sd.voucherdate', '<=', $data['end_time'])
  1065. ->where('sd.voucherState', '=', 189) //181 未审核 189 已审核
  1066. ->where('sd_b.ID', '>', $lastId) // 用真实字段
  1067. ->orderBy('sd_b.ID')
  1068. ->limit($limit)
  1069. ->selectRaw("
  1070. COALESCE(sd.ID, 0) as order_id,
  1071. COALESCE(sd.code, '') as order_number,
  1072. sd.voucherdate as order_time,
  1073. sd.voucherState as order_state,
  1074. COALESCE(ps.name, '') as employee_id_1_title,
  1075. COALESCE(sd.idclerk, 0) as employee_id_1,
  1076. COALESCE(ps2.name, '') as employee_id_2_title,
  1077. COALESCE(pn.idsaleman, 0) as employee_id_2,
  1078. COALESCE(pn.code, '') as customer_code,
  1079. COALESCE(pn.name, '') as customer_title,
  1080. COALESCE(pn.priuserdefdecm3, 0) as customer_store_price,
  1081. COALESCE(it.code, '') as product_code,
  1082. COALESCE(it.name, '') as product_title,
  1083. COALESCE(it.specification, '') as product_size,
  1084. COALESCE(it.priuserdefdecm1, 0) as product_box_size,
  1085. COALESCE(it.priuserdefdecm3, 0) as product_weight,
  1086. COALESCE(it.priuserdefdecm10, 0) as product_store_price,
  1087. COALESCE(it.priuserdefdecm11, 0) as product_store_price2,
  1088. COALESCE(it.priuserdefnvc5, '') as product_category,
  1089. COALESCE(ui.name, '') as unit,
  1090. COALESCE(sd_b.quantity, 0) as quantity,
  1091. COALESCE(sd_b.taxPrice, 0) as price_3,
  1092. COALESCE(sd_b.taxAmount, 0) as price_3_total,
  1093. COALESCE(sd_b.ID, 0) as id_detail,
  1094. COALESCE(sd_b.isPresent, 0) as is_present,
  1095. COALESCE(sd_b.DetailMemo, '') as item_mark,
  1096. COALESCE(sd.memo, '') as mark,
  1097. sd_b.idwarehouse as warehouse_id,
  1098. COALESCE(wa.name, '') as warehouse_name,
  1099. sd.idbusinesstype as business_type_id,
  1100. COALESCE(bs.name , '') as business_type_title,
  1101. COALESCE(sd.address , '') as address,
  1102. COALESCE(sd.priuserdefnvc2 , '') as area_hs,
  1103. COALESCE(sd.deliveryMode , 0) as delivery_mode,
  1104. COALESCE(sd.priuserdefdecm5 , 0) as sl_fee
  1105. ")
  1106. ->get();
  1107. if ($rows->isEmpty()) break;
  1108. $dataArray = Collect($rows)->map(function ($object) {
  1109. return (array)$object;
  1110. })->toArray();
  1111. $freight = Freight::where('del_time',0)
  1112. ->whereIn('region',array_column($dataArray,'area_hs'))
  1113. ->select('region','one_and_five','greater_than_five','min_freight_fee')
  1114. ->get()->toArray();
  1115. $freight_map = array_column($freight,null,'region');
  1116. //组织数据
  1117. foreach ($dataArray as $key => $value) {
  1118. $quantity = abs($value['quantity']);
  1119. //箱数
  1120. $xs = 0;
  1121. if(! empty($value['product_box_size']) && is_numeric($value['product_box_size']) && $value['product_box_size'] > 0) $xs = ceil($quantity / $value['product_box_size']);
  1122. $dataArray[$key]['xs'] = $xs;
  1123. //总重量
  1124. $weight = 0;
  1125. if(! empty($value['product_weight']) && is_numeric($value['product_weight']) && $value['product_weight'] > 0) $weight = bcdiv(bcmul($xs, $value['product_weight']),1000,4);
  1126. $dataArray[$key]['weight'] = $weight;
  1127. //运价区间
  1128. $area_range = 1;
  1129. if($weight >= 5) $area_range = 2;
  1130. $dataArray[$key]['area_range'] = $area_range;
  1131. //配送费单价
  1132. $freight = $min_freight = 0;
  1133. if(isset($freight_map[$value['area_hs']])) {
  1134. $tmp = $freight_map[$value['area_hs']];
  1135. if($area_range == 1){
  1136. $freight = $tmp['one_and_five'];
  1137. }else{
  1138. $freight = $tmp['greater_than_five'];
  1139. }
  1140. $min_freight = $tmp['min_freight_fee'];
  1141. }
  1142. $dataArray[$key]['freight_unit_price'] = $freight;
  1143. //地区最低运价
  1144. $dataArray[$key]['min_freight_amount'] = $min_freight;
  1145. //纯自提不计算-------------------------------------------------------
  1146. if($value['delivery_mode'] == FreightFee::deliveryModeNormal){
  1147. //配送费金额
  1148. $dataArray[$key]['freight_amount'] = 0;
  1149. //结算金额 记录的是每一条的
  1150. $dataArray[$key]['js_single_amount'] = 0;
  1151. //门店卸货费
  1152. $dataArray[$key]['customer_store_zx_fee'] = 0;
  1153. //到货装卸费
  1154. $dataArray[$key]['dh_fee'] = 0;
  1155. }else{
  1156. //配送费金额
  1157. $freight_amount = bcmul($weight, $freight,4);
  1158. $dataArray[$key]['freight_amount'] = $freight_amount;
  1159. //结算金额 记录的是每一条的
  1160. $dataArray[$key]['js_single_amount'] = $freight_amount;
  1161. //门店卸货费
  1162. $customer_store_price = 0;
  1163. if(! empty($value['customer_store_price']) && is_numeric($value['customer_store_price']) && $value['customer_store_price'] > 0){
  1164. $customer_store_price = bcmul($value['customer_store_price'], $xs,4);
  1165. }else{
  1166. if(! empty($value['product_store_price']) && is_numeric($value['product_store_price']) && $value['product_store_price'] > 0){
  1167. $customer_store_price = bcmul($value['product_store_price'], $xs,4);
  1168. }
  1169. }
  1170. $dataArray[$key]['customer_store_zx_fee'] = $customer_store_price;
  1171. //到货装卸费
  1172. $product_store_price2 = 0;
  1173. if(! empty($value['product_store_price2']) && is_numeric($value['product_store_price2'])) $product_store_price2 = $value['product_store_price2'];
  1174. if(! empty($value['product_category']) && $value['product_category'] == "礼盒"){
  1175. $dh_fee = bcmul($xs, $product_store_price2,4);
  1176. }else{
  1177. $dh_fee = bcmul($weight, $product_store_price2,4);
  1178. }
  1179. if($value['business_type_id'] == FreightFee::businessTypeReturn) $dh_fee = bcmul($dh_fee,2,4);
  1180. $dataArray[$key]['dh_fee'] = $dh_fee;
  1181. }
  1182. }
  1183. DB::table($table)->insert($dataArray);
  1184. // 更新 lastId 继续下一批
  1185. $lastId = end($dataArray)['id_detail'] ?? $lastId;
  1186. } while (count($rows) === $limit);
  1187. }catch (\Throwable $exception){
  1188. return [false, "运费获取销货单数据异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  1189. }
  1190. return [true, ''];
  1191. }
  1192. private function updateFreightFeeFromMine($data){
  1193. try {
  1194. $start_timeStamp = $data['start_timeStamp'];
  1195. $end_timeStamp = $data['end_timeStamp'];
  1196. $tmpTable = $this->table_3;
  1197. $time = time();
  1198. $ergs = $data;
  1199. DB::transaction(function () use ($start_timeStamp, $end_timeStamp, $tmpTable,$time, $ergs) {
  1200. // 1. 先软删除旧数据(你已有)
  1201. FreightFee::where('del_time', 0)
  1202. ->where('order_time', '>=', $start_timeStamp)
  1203. ->where('order_time', '<=', $end_timeStamp)
  1204. ->update(['del_time' => $time]);
  1205. // 2. 分批从临时表插入新数据
  1206. $batchSize = 500;
  1207. $lastId = 0;
  1208. do {
  1209. $chunk = DB::table($tmpTable)
  1210. ->where('id', '>', $lastId)
  1211. ->orderBy('id')
  1212. ->limit($batchSize)
  1213. ->get();
  1214. if ($chunk->isEmpty()) {
  1215. break;
  1216. }
  1217. $data = $chunk->map(function ($item) use($time){
  1218. return [
  1219. // 基础字段(按你给的顺序)
  1220. 'order_id' => $item->order_id ?? 0,
  1221. 'order_number' => $item->order_number ?? '',
  1222. 'order_time' => $item->order_time ? strtotime($item->order_time) : 0,
  1223. 'order_state' => $item->order_state ?? 0,
  1224. 'employee_id_1_title' => $item->employee_id_1_title ?? '',
  1225. 'employee_id_1' => $item->employee_id_1 ?? 0,
  1226. 'employee_id_2_title' => $item->employee_id_2_title ?? '',
  1227. 'employee_id_2' => $item->employee_id_2 ?? 0,
  1228. 'customer_code' => $item->customer_code ?? '',
  1229. 'customer_title' => $item->customer_title ?? '',
  1230. 'customer_store_price' => $item->customer_store_price ?? 0,
  1231. 'product_code' => $item->product_code ?? '',
  1232. 'product_title' => $item->product_title ?? '',
  1233. 'product_size' => $item->product_size ?? '',
  1234. 'product_box_size' => $item->product_box_size ?? 0,
  1235. 'product_weight' => $item->product_weight ?? 0,
  1236. 'product_store_price' => $item->product_store_price ?? 0,
  1237. 'product_store_price2' => $item->product_store_price2 ?? 0,
  1238. 'product_category' => $item->product_category ?? '',
  1239. 'unit' => $item->unit ?? '',
  1240. 'quantity' => $item->quantity ?? 0,
  1241. 'price_3' => $item->price_3 ?? 0,
  1242. 'price_3_total' => $item->price_3_total ?? 0,
  1243. 'id_detail' => $item->id_detail ?? 0,
  1244. 'is_present' => $item->is_present ?? '',
  1245. 'mark' => $item->mark ?? '',
  1246. 'item_mark' => $item->item_mark ?? '',
  1247. 'warehouse_id' => $item->warehouse_id ?? 0,
  1248. 'warehouse_name' => $item->warehouse_name ?? '',
  1249. 'business_type_id' => $item->business_type_id ?? 0,
  1250. 'business_type_title' => $item->business_type_title ?? '',
  1251. 'address' => $item->address ?? '',
  1252. 'area_hs' => $item->area_hs ?? '',
  1253. 'delivery_mode' => $item->delivery_mode ?? 0,
  1254. 'sl_fee' => $item->sl_fee ?? 0,
  1255. 'xs' => $item->xs,
  1256. 'weight' => $item->weight ?? 0,
  1257. 'area_range' => $item->area_range ?? 0,
  1258. 'freight_unit_price' => $item->freight_unit_price ?? 0,
  1259. 'freight_amount' => $item->freight_amount ?? 0,
  1260. 'js_single_amount' => $item->js_single_amount ?? 0,
  1261. 'min_freight_amount' => $item->min_freight_amount ?? 0,
  1262. 'customer_store_zx_fee' => $item->customer_store_zx_fee ?? 0,
  1263. 'dh_fee' => $item->dh_fee ?? 0,
  1264. 'crt_time' => $time,
  1265. ];
  1266. })->toArray();
  1267. // 每批单独插入(可选:加小事务)
  1268. FreightFee::insert($data);
  1269. // 更新 lastId
  1270. $lastId = $chunk->last()->id;
  1271. } while ($chunk->count() == $batchSize);
  1272. });
  1273. }catch (\Throwable $exception){
  1274. return [false, "单据明细同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  1275. }
  1276. return [true, ''];
  1277. }
  1278. public function synItemRoad($data, $user){
  1279. if(empty($data['crt_time'][0]) || empty($data['crt_time'][1])) return [false, '同步时间不能为空'];
  1280. $start_time = strtotime($data['crt_time'][0] . "-01");
  1281. $end_time = strtotime(date('Y-m-t', strtotime($data['crt_time'][1] . '-01')) . ' 00:00:00');
  1282. list($bool, $bool_msg) = $this->isWithinMonths($start_time, $end_time);
  1283. if(! $bool) return [false, $bool_msg];
  1284. $data['start_timeStamp'] = $start_time;
  1285. $data['end_timeStamp'] = $end_time;
  1286. $start = date('Y-m-d H:i:s.000', $start_time);
  1287. $end = date('Y-m-d H:i:s.000', $end_time);
  1288. $data['start_time'] = $start;
  1289. $data['end_time'] = $end;
  1290. $data['operation_time'] = time();
  1291. $data['type'] = 7;
  1292. // list($status, $msg) = $this->synItemRoadMy($data, $user);dd($status, $msg);
  1293. list($status,$msg) = $this->limitingSendRequest($this->table_4);
  1294. if(! $status) return [false, '统计同步正在后台运行,请稍后'];
  1295. //队列
  1296. ProcessDataJob::dispatch($data, $user, 4)->onQueue(RevenueCost::job4);
  1297. return [true, '统计同步已进入后台任务'];
  1298. }
  1299. private function createTmpTable4(){
  1300. $table = $this->table_4;
  1301. if (! Schema::hasTable($table)) {
  1302. Schema::create($table, function (Blueprint $table) {
  1303. $table->bigIncrements('id');
  1304. // 订单基础信息
  1305. $table->bigInteger('order_id')->default(0)->comment('收款单ID(rp.ID)');
  1306. $table->string('order_number')->default('')->comment('收款单编号(rp.code)');
  1307. $table->integer('order_time')->default(0)->comment('单据时间(时间戳)');
  1308. $table->integer('order_state')->default(0)->comment('订单状态');
  1309. $table->integer('order_type')->default(0)->comment('订单分类标识');
  1310. // 渠道/分销相关
  1311. $table->string('channel_finance')->default('')->comment('渠道财务(rp.pubuserdefnvc11)');
  1312. $table->string('channel_details')->default('')->comment('渠道明细(rp.pubuserdefnvc12)');
  1313. $table->string('channel_details_fp')->default('')->comment('发票渠道明细(si.pubuserdefnvc12)');
  1314. // 客户信息
  1315. $table->string('customer_code')->default('')->comment('结算客户编码');
  1316. $table->string('customer_title')->default('')->comment('结算客户名称');
  1317. // 人员信息
  1318. $table->bigInteger('employee_id_1')->default(0)->comment('业务员ID');
  1319. $table->string('employee_id_1_title')->default('')->comment('业务员名称');
  1320. $table->bigInteger('employee_id_2')->default(0)->comment('上级管理人员ID');
  1321. $table->string('employee_id_2_title')->default('')->comment('上级管理人员名称');
  1322. // 产品信息 (仅限 idvouchertype = 20)
  1323. $table->string('product_code')->default('')->comment('产品编码');
  1324. $table->string('product_title')->default('')->comment('产品名称');
  1325. $table->decimal('quantity', 14, 3)->default(0)->comment('发票数量');
  1326. // 收入/价格相关
  1327. $table->decimal('price_1', 14, 4)->default(0)->comment('含税单价(taxPrice)');
  1328. $table->decimal('price_1_total', 14, 2)->default(0)->comment('含税金额(taxAmount)');
  1329. $table->decimal('payment_amount', 14, 2)->default(0)->comment('明细行的收款金额');
  1330. // 成本相关 (计算得出)
  1331. $table->decimal('price_4', 14, 4)->default(0)->comment('业务成本单价');
  1332. $table->decimal('price_4_total', 14, 2)->default(0)->comment('业务成本总额');
  1333. // 关联追溯字段
  1334. $table->bigInteger('id_detail')->default(0)->comment('收款明细ID(rp_b.ID)');
  1335. $table->bigInteger('id_detail_upstream')->default(0)->comment('上游单据明细ID(voucherDetailID)');
  1336. $table->string('order_number_upstream')->default('')->comment('上游单据编号(voucherCode)');
  1337. $table->integer('voucher_type')->default(0)->comment('单据类型(idvouchertype)');
  1338. $table->string('is_kh')->default('0')->comment('是否计入考核(sd.priuserdefnvc4)');
  1339. });
  1340. }
  1341. }
  1342. private function createTmpTable5(){
  1343. $table = $this->table_5;
  1344. if (! Schema::hasTable($table)) {
  1345. Schema::create($table, function (Blueprint $table) {
  1346. $table->bigIncrements('id');
  1347. // 基础信息
  1348. $table->bigInteger('order_id')->default(0)->comment('费用单ID(cs.ID)');
  1349. $table->string('order_number')->default('')->comment('费用单编号(cs.code)');
  1350. $table->integer('order_time')->default(0)->comment('单据时间(时间戳)');
  1351. $table->integer('order_type')->default(0)->comment('订单分类标识(1 费用单 2 其他出库单)');
  1352. $table->string('ck_type')->default("")->comment('出库单出库类别');
  1353. $table->integer('employee_id_1')->default(0)->comment('业务员id');
  1354. // 维度信息
  1355. $table->string('channel_details')->default('')->comment('渠道明细(cs.pubuserdefnvc12)');
  1356. $table->string('fy_code')->default('')->comment('费用项目编码(ae.code)');
  1357. // 金额信息
  1358. $table->decimal('taxamount', 14, 2)->default(0)->comment('含税金额(cs_b.taxamount)');
  1359. // 追溯信息
  1360. $table->bigInteger('id_detail')->default(0)->comment('费用明细行ID(cs_b.ID)');
  1361. });
  1362. }
  1363. }
  1364. public function synItemRoadMy($data, $user){
  1365. //收入
  1366. list($status, $msg) = $this->synReceipt($data,$user);
  1367. if(! $status) return [false, $msg];
  1368. //成本
  1369. list($status, $msg) = $this->synSaleCost($data,$user);
  1370. if(! $status) return [false, $msg];
  1371. //汇总项目报表
  1372. list($status, $msg) = $this->saveResult($data,$user);
  1373. if(! $status) return [false, $msg];
  1374. //清理临时表 如果内容不为空
  1375. $this->clearTmpTable(4);
  1376. //释放redis
  1377. $this->delTableKey(4);
  1378. return [true, ''];
  1379. }
  1380. private function synReceipt($data, $user){
  1381. //创建临时表 如果不存在
  1382. $this->createTmpTable4();
  1383. //清理临时表 如果内容不为空
  1384. $this->clearTmpTable(4);
  1385. try{
  1386. $table = $this->table_4;
  1387. $limit = 500;
  1388. $lastId = 0;
  1389. do {
  1390. $rows = $this->databaseService->table('ARAP_ReceivePayment_b as rp_b')
  1391. ->join('ARAP_ReceivePayment as rp', 'rp_b.idArapReceivePaymentDTO', '=', 'rp.ID')
  1392. // 发票子表关联(仅限 idvouchertype = 20)
  1393. ->leftJoin('SA_SaleInvoice_b as si_b', function ($join) {
  1394. $join->on('rp_b.voucherDetailID', '=', 'si_b.ID')
  1395. ->where('rp_b.idvouchertype', '=', 20);
  1396. })
  1397. ->leftJoin('SA_SaleInvoice as si', function ($join) {
  1398. $join->on('si_b.idSaleInvoiceDTO', '=', 'si.ID')
  1399. ->where('rp_b.idvouchertype', '=', 20);
  1400. })
  1401. ->leftJoin('SA_SaleDelivery_b as sd_b', function ($join) {
  1402. $join->on('si_b.sourceVoucherDetailId', '=', 'sd_b.ID')
  1403. ->where('rp_b.idvouchertype', '=', 20);
  1404. })
  1405. ->leftJoin('SA_SaleDelivery as sd', function ($join) {
  1406. $join->on('sd_b.idSaleDeliveryDTO', '=', 'sd.ID')
  1407. ->where('rp_b.idvouchertype', '=', 20);
  1408. })
  1409. ->leftJoin('AA_Inventory as it', 'sd_b.idinventory', '=', 'it.ID')
  1410. ->leftJoin('AA_Partner as pn', 'si.idsettlecustomer', '=', 'pn.ID') //结算客户
  1411. ->leftJoin('AA_Person as ps', 'rp.idperson', '=', 'ps.ID')
  1412. ->leftJoin('AA_Person as ps2', 'pn.idsaleman', '=', 'ps2.ID') // 结算客户的上级管理人员
  1413. ->where('rp.voucherdate','>=',$data['start_time'])
  1414. ->where('rp.voucherdate','<=',$data['end_time'])
  1415. // ->where('priuserdefnvc4','=', 1) //.. 不计入考核 todo
  1416. ->where('rp.isReceiveFlag','=', 1)
  1417. ->where('rp_b.ID', '>', $lastId)
  1418. ->orderBy('rp_b.ID')
  1419. ->limit($limit)
  1420. ->selectRaw("
  1421. COALESCE(rp.ID, 0) as order_id,
  1422. COALESCE(rp.code, '') as order_number,
  1423. rp.voucherdate as order_time,
  1424. rp.voucherstate as order_state,
  1425. COALESCE(rp.pubuserdefnvc11, '') as channel_finance,
  1426. COALESCE(rp.pubuserdefnvc12, '') as channel_details,
  1427. COALESCE(si.pubuserdefnvc12, '') as channel_details_fp,
  1428. COALESCE(pn.code, '') as customer_code,
  1429. COALESCE(pn.name, '') as customer_title,
  1430. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(it.code, '') ELSE '' END as product_code,
  1431. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(it.name, '') ELSE '' END as product_title,
  1432. COALESCE(rp.idperson, 0) as employee_id_1,
  1433. COALESCE(ps.name, '') as employee_id_1_title,
  1434. COALESCE(pn.idsaleman, 0) as employee_id_2,
  1435. COALESCE(ps2.name, '') as employee_id_2_title,
  1436. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(si_b.quantity, 0) ELSE 0 END as quantity,
  1437. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(si_b.taxPrice, 0) ELSE 0 END as price_1,
  1438. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(si_b.taxAmount, 0) ELSE 0 END as price_1_total,
  1439. COALESCE(rp_b.origCurrentAmount, 0) as payment_amount,
  1440. COALESCE(rp_b.ID, 0) as id_detail,
  1441. COALESCE(rp_b.voucherDetailID, 0) as id_detail_upstream,
  1442. COALESCE(rp_b.voucherCode, '') as order_number_upstream,
  1443. rp_b.idvouchertype as voucher_type,
  1444. CASE WHEN rp_b.idvouchertype = 20 THEN COALESCE(sd.priuserdefnvc4, '') ELSE '' END as is_kh
  1445. ")
  1446. ->get();
  1447. if ($rows->isEmpty()) break;
  1448. $dataArray = Collect($rows)->map(function ($object) {
  1449. return (array)$object;
  1450. })->toArray();
  1451. //存货档案业务成本
  1452. $product_map = Product::where('del_time',0)
  1453. ->whereIn('code', array_unique(array_column($dataArray,'product_code')))
  1454. ->pluck('business_cost','code')
  1455. ->all();
  1456. //组织数据
  1457. foreach ($dataArray as $key => $value){
  1458. $p_tmp = $product_map[$value['product_code']] ?? 0;
  1459. $dataArray[$key]['order_type'] = RevenueCost::ORDER_THREE;
  1460. $dataArray[$key]['order_time'] = strtotime($value['order_time']);
  1461. //业务成本单价和金额
  1462. $business_cost = $p_tmp ?? 0;
  1463. $dataArray[$key]['price_4'] = $business_cost;
  1464. $price_4_total = bcmul($business_cost, $value['quantity'],2);
  1465. $dataArray[$key]['price_4_total'] = $price_4_total;
  1466. }
  1467. DB::table($table)->insert($dataArray);
  1468. // 更新 lastId 继续下一批
  1469. $lastId = end($dataArray)['id_detail'] ?? $lastId;
  1470. } while (count($rows) === $limit);
  1471. }catch (\Throwable $exception){
  1472. return [false, "收入同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  1473. }
  1474. return [true, ''];
  1475. }
  1476. private function synSaleCost($data, $user){
  1477. //创建临时表 如果不存在
  1478. $this->createTmpTable5();
  1479. //清理临时表 如果内容不为空
  1480. // $this->clearTmpTable(5);
  1481. try{
  1482. $table = $this->table_5;
  1483. $limit = 500;
  1484. $lastId = 0;
  1485. do {
  1486. $rows = $this->databaseService->table('CS_ExpenseVoucher_b as cs_b')
  1487. ->join('CS_ExpenseVoucher as cs', 'cs_b.idExpenseVoucherDTO', '=', 'cs.ID')
  1488. ->leftJoin('AA_ExpenseItem as ae', 'ae.id', '=', 'cs_b.idexpenseitem')
  1489. ->where('cs.voucherdate','>=',$data['start_time'])
  1490. ->where('cs.voucherdate','<=',$data['end_time'])
  1491. ->where('cs_b.ID', '>', $lastId)
  1492. ->orderBy('cs_b.ID')
  1493. ->limit($limit)
  1494. ->selectRaw("
  1495. 1 as order_type,
  1496. COALESCE(cs.ID, 0) as order_id,
  1497. COALESCE(cs.code, '') as order_number,
  1498. cs.voucherdate as order_time,
  1499. cs.idclerk as employee_id_1,
  1500. COALESCE(cs.pubuserdefnvc12, '') as channel_details,
  1501. COALESCE(ae.code, '') as fy_code,
  1502. COALESCE(cs_b.taxamount, 0) as taxamount,
  1503. COALESCE(cs_b.ID, 0) as id_detail
  1504. ")
  1505. ->get();
  1506. if ($rows->isEmpty()) break;
  1507. $dataArray = Collect($rows)->map(function ($object) {
  1508. return (array)$object;
  1509. })->toArray();
  1510. foreach ($dataArray as $key => $value){
  1511. $dataArray[$key]['order_time'] = strtotime($value['order_time']);
  1512. }
  1513. DB::table($table)->insert($dataArray);
  1514. // 更新 lastId 继续下一批
  1515. $lastId = end($dataArray)['id_detail'] ?? $lastId;
  1516. } while (count($rows) === $limit);
  1517. }catch (\Throwable $exception){
  1518. return [false, "费用同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  1519. }
  1520. try{
  1521. $table = $this->table_5;
  1522. $limit = 500;
  1523. $lastId = 0;
  1524. do {
  1525. $rows = $this->databaseService->table('ST_RDRecord_b as st_b')
  1526. ->join('ST_RDRecord as st', 'st_b.idRDRecordDTO', '=', 'st.ID')
  1527. ->where('st.voucherdate','>=',$data['start_time'])
  1528. ->where('st.voucherdate','<=',$data['end_time'])
  1529. ->where('st.idvouchertype', 30)
  1530. ->whereIn('st.idbusitype',[20048,60,20049]) //20049 客情出库 60 赠品出库 20048 员工福利
  1531. ->where('st_b.ID', '>', $lastId)
  1532. ->orderBy('st_b.ID')
  1533. ->limit($limit)
  1534. ->selectRaw("
  1535. 2 as order_type,
  1536. COALESCE(st.ID, 0) as order_id,
  1537. COALESCE(st.code, '') as order_number,
  1538. st.voucherdate as order_time,
  1539. st.idclerk as employee_id_1,
  1540. COALESCE(st.pubuserdefnvc12, '') as channel_details,
  1541. COALESCE(st_b.amount, 0) as taxamount,
  1542. COALESCE(st_b.ID, 0) as id_detail,
  1543. st.idbusitype as ck_type
  1544. ")->get();
  1545. if ($rows->isEmpty()) break;
  1546. $dataArray = Collect($rows)->map(function ($object) {
  1547. return (array)$object;
  1548. })->toArray();
  1549. foreach ($dataArray as $key => $value){
  1550. $dataArray[$key]['order_time'] = strtotime($value['order_time']);
  1551. }
  1552. DB::table($table)->insert($dataArray);
  1553. // 更新 lastId 继续下一批
  1554. $lastId = end($dataArray)['id_detail'] ?? $lastId;
  1555. } while (count($rows) === $limit);
  1556. }catch (\Throwable $exception){
  1557. return [false, "其他出库同步异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  1558. }
  1559. return [true, ''];
  1560. }
  1561. private function saveResult($data, $user){
  1562. // 初始化汇总数组------报表一
  1563. $paymentSummary = [];
  1564. $costSummary = [];
  1565. $costSummary2 = [];
  1566. //报表二
  1567. $paymentSummary_road = [];
  1568. $costSummary_road = [];
  1569. $costSummary2_road = [];
  1570. $map = [
  1571. 2 => [
  1572. 'type' => 1,
  1573. 'channel_details' => ['通路'],
  1574. ],
  1575. 3 => [
  1576. 'type' => 2,
  1577. 'channel_details' => ['通路'],
  1578. ],
  1579. 23 => [
  1580. 'type' => 3,
  1581. 'channel_details' => ['通路'],
  1582. ],
  1583. 7 => [
  1584. 'type' => 4,
  1585. 'channel_details' => ['通路','大卖场'],
  1586. ],
  1587. 8 => [
  1588. 'type' => 4,
  1589. 'channel_details' => ['通路','大卖场'],
  1590. ],
  1591. 48 => [
  1592. 'type' => 4,
  1593. 'channel_details' => ['通路','大卖场'],
  1594. ],
  1595. ];
  1596. try{
  1597. $limit = 500;
  1598. $lastId = 0;
  1599. do {
  1600. // 分批查询:只查 is_kh 不为空的数据
  1601. $rows = DB::table('tmp_item_road')
  1602. ->where('id', '>', $lastId)
  1603. ->orderBy('id')
  1604. ->limit($limit)
  1605. ->select([
  1606. 'id',
  1607. 'order_time',
  1608. 'channel_details',
  1609. 'payment_amount',
  1610. 'price_4_total',
  1611. 'is_kh',
  1612. 'employee_id_2'
  1613. ])
  1614. ->get();
  1615. if ($rows->isEmpty()) {
  1616. break;
  1617. }
  1618. // 聚合到汇总数组
  1619. foreach ($rows as $row) {
  1620. $order_time = $row->order_time;
  1621. $month = strtotime(date("Y-m-01", $order_time));
  1622. $channel = $row->channel_details ?? '';
  1623. $t = $map[$row->employee_id_2] ?? [];
  1624. //收款销售收入
  1625. if (! $row->is_kh) {
  1626. if (!isset($paymentSummary[$month][$channel])) {
  1627. $paymentSummary[$month][$channel] = $row->payment_amount;
  1628. }else{
  1629. $paymentSummary[$month][$channel] = bcadd(
  1630. $paymentSummary[$month][$channel],
  1631. $row->payment_amount,
  1632. 3
  1633. );
  1634. }
  1635. if(! empty($t)){
  1636. $type = $t['type'];
  1637. $c_t = $t['channel_details'];
  1638. if(in_array($channel, $c_t)){
  1639. if (!isset($paymentSummary_road[$month][$type])) {
  1640. $paymentSummary_road[$month][$type] = $row->payment_amount;
  1641. }else{
  1642. $paymentSummary_road[$month][$type] = bcadd(
  1643. $paymentSummary_road[$month][$type],
  1644. $row->payment_amount,
  1645. 3
  1646. );
  1647. }
  1648. }
  1649. }
  1650. }
  1651. //成本
  1652. if (!isset($costSummary[$month][$channel])) {
  1653. $costSummary[$month][$channel] = $row->price_4_total;
  1654. }else{
  1655. $costSummary[$month][$channel] = bcadd(
  1656. $costSummary[$month][$channel],
  1657. $row->price_4_total,
  1658. 3
  1659. );
  1660. }
  1661. if(! empty($t)){
  1662. $type = $t['type'];
  1663. $c_t = $t['channel_details'];
  1664. if(in_array($channel, $c_t)){
  1665. if (!isset($costSummary_road[$month][$type])) {
  1666. $costSummary_road[$month][$type] = $row->price_4_total;
  1667. }else{
  1668. $costSummary_road[$month][$type] = bcadd(
  1669. $costSummary_road[$month][$type],
  1670. $row->price_4_total,
  1671. 3
  1672. );
  1673. }
  1674. }
  1675. }
  1676. }
  1677. // 更新 lastId
  1678. $lastId = $rows->last()->id;
  1679. } while ($rows->count() === $limit);
  1680. $limit = 500;
  1681. $lastId = 0;
  1682. do {
  1683. $rows = DB::table('tmp_item_cost')
  1684. ->where('id', '>', $lastId)
  1685. ->orderBy('id')
  1686. ->limit($limit)
  1687. ->select([
  1688. 'id',
  1689. 'order_time',
  1690. 'channel_details',
  1691. 'ck_type',
  1692. 'fy_code',
  1693. 'taxamount',
  1694. 'employee_id_1'
  1695. ])
  1696. ->get();
  1697. if ($rows->isEmpty()) {
  1698. break;
  1699. }
  1700. foreach ($rows as $row) {
  1701. $order_time = $row->order_time;
  1702. $month = strtotime(date("Y-m-01", $order_time));
  1703. $channel = $row->channel_details ?? '';
  1704. $amount = $row->taxamount;
  1705. $t = $map[$row->employee_id_1] ?? [];
  1706. if($row->fy_code == 7004){
  1707. if (! isset($costSummary2[$month][$channel]['settle_amount'])) {
  1708. $costSummary2[$month][$channel]['settle_amount'] = $amount;
  1709. }else{
  1710. $costSummary2[$month][$channel]['settle_amount'] = bcadd(
  1711. $costSummary2[$month][$channel]['settle_amount'],
  1712. $amount,
  1713. 3
  1714. );
  1715. }
  1716. if(! empty($t)){
  1717. $type = $t['type'];
  1718. $c_t = $t['channel_details'];
  1719. if(in_array($channel, $c_t)){
  1720. if (!isset($costSummary2_road[$month][$type])) {
  1721. $costSummary2_road[$month][$type]['settle_amount'] = $amount;
  1722. }else{
  1723. $costSummary2_road[$month][$type]['settle_amount'] = bcadd(
  1724. $costSummary2_road[$month][$type]['settle_amount'],
  1725. $amount,
  1726. 3
  1727. );
  1728. }
  1729. }
  1730. }
  1731. }
  1732. $gl_amount = bcmul($amount, 0.05,3);
  1733. if (! isset($costSummary2[$month][$channel]['gl_amount'])) {
  1734. $costSummary2[$month][$channel]['gl_amount'] = $gl_amount;
  1735. }else{
  1736. $costSummary2[$month][$channel]['gl_amount'] = bcadd(
  1737. $costSummary2[$month][$channel]['gl_amount'],
  1738. $gl_amount,
  1739. 3
  1740. );
  1741. }
  1742. if(! empty($t)){
  1743. $type = $t['type'];
  1744. $c_t = $t['channel_details'];
  1745. if(in_array($channel, $c_t)){
  1746. if (!isset($costSummary2_road[$month][$type]['gl_amount'])) {
  1747. $costSummary2_road[$month][$type]['gl_amount'] = $amount;
  1748. }else{
  1749. $costSummary2_road[$month][$type]['gl_amount'] = bcadd(
  1750. $costSummary2_road[$month][$type]['gl_amount'],
  1751. $amount,
  1752. 3
  1753. );
  1754. }
  1755. }
  1756. }
  1757. $wl_amount = bcmul($amount, 2.3,3);
  1758. if (! isset($costSummary2[$month][$channel]['wl_amount'])) {
  1759. $costSummary2[$month][$channel]['wl_amount'] = $wl_amount;
  1760. }else{
  1761. $costSummary2[$month][$channel]['wl_amount'] = bcadd(
  1762. $costSummary2[$month][$channel]['wl_amount'],
  1763. $wl_amount,
  1764. 3
  1765. );
  1766. }
  1767. if(! empty($t)){
  1768. $type = $t['type'];
  1769. $c_t = $t['channel_details'];
  1770. if(in_array($channel, $c_t)){
  1771. if (!isset($costSummary2_road[$month][$type]['wl_amount'])) {
  1772. $costSummary2_road[$month][$type]['wl_amount'] = $amount;
  1773. }else{
  1774. $costSummary2_road[$month][$type]['wl_amount'] = bcadd(
  1775. $costSummary2_road[$month][$type]['wl_amount'],
  1776. $amount,
  1777. 3
  1778. );
  1779. }
  1780. }
  1781. }
  1782. if($row->fy_code == 7005){
  1783. if (! isset($costSummary2[$month][$channel]['ht_amount'])) {
  1784. $costSummary2[$month][$channel]['ht_amount'] = $amount;
  1785. }else{
  1786. $costSummary2[$month][$channel]['ht_amount'] = bcadd(
  1787. $costSummary2[$month][$channel]['ht_amount'],
  1788. $amount,
  1789. 3
  1790. );
  1791. }
  1792. if(! empty($t)){
  1793. $type = $t['type'];
  1794. $c_t = $t['channel_details'];
  1795. if(in_array($channel, $c_t)){
  1796. if (!isset($costSummary2_road[$month][$type]['ht_amount'])) {
  1797. $costSummary2_road[$month][$type]['ht_amount'] = $amount;
  1798. }else{
  1799. $costSummary2_road[$month][$type]['ht_amount'] = bcadd(
  1800. $costSummary2_road[$month][$type]['ht_amount'],
  1801. $amount,
  1802. 3
  1803. );
  1804. }
  1805. }
  1806. }
  1807. }
  1808. if($row->fy_code == 7006){
  1809. if (! isset($costSummary2[$month][$channel]['zk_amount'])) {
  1810. $costSummary2[$month][$channel]['zk_amount'] = $amount;
  1811. }else{
  1812. $costSummary2[$month][$channel]['zk_amount'] = bcadd(
  1813. $costSummary2[$month][$channel]['zk_amount'],
  1814. $amount,
  1815. 3
  1816. );
  1817. }
  1818. if(! empty($t)){
  1819. $type = $t['type'];
  1820. $c_t = $t['channel_details'];
  1821. if(in_array($channel, $c_t)){
  1822. if (!isset($costSummary2_road[$month][$type]['zk_amount'])) {
  1823. $costSummary2_road[$month][$type]['zk_amount'] = $amount;
  1824. }else{
  1825. $costSummary2_road[$month][$type]['zk_amount'] = bcadd(
  1826. $costSummary2_road[$month][$type]['zk_amount'],
  1827. $amount,
  1828. 3
  1829. );
  1830. }
  1831. }
  1832. }
  1833. }
  1834. if($row->fy_code == 7007){
  1835. if (! isset($costSummary2[$month][$channel]['cx_amount'])) {
  1836. $costSummary2[$month][$channel]['cx_amount'] = $amount;
  1837. }else{
  1838. $costSummary2[$month][$channel]['cx_amount'] = bcadd(
  1839. $costSummary2[$month][$channel]['cx_amount'],
  1840. $amount,
  1841. 3
  1842. );
  1843. }
  1844. if(! empty($t)){
  1845. $type = $t['type'];
  1846. $c_t = $t['channel_details'];
  1847. if(in_array($channel, $c_t)){
  1848. if (!isset($costSummary2_road[$month][$type]['cx_amount'])) {
  1849. $costSummary2_road[$month][$type]['cx_amount'] = $amount;
  1850. }else{
  1851. $costSummary2_road[$month][$type]['cx_amount'] = bcadd(
  1852. $costSummary2_road[$month][$type]['cx_amount'],
  1853. $amount,
  1854. 3
  1855. );
  1856. }
  1857. }
  1858. }
  1859. }
  1860. if($row->fy_code == 7013){
  1861. if (! isset($costSummary2[$month][$channel]['tg_amount'])) {
  1862. $costSummary2[$month][$channel]['tg_amount'] = $amount;
  1863. }else{
  1864. $costSummary2[$month][$channel]['tg_amount'] = bcadd(
  1865. $costSummary2[$month][$channel]['tg_amount'],
  1866. $amount,
  1867. 3
  1868. );
  1869. }
  1870. if(! empty($t)){
  1871. $type = $t['type'];
  1872. $c_t = $t['channel_details'];
  1873. if(in_array($channel, $c_t)){
  1874. if (!isset($costSummary2_road[$month][$type]['tg_amount'])) {
  1875. $costSummary2_road[$month][$type]['tg_amount'] = $amount;
  1876. }else{
  1877. $costSummary2_road[$month][$type]['tg_amount'] = bcadd(
  1878. $costSummary2_road[$month][$type]['tg_amount'],
  1879. $amount,
  1880. 3
  1881. );
  1882. }
  1883. }
  1884. }
  1885. }
  1886. if($row->fy_code == 7012){
  1887. if (! isset($costSummary2[$month][$channel]['cl_amount'])) {
  1888. $costSummary2[$month][$channel]['cl_amount'] = $amount;
  1889. }else{
  1890. $costSummary2[$month][$channel]['cl_amount'] = bcadd(
  1891. $costSummary2[$month][$channel]['cl_amount'],
  1892. $amount,
  1893. 3
  1894. );
  1895. }
  1896. if(! empty($t)){
  1897. $type = $t['type'];
  1898. $c_t = $t['channel_details'];
  1899. if(in_array($channel, $c_t)){
  1900. if (!isset($costSummary2_road[$month][$type]['cl_amount'])) {
  1901. $costSummary2_road[$month][$type]['cl_amount'] = $amount;
  1902. }else{
  1903. $costSummary2_road[$month][$type]['cl_amount'] = bcadd(
  1904. $costSummary2_road[$month][$type]['cl_amount'],
  1905. $amount,
  1906. 3
  1907. );
  1908. }
  1909. }
  1910. }
  1911. }
  1912. //20049 客情出库 60 赠品出库 20048 员工福利
  1913. if($row->fy_code == 7008 || $row->ck_type == 20049){
  1914. if (! isset($costSummary2[$month][$channel]['kq_amount'])) {
  1915. $costSummary2[$month][$channel]['kq_amount'] = $amount;
  1916. }else{
  1917. $costSummary2[$month][$channel]['kq_amount'] = bcadd(
  1918. $costSummary2[$month][$channel]['kq_amount'],
  1919. $amount,
  1920. 3
  1921. );
  1922. }
  1923. if(! empty($t)){
  1924. $type = $t['type'];
  1925. $c_t = $t['channel_details'];
  1926. if(in_array($channel, $c_t)){
  1927. if (!isset($costSummary2_road[$month][$type]['kq_amount'])) {
  1928. $costSummary2_road[$month][$type]['kq_amount'] = $amount;
  1929. }else{
  1930. $costSummary2_road[$month][$type]['kq_amount'] = bcadd(
  1931. $costSummary2_road[$month][$type]['kq_amount'],
  1932. $amount,
  1933. 3
  1934. );
  1935. }
  1936. }
  1937. }
  1938. }
  1939. if($row->fy_code == 7009 || $row->ck_type == 60){
  1940. if (! isset($costSummary2[$month][$channel]['zp_amount'])) {
  1941. $costSummary2[$month][$channel]['zp_amount'] = $amount;
  1942. }else{
  1943. $costSummary2[$month][$channel]['zp_amount'] = bcadd(
  1944. $costSummary2[$month][$channel]['zp_amount'],
  1945. $amount,
  1946. 3
  1947. );
  1948. }
  1949. if(! empty($t)){
  1950. $type = $t['type'];
  1951. $c_t = $t['channel_details'];
  1952. if(in_array($channel, $c_t)){
  1953. if (!isset($costSummary2_road[$month][$type]['zp_amount'])) {
  1954. $costSummary2_road[$month][$type]['zp_amount'] = $amount;
  1955. }else{
  1956. $costSummary2_road[$month][$type]['zp_amount'] = bcadd(
  1957. $costSummary2_road[$month][$type]['zp_amount'],
  1958. $amount,
  1959. 3
  1960. );
  1961. }
  1962. }
  1963. }
  1964. }
  1965. if($row->fy_code == 7010){
  1966. if (! isset($costSummary2[$month][$channel]['gg_amount'])) {
  1967. $costSummary2[$month][$channel]['gg_amount'] = $amount;
  1968. }else{
  1969. $costSummary2[$month][$channel]['gg_amount'] = bcadd(
  1970. $costSummary2[$month][$channel]['gg_amount'],
  1971. $amount,
  1972. 3
  1973. );
  1974. }
  1975. if(! empty($t)){
  1976. $type = $t['type'];
  1977. $c_t = $t['channel_details'];
  1978. if(in_array($channel, $c_t)){
  1979. if (!isset($costSummary2_road[$month][$type]['gg_amount'])) {
  1980. $costSummary2_road[$month][$type]['gg_amount'] = $amount;
  1981. }else{
  1982. $costSummary2_road[$month][$type]['gg_amount'] = bcadd(
  1983. $costSummary2_road[$month][$type]['gg_amount'],
  1984. $amount,
  1985. 3
  1986. );
  1987. }
  1988. }
  1989. }
  1990. }
  1991. if($row->fy_code == 7011){
  1992. if (! isset($costSummary2[$month][$channel]['kd_amount'])) {
  1993. $costSummary2[$month][$channel]['kd_amount'] = $amount;
  1994. }else{
  1995. $costSummary2[$month][$channel]['kd_amount'] = bcadd(
  1996. $costSummary2[$month][$channel]['kd_amount'],
  1997. $amount,
  1998. 3
  1999. );
  2000. }
  2001. if(! empty($t)){
  2002. $type = $t['type'];
  2003. $c_t = $t['channel_details'];
  2004. if(in_array($channel, $c_t)){
  2005. if (!isset($costSummary2_road[$month][$type]['kd_amount'])) {
  2006. $costSummary2_road[$month][$type]['kd_amount'] = $amount;
  2007. }else{
  2008. $costSummary2_road[$month][$type]['kd_amount'] = bcadd(
  2009. $costSummary2_road[$month][$type]['kd_amount'],
  2010. $amount,
  2011. 3
  2012. );
  2013. }
  2014. }
  2015. }
  2016. }
  2017. if($row->fy_code == 7001){
  2018. if (! isset($costSummary2[$month][$channel]['xsqt_amount'])) {
  2019. $costSummary2[$month][$channel]['xsqt_amount'] = $amount;
  2020. }else{
  2021. $costSummary2[$month][$channel]['xsqt_amount'] = bcadd(
  2022. $costSummary2[$month][$channel]['xsqt_amount'],
  2023. $amount,
  2024. 3
  2025. );
  2026. }
  2027. if(! empty($t)){
  2028. $type = $t['type'];
  2029. $c_t = $t['channel_details'];
  2030. if(in_array($channel, $c_t)){
  2031. if (!isset($costSummary2_road[$month][$type]['xsqt_amount'])) {
  2032. $costSummary2_road[$month][$type]['xsqt_amount'] = $amount;
  2033. }else{
  2034. $costSummary2_road[$month][$type]['xsqt_amount'] = bcadd(
  2035. $costSummary2_road[$month][$type]['xsqt_amount'],
  2036. $amount,
  2037. 3
  2038. );
  2039. }
  2040. }
  2041. }
  2042. }
  2043. if($row->fy_code == 7003){
  2044. if (! isset($costSummary2[$month][$channel]['ry_amount'])) {
  2045. $costSummary2[$month][$channel]['ry_amount'] = $amount;
  2046. }else{
  2047. $costSummary2[$month][$channel]['ry_amount'] = bcadd(
  2048. $costSummary2[$month][$channel]['ry_amount'],
  2049. $amount,
  2050. 3
  2051. );
  2052. }
  2053. if(! empty($t)){
  2054. $type = $t['type'];
  2055. $c_t = $t['channel_details'];
  2056. if(in_array($channel, $c_t)){
  2057. if (!isset($costSummary2_road[$month][$type]['ry_amount'])) {
  2058. $costSummary2_road[$month][$type]['ry_amount'] = $amount;
  2059. }else{
  2060. $costSummary2_road[$month][$type]['ry_amount'] = bcadd(
  2061. $costSummary2_road[$month][$type]['ry_amount'],
  2062. $amount,
  2063. 3
  2064. );
  2065. }
  2066. }
  2067. }
  2068. }
  2069. if($row->fy_code == 7019 || $row->ck_type == 20048){
  2070. if (! isset($costSummary2[$month][$channel]['sb_amount'])) {
  2071. $costSummary2[$month][$channel]['sb_amount'] = $amount;
  2072. }else{
  2073. $costSummary2[$month][$channel]['sb_amount'] = bcadd(
  2074. $costSummary2[$month][$channel]['sb_amount'],
  2075. $amount,
  2076. 3
  2077. );
  2078. }
  2079. if(! empty($t)){
  2080. $type = $t['type'];
  2081. $c_t = $t['channel_details'];
  2082. if(in_array($channel, $c_t)){
  2083. if (!isset($costSummary2_road[$month][$type]['sb_amount'])) {
  2084. $costSummary2_road[$month][$type]['sb_amount'] = $amount;
  2085. }else{
  2086. $costSummary2_road[$month][$type]['sb_amount'] = bcadd(
  2087. $costSummary2_road[$month][$type]['sb_amount'],
  2088. $amount,
  2089. 3
  2090. );
  2091. }
  2092. }
  2093. }
  2094. }
  2095. $sj_amount = bcmul($amount,0.01,3);
  2096. if (! isset($costSummary2[$month][$channel]['sj_amount'])) {
  2097. $costSummary2[$month][$channel]['sj_amount'] = $sj_amount;
  2098. }else{
  2099. $costSummary2[$month][$channel]['sj_amount'] = bcadd(
  2100. $costSummary2[$month][$channel]['sj_amount'],
  2101. $sj_amount,
  2102. 3
  2103. );
  2104. }
  2105. if(! empty($t)){
  2106. $type = $t['type'];
  2107. $c_t = $t['channel_details'];
  2108. if(in_array($channel, $c_t)){
  2109. if (!isset($costSummary2_road[$month][$type]['sj_amount'])) {
  2110. $costSummary2_road[$month][$type]['sj_amount'] = $amount;
  2111. }else{
  2112. $costSummary2_road[$month][$type]['sj_amount'] = bcadd(
  2113. $costSummary2_road[$month][$type]['sj_amount'],
  2114. $amount,
  2115. 3
  2116. );
  2117. }
  2118. }
  2119. }
  2120. }
  2121. // 更新 lastId
  2122. $lastId = $rows->last()->id;
  2123. } while ($rows->count() === $limit);
  2124. }catch (\Throwable $exception){
  2125. return [false, "初步汇总异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  2126. }
  2127. try {
  2128. $start_timeStamp = $data['start_timeStamp'];
  2129. $end_timeStamp = $data['end_timeStamp'];
  2130. $result = $this->sumRes($paymentSummary,$costSummary,$costSummary2);
  2131. $result2 = $this->sumRes2($paymentSummary_road, $costSummary_road, $costSummary2_road);
  2132. DB::transaction(function () use ($start_timeStamp, $end_timeStamp, $result, $result2) {
  2133. // 1. 先删除旧数据
  2134. ItemReport::where('time', '>=', $start_timeStamp)
  2135. ->where('time', '<=', $end_timeStamp)
  2136. ->delete();
  2137. ItemReportRoad::where('time', '>=', $start_timeStamp)
  2138. ->where('time', '<=', $end_timeStamp)
  2139. ->delete();
  2140. // 2. 插入新数据
  2141. ItemReport::insert($result);
  2142. ItemReportRoad::insert($result2);
  2143. });
  2144. }catch (\Throwable $exception){
  2145. return [false, "结果异常" . $exception->getMessage() . "|" . $exception->getLine() . "|" . $exception->getFile()];
  2146. }
  2147. return [true, ''];
  2148. }
  2149. private function sumRes($paymentSummary, $costSummary, $costSummary2){
  2150. // 合并三个汇总数组为最终结果
  2151. $result = [];
  2152. // 获取所有唯一的时间+渠道组合
  2153. $keys = [];
  2154. foreach (array_keys($paymentSummary) as $month) {
  2155. foreach (array_keys($paymentSummary[$month]) as $channel) {
  2156. $keys["$month|$channel"] = ['month' => $month, 'channel' => $channel];
  2157. }
  2158. }
  2159. foreach (array_keys($costSummary) as $month) {
  2160. foreach (array_keys($costSummary[$month]) as $channel) {
  2161. $keys["$month|$channel"] = ['month' => $month, 'channel' => $channel];
  2162. }
  2163. }
  2164. foreach (array_keys($costSummary2) as $month) {
  2165. foreach (array_keys($costSummary2[$month]) as $channel) {
  2166. $keys["$month|$channel"] = ['month' => $month, 'channel' => $channel];
  2167. }
  2168. }
  2169. // 遍历所有组合,构建最终数据
  2170. foreach ($keys as $key => $info) {
  2171. $month = $info['month'];
  2172. $channel = $info['channel'];
  2173. // 收款销售收入(注意:原逻辑中 is_kh == false 才计入)
  2174. $receipt_amount = isset($paymentSummary[$month][$channel])
  2175. ? $paymentSummary[$month][$channel]
  2176. : '0.000';
  2177. // 业务成本(来自 tmp_item_road 的 price_4_total)
  2178. $cost = isset($costSummary[$month][$channel])
  2179. ? $costSummary[$month][$channel]
  2180. : '0.000';
  2181. // 利润 = 收入 - 成本
  2182. $profit = bcsub($receipt_amount, $cost, 3);
  2183. // 从 costSummary2 提取各项费用(默认为 0.000)
  2184. $cs2 = $costSummary2[$month][$channel] ?? [];
  2185. $settle_amount = $cs2['settle_amount'] ?? '0.000';
  2186. $gl_amount = $cs2['gl_amount'] ?? '0.000';
  2187. $wl_amount = $cs2['wl_amount'] ?? '0.000';
  2188. $ht_amount = $cs2['ht_amount'] ?? '0.000';
  2189. $zk_amount = $cs2['zk_amount'] ?? '0.000';
  2190. $cx_amount = $cs2['cx_amount'] ?? '0.000';
  2191. $tg_amount = $cs2['tg_amount'] ?? '0.000';
  2192. $cl_amount = $cs2['cl_amount'] ?? '0.000';
  2193. $kq_amount = $cs2['kq_amount'] ?? '0.000';
  2194. $zp_amount = $cs2['zp_amount'] ?? '0.000';
  2195. $gg_amount = $cs2['gg_amount'] ?? '0.000';
  2196. $kd_amount = $cs2['kd_amount'] ?? '0.000';
  2197. $xsqt_amount = $cs2['xsqt_amount'] ?? '0.000';
  2198. $ry_amount = $cs2['ry_amount'] ?? '0.000';
  2199. $sb_amount = $cs2['sb_amount'] ?? '0.000';
  2200. $sj_amount = $cs2['sj_amount'] ?? '0.000';
  2201. $result[] = [
  2202. 'time' => $month,
  2203. 'channel_details'=> $channel,
  2204. 'receipt_amount' => $receipt_amount,
  2205. 'cost' => $cost,
  2206. 'profit' => $profit,
  2207. 'settle_amount' => $settle_amount,
  2208. 'gl_amount' => $gl_amount,
  2209. 'wl_amount' => $wl_amount,
  2210. 'ht_amount' => $ht_amount,
  2211. 'zk_amount' => $zk_amount,
  2212. 'cx_amount' => $cx_amount,
  2213. 'tg_amount' => $tg_amount,
  2214. 'cl_amount' => $cl_amount,
  2215. 'kq_amount' => $kq_amount,
  2216. 'zp_amount' => $zp_amount,
  2217. 'gg_amount' => $gg_amount,
  2218. 'kd_amount' => $kd_amount,
  2219. 'xsqt_amount' => $xsqt_amount,
  2220. 'ry_amount' => $ry_amount,
  2221. 'sb_amount' => $sb_amount,
  2222. 'sj_amount' => $sj_amount,
  2223. ];
  2224. }
  2225. return $result;
  2226. }
  2227. private function sumRes2($paymentSummary, $costSummary, $costSummary2){
  2228. // 合并三个汇总数组为最终结果
  2229. $result = [];
  2230. // 获取所有唯一的时间+渠道组合
  2231. $keys = [];
  2232. foreach (array_keys($paymentSummary) as $month) {
  2233. foreach (array_keys($paymentSummary[$month]) as $channel) {
  2234. $keys["$month|$channel"] = ['month' => $month, 'channel' => $channel];
  2235. }
  2236. }
  2237. foreach (array_keys($costSummary) as $month) {
  2238. foreach (array_keys($costSummary[$month]) as $channel) {
  2239. $keys["$month|$channel"] = ['month' => $month, 'channel' => $channel];
  2240. }
  2241. }
  2242. foreach (array_keys($costSummary2) as $month) {
  2243. foreach (array_keys($costSummary2[$month]) as $channel) {
  2244. $keys["$month|$channel"] = ['month' => $month, 'channel' => $channel];
  2245. }
  2246. }
  2247. // 遍历所有组合,构建最终数据
  2248. foreach ($keys as $key => $info) {
  2249. $month = $info['month'];
  2250. $channel = $info['channel'];
  2251. // 收款销售收入
  2252. $receipt_amount = isset($paymentSummary[$month][$channel])
  2253. ? $paymentSummary[$month][$channel]
  2254. : '0.000';
  2255. // 业务成本(来自 tmp_item_road 的 price_4_total)
  2256. $cost = isset($costSummary[$month][$channel])
  2257. ? $costSummary[$month][$channel]
  2258. : '0.000';
  2259. // 利润 = 收入 - 成本
  2260. $profit = bcsub($receipt_amount, $cost, 3);
  2261. // 从 costSummary2 提取各项费用(默认为 0.000)
  2262. $cs2 = $costSummary2[$month][$channel] ?? [];
  2263. $settle_amount = $cs2['settle_amount'] ?? '0.000';
  2264. $gl_amount = $cs2['gl_amount'] ?? '0.000';
  2265. $wl_amount = $cs2['wl_amount'] ?? '0.000';
  2266. $ht_amount = $cs2['ht_amount'] ?? '0.000';
  2267. $zk_amount = $cs2['zk_amount'] ?? '0.000';
  2268. $cx_amount = $cs2['cx_amount'] ?? '0.000';
  2269. $tg_amount = $cs2['tg_amount'] ?? '0.000';
  2270. $cl_amount = $cs2['cl_amount'] ?? '0.000';
  2271. $kq_amount = $cs2['kq_amount'] ?? '0.000';
  2272. $zp_amount = $cs2['zp_amount'] ?? '0.000';
  2273. $gg_amount = $cs2['gg_amount'] ?? '0.000';
  2274. $kd_amount = $cs2['kd_amount'] ?? '0.000';
  2275. $xsqt_amount = $cs2['xsqt_amount'] ?? '0.000';
  2276. $ry_amount = $cs2['ry_amount'] ?? '0.000';
  2277. $sb_amount = $cs2['sb_amount'] ?? '0.000';
  2278. $sj_amount = $cs2['sj_amount'] ?? '0.000';
  2279. $result[] = [
  2280. 'time' => $month,
  2281. 'receipt_amount' => $receipt_amount,
  2282. 'cost' => $cost,
  2283. 'profit' => $profit,
  2284. 'settle_amount' => $settle_amount,
  2285. 'gl_amount' => $gl_amount,
  2286. 'wl_amount' => $wl_amount,
  2287. 'ht_amount' => $ht_amount,
  2288. 'zk_amount' => $zk_amount,
  2289. 'cx_amount' => $cx_amount,
  2290. 'tg_amount' => $tg_amount,
  2291. 'cl_amount' => $cl_amount,
  2292. 'kq_amount' => $kq_amount,
  2293. 'zp_amount' => $zp_amount,
  2294. 'gg_amount' => $gg_amount,
  2295. 'kd_amount' => $kd_amount,
  2296. 'xsqt_amount' => $xsqt_amount,
  2297. 'ry_amount' => $ry_amount,
  2298. 'sb_amount' => $sb_amount,
  2299. 'sj_amount' => $sj_amount,
  2300. 'employee_title_type' => $channel
  2301. ];
  2302. }
  2303. return $result;
  2304. }
  2305. }