OuterCarJISCO.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. using com.hnshituo.core.webapp.vo;
  2. using Common;
  3. using Common.utils;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace MeterSceneLibrary
  10. {
  11. /// <summary>
  12. /// 酒钢厂外车辆计量业务
  13. /// </summary>
  14. public class OuterCarJISCO
  15. {
  16. // 一次计量数据
  17. private MeterWorkCarActualFirstService mwcfs = new MeterWorkCarActualFirstService();
  18. // 车辆委托表
  19. private PreTrackScaleService preTrackScaleService = new PreTrackScaleService();
  20. private rtInfo rt = new rtInfo();
  21. // 构建一次计量数据
  22. private MeterWorkCarActualFirst mwaf = new MeterWorkCarActualFirst();
  23. // 结净最小值,默认取配置文件
  24. private double diffrentWgt = AppConfigCache.differenceWgt;
  25. // 根据车号查询委托表中未使用和使用中的委托
  26. private List<PreTrackScale> listPreScale;
  27. private JISCO.SaveMethod saveMethod = new JISCO.SaveMethod();
  28. public rtInfo MeterMethod(InnerMeterInfo scale)
  29. {
  30. Log lg = Log.GetInstance();
  31. rt.isError = false;
  32. string ResultMessage = "";
  33. bool isError = false;
  34. mwaf.carNo = CarNoUtil.CarNoChange(PbCache.lockCarNo);
  35. mwaf.weightType = ""; // 默认重量类型为空
  36. mwaf.actualFirstNo = DateTime.Now.ToString("yyyyMMdd");//10
  37. mwaf.meterWeight = PbCache.lockWgt;//计量重量
  38. mwaf.addWeight = PbCache.addWgt;//附加重量
  39. mwaf.createManNo = PbCache.sportInfo.baseSpotNo;
  40. mwaf.createManName = PbCache.sportInfo.baseSpotName;
  41. mwaf.meterGroup = "";
  42. mwaf.meterClass = "";
  43. mwaf.createTime = DateTime.Now;
  44. mwaf.baseSpotNo = PbCache.sportInfo.baseSpotNo;//计量点编号
  45. mwaf.baseSpotName = PbCache.sportInfo.baseSpotName;
  46. //mwaf.memo = "";
  47. mwaf.valueFlag = "3"; //状态(0 = 作废,1 = 有效(已匹配),2 = 结净,3 = 未匹配)
  48. mwaf.updateManName = "";
  49. mwaf.updateManNo = "";
  50. mwaf.updateTime = null;
  51. mwaf.checkFlag = "1"; //0未审核,1已审核
  52. mwaf.meterMode = "2"; //1:远程计量;2:智能计量;3:手工录入;4:放行智能计量;5:滞后匹配
  53. mwaf.addWeight = PbCache.addWgt;
  54. mwaf.dataSource = "1"; //数据来源(1=智能终端,2=本地计量,3=应急计量,4=手动录入(计量票据录入))
  55. // VALUE_FLAG 状态(0=作废,1=有效(已匹配),2=结净,3=未匹配)
  56. // 根据车号查询最近的一次计量数据
  57. RESTfulResult<List<MeterWorkCarActualFirst>> rmX = mwcfs.doQueryByFlag(new MeterWorkCarActualFirst { carNo = CarNoUtil.CarNoChange(PbCache.lockCarNo) });
  58. if (rmX.Succeed)
  59. {
  60. List<MeterWorkCarActualFirst> list = rmX.Data;
  61. // 不存在一次计量数据
  62. if (list == null || list.Count == 0)
  63. {
  64. // 根据车号查询委托表中未使用和使用中的委托
  65. // 状态(0:未配车;1:未使用;2:已使用;3:已作废;4:正使用)
  66. RESTfulResult<List<PreTrackScale>> rmPre = preTrackScaleService.doQueryByFlag(new PreTrackScale { carNo = CarNoUtil.CarNoChange(PbCache.lockCarNo)});
  67. if (rmPre.Succeed)
  68. {
  69. listPreScale = rmPre.Data;
  70. // 不存在委托
  71. if (listPreScale == null || listPreScale.Count == 0)
  72. {
  73. saveMethod.doAddFirst(mwaf);
  74. }
  75. // 存在一条使用中的委托
  76. else if (listPreScale.Count == 1 && listPreScale[0].valueFlag == "4")
  77. {
  78. saveMethod.doError("不存在一次计量数据却存在一条使用中的委托");
  79. }
  80. // 只存在一条未使用的委托
  81. else if (listPreScale.Count == 1 && (listPreScale[0].valueFlag == "0" || listPreScale[0].valueFlag == "1"))
  82. {
  83. //相同名称的均赋值一次
  84. //EntityBase<PreTrackScale> entityBase = new EntityBase<PreTrackScale>();
  85. //mwaf = entityBase.format<MeterWorkCarActualFirst>(scale, mwaf);
  86. // 查询上一次结净数据
  87. MeterWorkCarActualService meterWorkCarActualService = new MeterWorkCarActualService();
  88. //计量实绩
  89. CommonPage<MeterWorkCarActual> cpc = new CommonPage<MeterWorkCarActual>();
  90. MeterWorkCarActual mwca = new MeterWorkCarActual();
  91. mwca.carNo = CarNoUtil.CarNoChange(PbCache.lockCarNo);
  92. cpc.param = mwca;
  93. cpc.pageSize = 1;
  94. RESTfulResult<List<MeterWorkCarActual>> rm = meterWorkCarActualService.doQueryOneWf(cpc);
  95. if (rm.Succeed)
  96. {
  97. // 之前没有净重记录
  98. if (rm.Data.Count == 0)
  99. {
  100. /*
  101. * a. 正常保存重量(重量类型为空)
  102. * b. 匹配委托
  103. * c. 将委托状态变更为已使用
  104. * d. 提示称重完成
  105. */
  106. // 把委托编号复制给一次计量记录
  107. EntityBase<PreTrackScale> entityBase = new EntityBase<PreTrackScale>();
  108. mwaf = entityBase.format<MeterWorkCarActualFirst>(listPreScale[0], mwaf);
  109. saveMethod.doAddFirst(mwaf);
  110. }
  111. else
  112. {
  113. MeterWorkCarActual lastMeterWorkCarActual = rm.Data[0];
  114. // 上次净重记录未匹配委托
  115. if (lastMeterWorkCarActual.valueFlag == "3")
  116. {
  117. saveMethod.doAddFirst(mwaf);
  118. saveMethod.doError("上次净重数据未匹配委托,请联系计量大厅");
  119. }
  120. // 上次净重已匹配委托
  121. else if (lastMeterWorkCarActual.valueFlag == "1")
  122. {
  123. /* 委托和当次存在委托满足一车多卸逻辑 && 当次重量值小于上次净重记录中的皮重值
  124. * 一车多卸判断逻辑1
  125. * 存在判断依据(委托类型为一车多卸,且上次洁净数据中匹配委托类型也是一车多卸)
  126. *
  127. * 一车多卸判断逻辑2
  128. * 委托不存在判断依据,则根据签发时间排序
  129. * 如果两条数据发货单位一致,收货单位不一致,且签发时间在10分钟内,则可判定为一车多卸业务
  130. */
  131. bool isYCDX = false;
  132. // 签发时间比较
  133. // 通过上次洁净记录,找到该委托的签发时间
  134. RESTfulResult<List<PreTrackScale>> lastPre = preTrackScaleService.doQueryWf(new PreTrackScale { predictionNo = lastMeterWorkCarActual.predictionNo });
  135. int min = 999;
  136. if (lastPre.Succeed && lastPre.Data.Count == 1)
  137. {
  138. TimeSpan ts = new TimeSpan();
  139. ts = DateTime.Parse(listPreScale[0].trustDateTime.ToString()) - DateTime.Parse(lastPre.Data[0].trustDateTime.ToString());
  140. min = ts.Minutes; //此为相差分钟
  141. }
  142. // 一车多卸 && 当次重量值小于上次净重记录中的皮重值
  143. if (listPreScale[0].meterTypeNo.Equals("xxxx") && PbCache.lockWgt < lastMeterWorkCarActual.tareWeight)
  144. {
  145. isYCDX = true;
  146. }
  147. // 如果两条数据发货单位一致,收货单位不一致,且签发时间在10分钟内,则可判定为一车多卸业务
  148. else if (listPreScale[0].forwardingUnitNo.Equals(lastMeterWorkCarActual.forwardingUnitNo) && listPreScale[0].receivingUintNo.Equals(lastMeterWorkCarActual.receivingUintNo) && min <= 10)
  149. {
  150. isYCDX = true;
  151. }
  152. if (isYCDX == true)
  153. {
  154. /*
  155. * a. 取上次净重记录的皮重为当次毛重
  156. * b. 洁净匹配委托
  157. */
  158. // 新增一条毛重数据
  159. MeterWorkCarActualFirst tempCarActualFirst = new MeterWorkCarActualFirst();
  160. tempCarActualFirst.carNo = CarNoUtil.CarNoChange(PbCache.lockCarNo);
  161. tempCarActualFirst.weightType = "0"; // 重量类型(0=毛重;1=常规皮重;2=期限皮重;3=历史皮重;4=标识皮重;5=自重皮重)
  162. tempCarActualFirst.actualFirstNo = DateTime.Now.ToString("yyyyMMdd");//10
  163. tempCarActualFirst.meterWeight = PbCache.lockWgt;//计量重量
  164. tempCarActualFirst.addWeight = PbCache.addWgt;//附加重量
  165. tempCarActualFirst.createManNo = PbCache.sportInfo.baseSpotNo;
  166. tempCarActualFirst.createManName = PbCache.sportInfo.baseSpotName;
  167. tempCarActualFirst.meterGroup = "";
  168. tempCarActualFirst.meterClass = "";
  169. tempCarActualFirst.createTime = DateTime.Now;
  170. tempCarActualFirst.baseSpotNo = PbCache.sportInfo.baseSpotNo;//计量点编号
  171. tempCarActualFirst.baseSpotName = PbCache.sportInfo.baseSpotName;
  172. //mwaf.memo = "";
  173. tempCarActualFirst.valueFlag = "3"; //状态(0 = 作废,1 = 有效(已匹配),2 = 结净,3 = 未匹配)
  174. tempCarActualFirst.updateManName = "";
  175. tempCarActualFirst.updateManNo = "";
  176. tempCarActualFirst.updateTime = null;
  177. tempCarActualFirst.checkFlag = "1"; //0未审核,1已审核
  178. tempCarActualFirst.meterMode = "2"; //1:远程计量;2:智能计量;3:手工录入;4:放行智能计量;5:滞后匹配
  179. tempCarActualFirst.addWeight = PbCache.addWgt;
  180. tempCarActualFirst.dataSource = "1"; //数据来源(1=智能终端,2=本地计量,3=应急计量,4=手动录入(计量票据录入))
  181. // 复制对象,将档次委托信息复制给一次记录
  182. EntityBase<PreTrackScale> entityBase = new EntityBase<PreTrackScale>();
  183. tempCarActualFirst = entityBase.format<MeterWorkCarActualFirst>(listPreScale[0], tempCarActualFirst);
  184. // 将当次一次计量数据重量类型改为皮重
  185. mwaf.weightType = "1"; // 常规皮重
  186. // 混装卸逻辑,并洁净匹配委托
  187. saveMethod.doNetHZHX(scale, tempCarActualFirst, mwaf);
  188. }
  189. /* 匹配委托和当次委托满足混装逻辑 && 当次重量大于上次净重记录中的毛重值
  190. * 混装判断逻辑1
  191. * 存在判断依据(委托类型为混装,且上次洁净数据中匹配委托类型也是混装)
  192. *
  193. * 混装判断逻辑2
  194. * 两次委托发货单位一致,净重时间在4个小时之内
  195. */
  196. bool isHZ = false;
  197. // 签发时间比较
  198. // 通过上次洁净记录,找到该委托的签发时间
  199. int hour = 999;
  200. if (lastPre.Succeed && lastPre.Data.Count == 1)
  201. {
  202. TimeSpan ts = new TimeSpan();
  203. ts = DateTime.Parse(DateTime.Now.ToString()) - DateTime.Parse(lastMeterWorkCarActual.netTime.ToString());
  204. hour = ts.Hours; //此为相差小时
  205. }
  206. // 混装逻辑 && 当次重量大于上次净重记录中的毛重值
  207. if (listPreScale[0].meterTypeNo.Equals("yyyy") && PbCache.lockWgt > lastMeterWorkCarActual.tareWeight)
  208. {
  209. isHZ = true;
  210. }
  211. // 两次委托发货单位一致,净重时间在4个小时之内
  212. else if (listPreScale[0].forwardingUnitNo.Equals(lastMeterWorkCarActual.forwardingUnitNo) && hour <= 4)
  213. {
  214. isHZ = true;
  215. }
  216. if (isHZ == true)
  217. {
  218. /*
  219. * a. 取上次净重记录中的毛重值为当次皮重
  220. * b. 洁净匹配委托
  221. */
  222. // 新增一条皮重数据
  223. MeterWorkCarActualFirst newActualFirst = new MeterWorkCarActualFirst();
  224. newActualFirst.carNo = CarNoUtil.CarNoChange(PbCache.lockCarNo);
  225. newActualFirst.weightType = "1"; // 默认重量类型为皮重
  226. newActualFirst.actualFirstNo = DateTime.Now.ToString("yyyyMMdd");//10
  227. newActualFirst.meterWeight = lastMeterWorkCarActual.grossWeight;//取上次净重记录中的毛重值为当次皮重
  228. newActualFirst.addWeight = PbCache.addWgt;//附加重量
  229. newActualFirst.createManNo = PbCache.sportInfo.baseSpotNo;
  230. newActualFirst.createManName = PbCache.sportInfo.baseSpotName;
  231. newActualFirst.meterGroup = "";
  232. newActualFirst.meterClass = "";
  233. newActualFirst.createTime = DateTime.Now;
  234. newActualFirst.baseSpotNo = PbCache.sportInfo.baseSpotNo;//计量点编号
  235. newActualFirst.baseSpotName = PbCache.sportInfo.baseSpotName;
  236. //mwaf.memo = "";
  237. newActualFirst.valueFlag = "3"; //状态(0 = 作废,1 = 有效(已匹配),2 = 结净,3 = 未匹配)
  238. newActualFirst.updateManName = "";
  239. newActualFirst.updateManNo = "";
  240. newActualFirst.updateTime = null;
  241. newActualFirst.checkFlag = "1"; //0未审核,1已审核
  242. newActualFirst.meterMode = "2"; //1:远程计量;2:智能计量;3:手工录入;4:放行智能计量;5:滞后匹配
  243. newActualFirst.addWeight = PbCache.addWgt;
  244. newActualFirst.dataSource = "1"; //数据来源(1=智能终端,2=本地计量,3=应急计量,4=手动录入(计量票据录入))
  245. // 将当次一次计量数据重量类型改为毛重
  246. mwaf.weightType = "0"; // 毛重
  247. // 混装逻辑,并洁净匹配委托
  248. saveMethod.doNetHZHX(scale, newActualFirst, mwaf);
  249. }
  250. }
  251. // 存在洁净记录,不满足以上逻辑
  252. else {
  253. /*
  254. * a. 正常保存重量(重量类型为空)
  255. * b. 匹配委托
  256. * c. 提示称重完成
  257. */
  258. // 把委托编号复制给一次计量记录
  259. EntityBase<PreTrackScale> entityBase = new EntityBase<PreTrackScale>();
  260. mwaf = entityBase.format<MeterWorkCarActualFirst>(listPreScale[0], mwaf);
  261. saveMethod.doAddFirst(mwaf);
  262. }
  263. }
  264. }
  265. }
  266. // 存在多条委托
  267. else if (listPreScale.Count > 1)
  268. {
  269. /*
  270. * a. 正常保存重量(重量类型为空)
  271. * b. 提示称重完成
  272. */
  273. saveMethod.doAddFirst(mwaf);
  274. }
  275. }
  276. }
  277. // 存在一次计量数据
  278. else
  279. {
  280. // 读结净最小值配置
  281. ComBaseInfoService cbis = new ComBaseInfoService();
  282. RESTfulResult<List<ComBaseInfo>> res = cbis.doQueryBaseList(new ComBaseInfo { baseCode = "001031001" });
  283. if (res.Succeed)
  284. {
  285. if (res.Data != null && res.Data.Count == 1)
  286. {
  287. try
  288. {
  289. diffrentWgt = Double.Parse(res.Data[0].baseName);
  290. }
  291. finally
  292. {
  293. }
  294. }
  295. }
  296. // 校验上次计量数据和当次计量数据是否满足基础配置表中的洁净最小值条件
  297. if (Math.Abs(rmX.Data[0].meterWeight.Value - PbCache.lockWgt) > diffrentWgt)
  298. {
  299. // 存在的一次计量数据未匹配委托
  300. if (rmX.Data[0].valueFlag == "3")
  301. {
  302. // 不存在委托数据
  303. if (listPreScale == null || listPreScale.Count == 0)
  304. {
  305. /*
  306. * a. 正常产生洁净数据(状态为未发布)
  307. * b. 提示司机当前计量数据未匹配委托,请联系计量打印进行处理
  308. */
  309. saveMethod.doNet(scale, rmX.Data[0], mwaf);
  310. }
  311. // 只存在一条使用中的委托
  312. else if (listPreScale.Count == 1 && listPreScale[0].valueFlag == "4")
  313. {
  314. /*
  315. * a. 程序报警
  316. * b. 提示司机存在一条使用中的委托,请联系计量大厅进行确认
  317. * c. 自动进行语音求助
  318. */
  319. saveMethod.doError("存在一条使用中的委托,请联系计量大厅进行确认");
  320. }
  321. // 只存在一条未使用的委托数据
  322. else if (listPreScale.Count == 1 && (listPreScale[0].valueFlag == "0" || listPreScale[0].valueFlag == "1"))
  323. {
  324. /*
  325. * a. 程序根据大减小的原则,保存净重并正确设置一次计量数据中的重量类型
  326. * b. 播放称重完成的语音提示
  327. */
  328. saveMethod.doNetAndScale(scale, rmX.Data[0], mwaf);
  329. }
  330. // 如果存在两条未使用的委托
  331. else if (listPreScale.Count == 2 && (listPreScale[0].valueFlag == "0" || listPreScale[0].valueFlag == "1"))
  332. {
  333. /* 委托关系满足双委托逻辑
  334. * 分两种情况:
  335. * 1、委托数据货源字段中带有委托标识,且两条委托类型都是双委托。
  336. * 2、委托数据中没有带有委托标识,则根据签发时间排序,如果第一条委托的物料和第二条委托数据的相同,且第一条委托的收货单位是第二条委托的发货单位。
  337. */
  338. if (1 == 1)
  339. {
  340. // 正常洁净并生成两条净重数据
  341. saveMethod.doNetAddTwo(scale, rmX.Data[0]);
  342. }
  343. /*
  344. * 委托关系满足一车多卸逻辑
  345. * 分两种情况:
  346. * 1、委托数据中没有委托类型标识,则根据签发时间排序,如果两条数据发货单位一致,收货单位不一致,且签发时间在10分钟内,则可判定为一车多卸业务,根据时间顺序选择第一条委托产生净重数据,然后使用第二条委托产生一个毛重数据。
  347. * 2、委托数据中存在委托类型标识,且类型都为一车多卸。
  348. */
  349. else if (2 == 2)
  350. {
  351. /*
  352. * a. 正常洁净产生一条净重记录
  353. * b. 自动生成一条一次毛重计量数据,重量值值为当次计量数据中的毛重
  354. */
  355. // 将当次一次计量数据重量类型改为毛重
  356. mwaf.weightType = "0"; // 毛重
  357. // 洁净匹配委托
  358. saveMethod.doNetMass(scale, mwaf);
  359. }
  360. // 不满足以上逻辑
  361. else
  362. {
  363. /*
  364. * a. 正常洁净产生一条净重记录(状态为未发布)
  365. * b. 提示司机当前存计量数据未匹配委托
  366. * c. 进行大厅报警,请联系计量大厅进行处理
  367. * d. 自动进行语音求助(但是原有的语音求助逻辑是重量归零相应秤点的求助信息也会清空)
  368. */
  369. saveMethod.doNet(scale, rmX.Data[0], mwaf);
  370. saveMethod.doError("当前所存计量数据未匹配委托,请联系计量大厅进行处理");
  371. }
  372. }
  373. // 存在多条未使用的委托数据
  374. else if (listPreScale.Count > 2 && (listPreScale[0].valueFlag == "0" || listPreScale[0].valueFlag == "1"))
  375. {
  376. /* 委托关系满足多委托逻辑
  377. * 多委托判定逻辑:
  378. * 多条委托数据都存在委托类型依据,且类型都是多委托。
  379. */
  380. if (1 == 1)
  381. {
  382. // 正常洁净并生成两条净重数据
  383. saveMethod.doNetAddTwo(scale, mwaf);
  384. }
  385. /*
  386. * 委托关系满足一车多卸逻辑
  387. * 一车多卸逻辑:多条委托都存在委托判断依据,且类型都是一车多卸委托。
  388. */
  389. else if (2 == 2)
  390. {
  391. /*
  392. * a. 正常洁净产生一条净重记录
  393. * b. 自动生成一条一次毛重计量数据,重量值值为当次计量数据中的毛重
  394. */
  395. // 将当次一次计量数据重量类型改为毛重
  396. mwaf.weightType = "0"; // 毛重
  397. // 洁净匹配委托
  398. saveMethod.doNetMass(scale, mwaf);
  399. }
  400. // 不满足以上逻辑
  401. else
  402. {
  403. /*
  404. * a. 正常洁净产生一条净重记录(状态为未发布)
  405. * b. 提示司机当前计量数据未匹配委托,请联系计量大厅进行委托匹配
  406. * c. 自动进行语音求助(但是原有的语音求助逻辑是重量归零相应秤点的求助信息也会清空)
  407. */
  408. saveMethod.doNet(scale, rmX.Data[0], mwaf);
  409. saveMethod.doError("当前所存计量数据未匹配委托,请联系计量大厅进行处理");
  410. }
  411. }
  412. }
  413. // 存在的一次计量数据已匹配委托
  414. else if (rmX.Data[0].valueFlag == "1")
  415. {
  416. /*
  417. * a. 程序根据大减小的原则,保存净重并正确设置一次计量数据中的重量类型
  418. * b. 播放称重完成的语音提示
  419. */
  420. // 原数据大于新数据,原数据是毛重,新数据是皮重
  421. MeterWorkCarActualFirst oldCarActural = rmX.Data[0];
  422. if (rmX.Data[0].meterWeight.Value > PbCache.lockWgt)
  423. {
  424. mwaf.weightType = "1";
  425. oldCarActural.weightType = "0";
  426. }
  427. else
  428. {
  429. mwaf.weightType = "0";
  430. oldCarActural.weightType = "1";
  431. }
  432. saveMethod.doNet(scale, oldCarActural, mwaf);
  433. rt.result = true;
  434. rt.resultInfo = "称重完成";
  435. }
  436. }
  437. // 不满足
  438. else
  439. {
  440. saveMethod.doError("第一次计量重量【" + rmX.Data[0].meterWeight.Value / 1000 + "T】和第二次计量重量【" + PbCache.lockWgt / 1000 + "T】接近,小于结净最小值【" + diffrentWgt / 1000 + " T】");
  441. }
  442. }
  443. }
  444. else
  445. {
  446. saveMethod.doError("接口调用错误:无法读取车辆最近一次计量数据");
  447. }
  448. return rt;
  449. }
  450. }
  451. }