IcsFromERPJob
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

353 lines
19 KiB

  1. using log4net.Core;
  2. using Newtonsoft.Json;
  3. using Quartz;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Configuration;
  7. using System.Data;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Reflection;
  11. using System.Security.Policy;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using System.Xml.Linq;
  15. namespace ICSSoft.FromERP
  16. {
  17. public class ICSAddStdWorkHourFromMES : IJob
  18. {
  19. private static object key = new object();
  20. private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  21. public void Execute(IJobExecutionContext context)
  22. {
  23. try
  24. {
  25. lock (key)
  26. {
  27. log.Info("开始……………………………………………………………………");
  28. Execute();
  29. log.Info("结束……………………………………………………………………");
  30. }
  31. }
  32. catch (Exception ex)
  33. {
  34. log.Error(ex.ToString());
  35. }
  36. }
  37. public async void Execute()
  38. {
  39. try
  40. {
  41. Configuration config = GetConfig();
  42. string url = config.ConnectionStrings.ConnectionStrings["APIAddStdWorkHour"].ConnectionString.ToString();
  43. // 若变更环境 除了修改接口外,还需要替换ERP.U9DB u9数据库
  44. log.Info("获取创建定额工时接口 " + url);
  45. if (string.IsNullOrEmpty(url))
  46. {
  47. return;
  48. }
  49. string conStr = ICSHelper.GetConnectString();
  50. string Namespace = this.GetType().Namespace;
  51. List<string> AErrorCode = new List<string>();
  52. List<string> BErrorCode = new List<string>();
  53. List<string> CErrorCode = new List<string>();
  54. // 业务逻辑 从u9那边料品关联工时表 找到没有工时数据的料品 再向mes这边根据料号找到数据 去匹配条件 计算出工时 给u9
  55. // 二 分别抓取整机、本体部、驱动部未统计的料号 本体部、驱动部逆向去找型号
  56. // 准备请求接口的数据集合
  57. var AddList = new List<AddStdWorkHourItem>();
  58. #region 未统计的整机料号
  59. string sqls = @"select a.code,mf.Id as MFId,mfvb.ValueModel,mfvb.NominalDiameter,ISNULL(SpecialRequirement_ValveBodySpec,'') as SpecialRequirement from ERP.U9DB.dbo.CBO_ItemMaster a
  60. join (select ROW_NUMBER() over(partition by ManufacturingSerial order by Id desc) as MFIdFlag,Id,ItemModel,ManufacturingSerial,TenantId from IcsManufacturingHead ) mf
  61. on mf.MFIdFlag = 1 and a.code = mf.ManufacturingSerial --and mf.TenantId = ''
  62. join IcsMfValveBodySpec mfvb on mf.Id = mfvb.MFId
  63. left join ERP.U9DB.dbo.CA_StdWorkingHours b
  64. on a.Id = b.ItemMaster
  65. LEFT OUTER JOIN ERP.U9DB.dbo.Base_Organization AS oo
  66. ON oo.ID = a.Org
  67. where oo.Code = '01' and b.id is null and a.code like 'KA%' and mfvb.ValueModel is not null";
  68. DataTable dt = ICSHelper.ExecuteTable(conStr, sqls);
  69. if (dt != null)
  70. {
  71. log.Info("查询到整机待统计数量:" + dt.Rows.Count + "。");
  72. //准备整机条件 口径+A拼接
  73. string argsqls = @"select ItemModel,Type,NominalDiameter+'A' as NominalDiameter,Coefficient,ManHour,AdditiveManHour,ISNULL(SpecialRequirement,'') as SpecialRequirement
  74. from IcsProductionDurationStatistics
  75. where Type = 0 --and TenantId = ''";
  76. DataTable argdt = ICSHelper.ExecuteTable(conStr, argsqls);
  77. if (argdt != null)
  78. {
  79. //log.Info("整机循环开始!");
  80. foreach (DataRow dr in dt.Rows)
  81. {
  82. // 整机条件过滤 阀门型号、口径、特殊要求
  83. var ValueModel = dr["ValueModel"].ToString().Length > 5 ? dr["ValueModel"].ToString().Substring(0, 5) : dr["ValueModel"].ToString(); // 截取前五位数字符
  84. DataRow[] infoArgRow = argdt?.Select("ItemModel='" + ValueModel
  85. // + "' and SpecialRequirement = '" + dr["SpecialRequirement"].ToString() //特殊条件都为空 或者有特殊条件
  86. + "' and NominalDiameter = '" + dr["NominalDiameter"].ToString()
  87. + "'");
  88. if (infoArgRow.Length > 0)
  89. {
  90. var Manhour = infoArgRow[0]["ManHour"].ToDecimal(); //本体基础工时
  91. var AdditiveManHour = infoArgRow[0]["AdditiveManHour"].ToDecimal();//追加工时
  92. var Coefficient = infoArgRow[0]["Coefficient"].ToDecimal();//系数
  93. AddList.Add(new AddStdWorkHourItem()
  94. {
  95. ORGCode = "01",//u9 Base_Organization表 的 code 字段 组织编码
  96. WorkHour = ((Manhour + AdditiveManHour) * Coefficient) / 60, // 整机计算逻辑:(本体基础工时型号 + 追加工时) * 系数
  97. CreatedByCode = "",
  98. DepartmentCode = "080502",//部门
  99. ItemCode = dr["code"].ToString()
  100. });
  101. }
  102. else
  103. {
  104. //记录未匹配到条件 统计失败的料号
  105. AErrorCode.Add(dr["code"].ToString()+ "(阀门型号:" + dr["ValueModel"].ToString() + ",特殊规格:" + dr["SpecialRequirement"].ToString()+ ",口径:" + dr["NominalDiameter"].ToString() + ");");
  106. }
  107. }
  108. //log.Info("整机循环结束!");
  109. }
  110. else
  111. {
  112. log.Info("整机待统计数量:" + dt.Rows.Count + "。但未查询到整机条件配置,已跳过生成。");
  113. }
  114. }
  115. else
  116. {
  117. log.Info("查询到整机待统计数量:0。");
  118. }
  119. #endregion
  120. #region 未统计的本体部
  121. string vbssqls = @"select b.MFId,a.code,mfvb.ValueModel,mfvb.NominalDiameter,ISNULL(SpecialRequirement_ValveBodySpec,'') as SpecialRequirement from ERP.U9DB.dbo.CBO_ItemMaster a
  122. join (select ROW_NUMBER() over(partition by PartItemCode order by MFId desc) as Flag,PartItemCode,MFId from ICSPartItem where PartItemName = '') b -- and TenantId = ''
  123. on a.code = b.PartItemCode and b.Flag = 1
  124. join IcsMfValveBodySpec mfvb on b.MFId = mfvb.MFId
  125. left join ERP.U9DB.dbo.CA_StdWorkingHours c on a.Id = c.ItemMaster
  126. LEFT OUTER JOIN ERP.U9DB.dbo.Base_Organization AS oo ON oo.ID = a.Org
  127. where oo.Code = '01' and c.id is null and a.code like 'A2001%'";
  128. DataTable vbsdt = ICSHelper.ExecuteTable(conStr, vbssqls);
  129. if (vbsdt != null)
  130. {
  131. log.Info("查询到本体部待统计数量:" + vbsdt.Rows.Count + "。");
  132. //准备本体部条件 ItemModel型号 驱动部类型时此字段为驱动型号 口径+A拼接
  133. string vbsargsqls = @"select ItemModel,Type,NominalDiameter+'A' as NominalDiameter,Coefficient,ManHour,AdditiveManHour,ISNULL(SpecialRequirement,'') as SpecialRequirement
  134. from IcsProductionDurationStatistics
  135. where Type = 1 --and TenantId = ''";
  136. DataTable vbsargdt = ICSHelper.ExecuteTable(conStr, vbsargsqls);
  137. if (vbsargdt != null)
  138. {
  139. //log.Info("本体部循环开始!");
  140. foreach (DataRow dr in vbsdt.Rows)
  141. {
  142. // 本体部条件过滤 阀门型号、口径、特殊条件
  143. var ValueModel = dr["ValueModel"].ToString().Length > 5 ? dr["ValueModel"].ToString().Substring(0, 5) : dr["ValueModel"].ToString(); // 截取前五位数字符
  144. //log.Info(ValueModel);
  145. DataRow[] infoVbsRow = vbsargdt?.Select("ItemModel='" + ValueModel
  146. // + "' and SpecialRequirement = '" + dr["SpecialRequirement"].ToString() //特殊条件都为空 或者有特殊条件
  147. + "' and NominalDiameter = '" + dr["NominalDiameter"].ToString()
  148. + "'");
  149. if (infoVbsRow.Length > 0)
  150. {
  151. var Manhour = infoVbsRow[0]["ManHour"].ToDecimal(); //本体基础工时
  152. var AdditiveManHour = infoVbsRow[0]["AdditiveManHour"].ToDecimal();//追加工时
  153. var Coefficient = infoVbsRow[0]["Coefficient"].ToDecimal();//系数
  154. AddList.Add(new AddStdWorkHourItem()
  155. {
  156. ORGCode = "01",//u9 Base_Organization表 的 code 字段 组织编码
  157. WorkHour = (Manhour + AdditiveManHour) * Coefficient / 60, // 本体部计算逻辑:(本体基础工时型号 + 追加工时) * 系数
  158. CreatedByCode = "",
  159. DepartmentCode = "080502",//部门
  160. ItemCode = dr["code"].ToString()
  161. });
  162. }
  163. else
  164. {
  165. //记录未匹配到条件 统计失败的料号
  166. BErrorCode.Add(dr["code"].ToString() + "(阀门型号:" + dr["ValueModel"].ToString() + ",特殊规格:" + dr["SpecialRequirement"].ToString() + ",口径:" + dr["NominalDiameter"].ToString() + ");");
  167. }
  168. }
  169. //log.Info("本体部循环结束!");
  170. }
  171. else
  172. {
  173. log.Info("本体部待统计数量:" + vbsdt.Rows.Count + "。但未查询到本体部条件配置,已跳过生成。");
  174. }
  175. }
  176. else
  177. {
  178. log.Info("查询到本体部待统计数量:0。");
  179. }
  180. #endregion
  181. #region 未统计的驱动部
  182. string dssqls = @"select d.DriveModel,case when ISNULL(d.HandwheelMechanism,'NON') = 'NON' then 1 else 0 end as HandwheelMechanism,b.MFId,a.code
  183. from ERP.U9DB.dbo.CBO_ItemMaster a
  184. join (select ROW_NUMBER() over(partition by PartItemCode order by MFId desc) as Flag,PartItemCode,MFId from ICSPartItem where PartItemName = '') b
  185. on a.code = b.PartItemCode and b.Flag = 1
  186. join IcsMfDriverSpec d on b.MFId = d.MFId
  187. left join ERP.U9DB.dbo.CA_StdWorkingHours c on a.Id = c.ItemMaster
  188. LEFT OUTER JOIN ERP.U9DB.dbo.Base_Organization AS oo ON oo.ID = a.Org
  189. where oo.Code = '01' and c.id is null and a.code like 'A2002%'";
  190. DataTable dsdt = ICSHelper.ExecuteTable(conStr, dssqls);
  191. if (dsdt != null)
  192. {
  193. log.Info("查询到驱动部待统计数量:" + dsdt.Rows.Count + "。");
  194. //准备驱动部条件 ItemModel型号 驱动部类型时此字段为驱动型号
  195. string dsArgsqls = @"select ItemModel,Type,Coefficient,ManHour,AdditiveManHour,HandwheelMechanism
  196. from IcsProductionDurationStatistics
  197. where Type = 2 --and TenantId = ''";
  198. DataTable dsArgdt = ICSHelper.ExecuteTable(conStr, dsArgsqls);
  199. if (dsArgdt != null)
  200. {
  201. //log.Info("驱动部循环开始!");
  202. foreach (DataRow dr in dsdt.Rows)
  203. {
  204. // 驱动部条件过滤 驱动型号、是否有手轮机构
  205. var DriveModel = dr["DriveModel"].ToString().Length > 5 ? dr["DriveModel"].ToString().Substring(0, 5) : dr["DriveModel"].ToString(); // 截取前五位数字符
  206. //log.Info(DriveModel);
  207. DataRow[] infoDsArgRow = dsArgdt?.Select("ItemModel='" + DriveModel
  208. + "' and HandwheelMechanism = '" + dr["HandwheelMechanism"].ToString()
  209. + "'");
  210. if (infoDsArgRow.Length > 0)
  211. {
  212. var Manhour = infoDsArgRow[0]["ManHour"].ToDecimal(); //本体基础工时
  213. var AdditiveManHour = infoDsArgRow[0]["AdditiveManHour"].ToDecimal();//追加工时
  214. var Coefficient = infoDsArgRow[0]["Coefficient"].ToDecimal();//系数
  215. AddList.Add(new AddStdWorkHourItem()
  216. {
  217. ORGCode = "01",//u9 Base_Organization表 的 code 字段 组织编码
  218. WorkHour = (Manhour + AdditiveManHour) * Coefficient / 60, // 驱动部计算逻辑:(本体基础工时型号 + 追加工时) * 系数
  219. CreatedByCode = "",
  220. DepartmentCode = "080502",//部门
  221. ItemCode = dr["code"].ToString()
  222. });
  223. }
  224. else
  225. {
  226. //记录未匹配到条件 统计失败的料号
  227. CErrorCode.Add(dr["code"].ToString() + "(驱动型号:" + dr["DriveModel"].ToString() + ",是否有手轮机构:" + dr["HandwheelMechanism"].ToString() + ");");
  228. }
  229. }
  230. //log.Info("驱动部循环结束!");
  231. }
  232. else
  233. {
  234. log.Info("驱动部待统计数量:" + dsdt.Rows.Count + "。但未查询到驱动部条件配置,已跳过生成。");
  235. }
  236. }
  237. else
  238. {
  239. log.Info("查询到驱动部待统计数量:0。");
  240. }
  241. #endregion
  242. if (AErrorCode.Any())
  243. {
  244. log.Info("未匹配到统计条件的整机料号:" + string.Join(",", AErrorCode) + "。");
  245. }
  246. if (BErrorCode.Any())
  247. {
  248. log.Info("未匹配到统计条件的本体部料号:" + string.Join(",", BErrorCode) + "。");
  249. }
  250. if (CErrorCode.Any())
  251. {
  252. log.Info("未匹配到统计条件的驱动部料号:" + string.Join(",", CErrorCode) + "。");
  253. }
  254. log.Info("创建定额工时Req:" + JsonConvert.SerializeObject(AddList));
  255. if (AddList.Any())
  256. {
  257. var response = await HttpHelper.HttpClientPost<AddStdWorkHourReq>(url, JsonConvert.SerializeObject(AddList));
  258. //返回成功后 用流水号填写 表头产品名称、产品编码、u9料号
  259. if (response != null)
  260. {
  261. if (response.IsOK)
  262. {
  263. log.Info("请求成功。" + response.Message);
  264. }
  265. else
  266. {
  267. log.Info("请求失败。" + response.Message);
  268. }
  269. }
  270. else
  271. {
  272. log.Info("未拿到响应,请求失败。");
  273. }
  274. }
  275. else
  276. {
  277. log.Info("无需请求。");
  278. }
  279. }
  280. catch (Exception ex)
  281. {
  282. log.Error(ex.ToString());
  283. }
  284. }
  285. public static Configuration GetConfig()
  286. {
  287. Assembly assembly = Assembly.GetCallingAssembly();
  288. string path = string.Format("{0}.config", assembly.Location);
  289. if (!File.Exists(path))
  290. {
  291. throw new FileNotFoundException(path + "路径下的文件未找到!");
  292. }
  293. try
  294. {
  295. ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
  296. configFile.ExeConfigFilename = path;
  297. Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
  298. return config;
  299. }
  300. catch (Exception)
  301. {
  302. throw;
  303. }
  304. }
  305. }
  306. /// <summary>
  307. /// 创建定额工时接口入参
  308. /// </summary>
  309. public class AddStdWorkHourItem
  310. {
  311. /// <summary>
  312. /// 组织编码
  313. /// </summary>
  314. public string ORGCode { get; set; }
  315. /// <summary>
  316. /// 料品编码
  317. /// </summary>
  318. public string ItemCode { get; set; }
  319. /// <summary>
  320. /// 创建人编码
  321. /// </summary>
  322. public string CreatedByCode { get; set; }
  323. /// <summary>
  324. /// 工时(单位:小时)
  325. /// </summary>
  326. public decimal WorkHour { get; set; }
  327. /// <summary>
  328. /// 部门编码
  329. /// </summary>
  330. public string DepartmentCode { get; set; }
  331. }
  332. /// <summary>
  333. /// 响应
  334. /// </summary>
  335. public class AddStdWorkHourReq
  336. {
  337. /// <summary>
  338. /// true:成功;false:失败
  339. /// </summary>
  340. public bool IsOK { get; set; }
  341. /// <summary>
  342. /// 消息
  343. /// </summary>
  344. public string Message { get; set; }
  345. }
  346. }