MattressHelper.cs 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  1. using CSUST.Data.Expr;
  2. using DirectService.Tools;
  3. using JLHHJSvr.BLL;
  4. using JLHHJSvr.Com.Model;
  5. using JLHHJSvr.LJException;
  6. using JLHHJSvr.LJFramework.Tools;
  7. using LJLib.DAL.SQL;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Data.SqlClient;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. namespace JLHHJSvr.Helper
  15. {
  16. class MattressHelper : HelperBase
  17. {
  18. private Dictionary<string, object> replacements = new Dictionary<string, object>();
  19. public void CalCulateFormula(u_mattress mattress, List<u_mattress_mx_mtrl> mxlist)
  20. {
  21. InitMattress(mattress);
  22. InitMattressMx(mattress,mxlist);
  23. // 重算床网价格
  24. CalCulateBedNet(mxlist);
  25. InitReplaceMents(mattress);
  26. var diancengList = mxlist.Where(t => t.formulatype == 1).ToList();
  27. var mattersstype = new u_mattress_type() { mattresstypeid = mattress.mattresstypeid };
  28. DbSqlHelper.SelectOne(cmd, mattersstype, "formula_big_side,formula_small_side,formula_v_side");
  29. foreach (var mx in mxlist)
  30. {
  31. if (mx.mtrlid == 0 && mx.formulakind != 31) continue;
  32. if (string.IsNullOrEmpty(mx.formula) && string.IsNullOrEmpty(mx.useformula)) continue;
  33. InitMxReplaceMents(mx);
  34. string expression = ConvertToEnglishSymbols(mx.formula), use_expression = ConvertToEnglishSymbols(mx.useformula);
  35. expression = InitMxSideReplaceMents(mx, diancengList, mattersstype, expression);
  36. use_expression = InitMxSideReplaceMents(mx, diancengList, mattersstype,use_expression);
  37. #region 替换布料幅宽
  38. //大侧
  39. if (new List<int>() { 2,42,52,62,72,82 }.Contains(mx.formulakind.Value))
  40. {
  41. InitMxClothWidthReplaceMents(mx, mxlist,2);
  42. }
  43. //小侧
  44. if (new List<int>() { 3, 43, 53, 63, 73, 83 }.Contains(mx.formulakind.Value))
  45. {
  46. InitMxClothWidthReplaceMents(mx, mxlist,3);
  47. }
  48. //大侧
  49. if (new List<int>() { 4, 44, 54, 64, 74, 84 }.Contains(mx.formulakind.Value))
  50. {
  51. InitMxClothWidthReplaceMents(mx, mxlist,4);
  52. }
  53. //面裥绵
  54. if (new List<int>() { 0, 40, 50, 60, 70, 80, 203 }.Contains(mx.formulakind.Value))
  55. {
  56. InitMxClothWidthReplaceMents(mx, mxlist,0);
  57. }
  58. //底裥绵
  59. if (new List<int>() { 1, 41, 51, 61, 71, 81 }.Contains(mx.formulakind.Value))
  60. {
  61. InitMxClothWidthReplaceMents(mx, mxlist,1);
  62. }
  63. #endregion
  64. #region 替换布套高
  65. //内布套
  66. if (new List<int>() { 101,102,103,104,105,106 }.Contains(mx.formulakind.Value))
  67. {
  68. InitMxClothHeightReplaceMents(mxlist, 101);
  69. }
  70. //外布套
  71. if (new List<int>() { 111, 112, 113, 114, 115, 116 }.Contains(mx.formulakind.Value))
  72. {
  73. InitMxClothHeightReplaceMents(mxlist, 111);
  74. }
  75. #endregion
  76. #region 裥绵收缩率
  77. InitMxShrinkageReplaceMents(mx,mxlist);
  78. #endregion
  79. foreach (var replacement in replacements)
  80. {
  81. expression = expression.Replace(replacement.Key, Convert.ToString(replacement.Value));
  82. use_expression = use_expression.Replace(replacement.Key, Convert.ToString(replacement.Value));
  83. }
  84. #region 计算成本金额
  85. // 判断expression前两个字符是否为@@
  86. bool sqlCal = !string.IsNullOrEmpty(expression) && expression.Substring(0, 2) == "@@";
  87. expression = expression.Replace("@@", "");
  88. mx.replace_formula = expression;
  89. try
  90. {
  91. if (sqlCal)
  92. {
  93. cmd.CommandText = $@"{expression}";
  94. cmd.Parameters.Clear();
  95. var result = cmd.ExecuteScalar();
  96. if(result != null && result != DBNull.Value)
  97. {
  98. mx.costamt = Convert.ToDecimal(result);
  99. }
  100. } else
  101. {
  102. var res = LJExprParser.Parse(expression);
  103. mx.costamt = res.Result.DecimalValue;
  104. }
  105. }
  106. catch (Exception ex)
  107. {
  108. throw new LJCommonException($"计算成本金额公式错误!expression: {expression}" );
  109. }
  110. #endregion
  111. #region 计算清单用量
  112. sqlCal = !string.IsNullOrEmpty(use_expression) && use_expression.Substring(0, 2) == "@@";
  113. use_expression = use_expression.Replace("@@", "");
  114. mx.replace_useformula = use_expression;
  115. try
  116. {
  117. if (sqlCal)
  118. {
  119. cmd.CommandText = $@"{use_expression}";
  120. cmd.Parameters.Clear();
  121. var result = cmd.ExecuteScalar();
  122. if (result != null && result != DBNull.Value)
  123. {
  124. mx.useqty = Convert.ToDecimal(result);
  125. }
  126. }
  127. else
  128. {
  129. var res = LJExprParser.Parse(use_expression);
  130. mx.useqty = res.Result.DecimalValue;
  131. }
  132. }
  133. catch (Exception ex)
  134. {
  135. throw new LJCommonException($"计算清单用量公式错误!expression: {use_expression}");
  136. }
  137. #endregion
  138. }
  139. InitMattressMxListReplaceMents(mattress, mxlist);
  140. }
  141. private void CalCulateBedNet(List<u_mattress_mx_mtrl> mxlist)
  142. {
  143. var bedNetHelper = HelperBase.GetHelper<BedNetHelper>(cmd);
  144. var bednetList = mxlist.Where(t => t.formulatype == 99);
  145. foreach(var mx in bednetList)
  146. {
  147. if (mx.mtrlid <= 0) continue;
  148. var bednet = new u_bednet() { bednetid = mx.mtrlid };
  149. DbSqlHelper.SelectOne(cmd, bednet, "flag");
  150. if (bednet.flag == 1) continue;
  151. bedNetHelper.GetBedNet(bednet);
  152. var bednetMxlist = bedNetHelper.GetBedNetMxList(bednet.bednetid.Value);
  153. var bednetSpringList = bedNetHelper.GetBedNetSpringList(bednet.bednetid.Value);
  154. bedNetHelper.CalCulateFormula(bednet, bednetMxlist, bednetSpringList);
  155. bedNetHelper.SaveBedNet(bednet, bednetMxlist, bednetSpringList);
  156. mx.price = bednet.nottax_factory_cost;
  157. }
  158. }
  159. private void InitMattress(u_mattress mattress)
  160. {
  161. var dept = new u_dept() { deptid = mattress.deptid.Value };
  162. DbSqlHelper.SelectOne(cmd, dept, "pricelistid,profitrate,moneyrate,discount");
  163. var profirate = new u_factory_profitrate() { deptid = mattress.deptid, bednettypeid_mattresstypeid = mattress.mattresstypeid, bednet_or_mattress = 1 };
  164. DbSqlHelper.SelectOne(cmd, profirate, "profitrate");
  165. mattress.pricelistid = dept.pricelistid;
  166. mattress.dept_profitrate = mattress.profitrate;
  167. mattress.profitrate = profirate.profitrate;
  168. mattress.moneyrate = mattress.if_moneyrate == 1 ? dept.moneyrate ?? 1 : 1;
  169. mattress.discount = dept.discount ?? 1 ;
  170. mattress.commission = mattress.commission ?? 1;
  171. mattress.taxrate = mattress.taxrate ?? 1;
  172. mattress.other_rate = mattress.other_rate ?? 1;
  173. mattress.dept_profitrate = mattress.dept_profitrate ?? 0;
  174. // 检查佣金是否小于1
  175. if (mattress.commission < 1)
  176. {
  177. throw new LJCommonException("佣金点数不能小于1!");
  178. }
  179. // 检查税率是否小于1
  180. if (mattress.taxrate < 1)
  181. {
  182. throw new LJCommonException("税率不能小于1!");
  183. }
  184. // 检查额外点数是否小于1
  185. if (mattress.other_rate < 1)
  186. {
  187. throw new LJCommonException("税率不能小于1!");
  188. }
  189. // 检查部门利润率是否为0
  190. if (mattress.dept_profitrate == 0)
  191. {
  192. throw new LJCommonException("部门利润率不能为0!");
  193. }
  194. }
  195. private void InitMattressMx(u_mattress mattress,List<u_mattress_mx_mtrl> mxlist)
  196. {
  197. foreach(var mx in mxlist)
  198. {
  199. var formula = new u_mattress_formula() { formulaid = mx.formulaid, };
  200. DbSqlHelper.SelectOne(cmd, formula, "formulakind,formulatype,sortcode");
  201. var mtrldef = new u_mtrl_price() { mtrlid = mx.mtrlid };
  202. DbSqlHelper.SelectOne(cmd, mtrldef, "name,price,gram_weight,cloth_width,if_inputqty,priceunit,shrinkage,if_areaprice");
  203. mx.formulakind = formula.formulakind;
  204. mx.formulatype = formula.formulatype;
  205. mx.sortcode = formula.sortcode.Trim();
  206. mx.mtrlname = mtrldef.name ?? "";
  207. var formula2 = new u_mattress_formula();
  208. DbSqlHelper.SelectOne(cmd, "u_mattress_formula","formulakind = @formulakind",
  209. new Dictionary<string, object>() { { "@formulakind",mx.formulakind } },formula2, "formula,useformula,gydscrp");
  210. mx.formula = formula2.formula;
  211. mx.useformula = formula2.useformula;
  212. mx.gydscrp = formula2.gydscrp;
  213. cmd.CommandText = @"SELECT isnull(u_mtrl_price_pricelist.price, 0) AS pricelistprice
  214. ,u_mtrl_price.gram_weight
  215. ,u_mtrl_price.cloth_width
  216. ,u_mtrl_price.if_inputqty
  217. ,u_mtrl_price.priceunit
  218. ,u_mtrl_price.shrinkage
  219. ,isnull(u_mtrl_price_pricelist.price_formula, 0) AS price_formula
  220. ,isnull(u_mtrl_price_pricelist.qty_formula, 0) AS qty_formula
  221. ,u_mtrl_price.if_areaprice
  222. ,u_mtrl_price.thickness
  223. FROM u_mtrl_price
  224. INNER JOIN u_mtrl_price_pricelist ON u_mtrl_price.mtrlid = u_mtrl_price_pricelist.mtrlid
  225. WHERE (u_mtrl_price.mtrlid = @mtrlid)
  226. AND (u_mtrl_price_pricelist.pricelistid = @pricelistid)";
  227. cmd.Parameters.Clear();
  228. cmd.Parameters.AddWithValue("@mtrlid", mx.mtrlid);
  229. cmd.Parameters.AddWithValue("@pricelistid", mattress.pricelistid);
  230. using(var reader = cmd.ExecuteReader())
  231. {
  232. if (reader.Read())
  233. {
  234. mx.price = Convert.ToDecimal(reader["pricelistprice"]);
  235. mx.gram_weight = Convert.ToDecimal(reader["gram_weight"]);
  236. mx.cloth_width = Convert.ToDecimal(reader["cloth_width"]);
  237. mx.if_inputqty = Convert.ToInt32(reader["if_inputqty"]);
  238. mx.priceunit = reader["priceunit"].ToString();
  239. mx.shrinkage = Convert.ToDecimal(reader["shrinkage"]);
  240. mx.if_areaprice = Convert.ToByte(reader["if_areaprice"]);
  241. if(mx.if_inputqty == 1) mx.thickness = Convert.ToDecimal(reader["thickness"]);
  242. string price_formula = Convert.ToString(reader["price_formula"]);
  243. string qty_formula = Convert.ToString(reader["qty_formula"]);
  244. mx.formula = string.IsNullOrEmpty(price_formula) ? "" : price_formula;
  245. mx.useformula = string.IsNullOrEmpty(qty_formula) ? "" : qty_formula;
  246. }
  247. }
  248. }
  249. }
  250. private void InitReplaceMents(u_mattress mattress)
  251. {
  252. replacements.Clear();
  253. AddKeyValue("规格宽", mattress.mattress_width);
  254. AddKeyValue("规格长", mattress.mattress_length);
  255. AddKeyValue("规格高", mattress.mattress_height);
  256. AddKeyValue("压包数量", mattress.packqty);
  257. AddKeyValue("卷包直径", mattress.diameter);
  258. AddKeyValue("顶布裥棉外布套做法", mattress.if_db_wbutao_way);
  259. AddKeyValue("面料外布套做法", mattress.if_m_wbutao_way);
  260. AddKeyValue("内布套上覆", mattress.s_cover_qty);
  261. AddKeyValue("内布套侧覆", mattress.z_cover_qty);
  262. AddKeyValue("内布套下覆", mattress.x_cover_qty);
  263. AddKeyValue("面料上覆", mattress.s_m_cover_qty);
  264. AddKeyValue("面料侧覆", mattress.z_m_cover_qty);
  265. AddKeyValue("面料下覆", mattress.x_m_cover_qty);
  266. AddKeyValue("面拆", mattress.if_m_chai);
  267. AddKeyValue("中拆", mattress.if_z_chai);
  268. AddKeyValue("底拆", mattress.if_d_chai);
  269. // 地区FOB费用,如果存在变量表,会替代
  270. AddKeyValue("大柜-普通-地区FOB费用", 6500);
  271. AddKeyValue("大柜-特定-地区FOB费用", 8500);
  272. AddKeyValue("小柜-普通-地区FOB费用", 6000);
  273. AddKeyValue("小柜-特定-地区FOB费用", 7000);
  274. // 柜型立方数
  275. AddKeyValue("大柜-柜型立方数", 64);
  276. AddKeyValue("小柜-柜型立方数", 28);
  277. // 柜型米数
  278. AddKeyValue("大柜-柜型米数", 12);
  279. AddKeyValue("小柜-柜型米数", 5.9);
  280. if (mattress.woodpallettype == 0)
  281. {
  282. AddKeyValue("木托方式", "'普通木托'");
  283. }else if (mattress.woodpallettype == 1)
  284. {
  285. AddKeyValue("木托方式", " '夹板木托'");
  286. }else
  287. {
  288. AddKeyValue("木托方式", "'铁管木托' ");
  289. }
  290. var dept = new u_dept() { deptid = mattress.deptid.Value };
  291. DbSqlHelper.SelectOne(cmd, dept, "pricelistid");
  292. var bednetVarList = new List<u_bednet_var>();
  293. var selectStr = @"SELECT u_bednet_varmx.varid AS varid
  294. ,varkind
  295. ,varcode
  296. ,varname
  297. ,varclass
  298. ,vartype
  299. ,varunit
  300. ,u_bednet_varmx.varvalue AS varvalue
  301. FROM u_bednet_var
  302. INNER JOIN u_bednet_varmx ON u_bednet_varmx.varid = u_bednet_var.varid
  303. INNER JOIN u_dept ON u_dept.pricelistid = u_bednet_varmx.pricelistid";
  304. var whereList = new List<string>();
  305. whereList.Add("u_bednet_var.varkind = @varkind");
  306. whereList.Add("u_dept.deptid = @deptid");
  307. var param = new Dictionary<string, object>();
  308. param.Add("@varkind", 1);
  309. param.Add("@deptid", mattress.deptid);
  310. DbSqlHelper.SelectJoin(cmd, selectStr, ListEx.GetWhereStr(whereList), param, "varid", "varid,varkind,varcode,varname,varclass,vartype,varunit,varvalue", 0, 0, bednetVarList);
  311. foreach (var netvar in bednetVarList)
  312. {
  313. AddKeyValue(netvar.varname, netvar.varvalue);
  314. }
  315. }
  316. private void InitMxReplaceMents(u_mattress_mx_mtrl mx)
  317. {
  318. mx.mtrlname = !string.IsNullOrEmpty(mx.mtrlname) ? mx.mtrlname.Trim() : "null";
  319. mx.shrinkage = mx.shrinkage ?? 1;
  320. //取mtrldef.name的前两位
  321. AddKeyValue("名称前2位", mx.mtrlname.Substring(0, 2));
  322. AddKeyValue("物料单价", mx.price);
  323. AddKeyValue("物料克重", mx.gram_weight);
  324. AddKeyValue("幅宽", mx.cloth_width);
  325. AddKeyValue("数量", mx.qty);
  326. AddKeyValue("物料厚度", mx.if_inputqty);
  327. AddKeyValue("固定厚度", mx.if_inputqty);
  328. AddKeyValue("厚度", mx.thickness);
  329. AddKeyValue("按面积单价", mx.if_areaprice);
  330. AddKeyValue("物料名称", mx.mtrlname);
  331. AddKeyValue("物料收缩率", mx.shrinkage);
  332. }
  333. /// <summary>
  334. /// 添加大侧,小侧,V侧高度公式替换
  335. /// </summary>
  336. /// <param name="mx"></param>
  337. /// <param name="diancengList"></param>
  338. /// <param name="mattersstype"></param>
  339. /// <param name="expression"></param>
  340. /// <returns></returns>
  341. private string InitMxSideReplaceMents(u_mattress_mx_mtrl mx,List<u_mattress_mx_mtrl> diancengList, u_mattress_type mattersstype, string expression)
  342. {
  343. // 获取垫层的数据
  344. decimal bigSum = 0, smallSum = 0, vSum = 0;
  345. string bigChaStr = mx.chastr ?? "大侧";
  346. string smallChaStr = mx.chastr ?? "小侧1";
  347. string vChaStr = mx.chastr ?? "V侧1";
  348. foreach (var dianceng in diancengList)
  349. {
  350. if (dianceng.chastr.IndexOf(bigChaStr) > -1) bigSum += dianceng.qty.Value * dianceng.thickness.Value;
  351. if (dianceng.chastr.IndexOf(smallChaStr) > -1) smallSum += dianceng.qty.Value * dianceng.thickness.Value;
  352. if (dianceng.chastr.IndexOf(vChaStr) > -1) vSum += dianceng.qty.Value * dianceng.thickness.Value;
  353. }
  354. if (bigSum > 0)
  355. {
  356. AddKeyValue("大侧高度", bigSum);
  357. }
  358. if (smallSum > 0)
  359. {
  360. AddKeyValue("小侧高度", smallSum);
  361. }
  362. if (vSum > 0)
  363. {
  364. AddKeyValue("V侧高度", vSum);
  365. }
  366. #region 替换大侧高度
  367. if (expression.IndexOf("【大侧高度】") > -1)
  368. {
  369. if (!string.IsNullOrEmpty(mattersstype.formula_big_side)) expression = expression.Replace("【大侧高度】", $"({mattersstype.formula_big_side})");
  370. expression = expression.Replace("【位置】", $"'{bigChaStr}'");
  371. }
  372. #endregion
  373. #region 替换小侧高度
  374. if (expression.IndexOf("【小侧高度】") > -1)
  375. {
  376. if (!string.IsNullOrEmpty(mattersstype.formula_small_side)) expression = expression.Replace("【小侧高度】", $"({mattersstype.formula_small_side})");
  377. expression = expression.Replace("【位置】", $"'{smallChaStr}'");
  378. }
  379. #endregion
  380. #region 替换V侧高度
  381. if (expression.IndexOf("【V侧高度】") > -1)
  382. {
  383. if(!string.IsNullOrEmpty(mattersstype.formula_v_side)) expression = expression.Replace("【V侧高度】", $"({mattersstype.formula_v_side})");
  384. expression = expression.Replace("【位置】", $"'{vChaStr}'");
  385. }
  386. #endregion
  387. return expression;
  388. }
  389. /// <summary>
  390. /// 添加布料幅宽公式替换
  391. /// </summary>
  392. /// <param name="mx"></param>
  393. /// <param name="mxlist"></param>
  394. /// <param name="formulakind"></param>
  395. private void InitMxClothWidthReplaceMents(u_mattress_mx_mtrl mx, List<u_mattress_mx_mtrl> mxlist,int formulakind)
  396. {
  397. decimal cloth_width = 0;
  398. if (string.IsNullOrEmpty(mx.chastr))
  399. {
  400. cloth_width = mxlist.First(t => t.formulakind.Value == formulakind).cloth_width.Value;
  401. }
  402. else
  403. {
  404. cloth_width = mxlist.First(t => t.formulakind.Value == formulakind && t.chastr.Equals(mx.chastr)).cloth_width.Value;
  405. }
  406. AddKeyValue("布料幅宽", cloth_width);
  407. }
  408. /// <summary>
  409. /// 添加布套高公式替换
  410. /// </summary>
  411. /// <param name="mxlist"></param>
  412. /// <param name="formulakind"></param>
  413. private void InitMxClothHeightReplaceMents(List<u_mattress_mx_mtrl> mxlist, int formulakind)
  414. {
  415. decimal cloth_height = 0;
  416. cloth_height = mxlist.First(t => t.formulakind.Value == formulakind).thickness.Value;
  417. AddKeyValue("布套高", cloth_height);
  418. }
  419. /// <summary>
  420. /// 添加裥绵收缩率公式替换
  421. /// </summary>
  422. /// <param name="mx"></param>
  423. /// <param name="mxlist"></param>
  424. private void InitMxShrinkageReplaceMents(u_mattress_mx_mtrl mx, List<u_mattress_mx_mtrl> mxlist)
  425. {
  426. decimal thickness = 0, shrinkage = 0;
  427. if(new List<int>() { 0,40,50,60,70,80,1,41, 51,61,71,81, 2,42,52,62,72,82,3,43, 53,63,73,83,4,44, 54,64,74,84 }.Contains(mx.formulakind.Value))
  428. {
  429. foreach (var row in mxlist) // mxList.Rows等价于arg_dw.RowCount()
  430. {
  431. if (new List<int>() { 50, 51, 52, 53, 54 }.Contains(row.formulakind.Value))
  432. {
  433. // 如果当前行的公式种类匹配
  434. thickness += row.thickness.Value * row.qty.Value; // 简化计算
  435. }
  436. }
  437. }
  438. if(thickness > 0)
  439. {
  440. cmd.CommandText = @"SELECT TOP 1 shrinkage
  441. FROM u_shrinkage
  442. WHERE u_shrinkage.minvalue <= @thickness
  443. AND u_shrinkage.maxvalue >= @thickness";
  444. cmd.Parameters.Clear();
  445. cmd.Parameters.AddWithValue("@thickness", thickness);
  446. using(var reader = cmd.ExecuteReader())
  447. {
  448. if (reader.Read())
  449. {
  450. shrinkage = Convert.ToDecimal(reader["shrinkage"]);
  451. }
  452. }
  453. }
  454. if(shrinkage > 0)
  455. {
  456. AddKeyValue("收缩率", shrinkage);
  457. }
  458. }
  459. /// <summary>
  460. /// 添加主表与明细表相关公式替换
  461. /// </summary>
  462. /// <param name="mattress"></param>
  463. /// <param name="mxlist"></param>
  464. private void InitMattressMxListReplaceMents(u_mattress mattress,List<u_mattress_mx_mtrl> mxlist)
  465. {
  466. string fob_expression = string.Empty,cubage_expression = string.Empty;
  467. cubage_expression = "(【规格长】*【规格宽】* 【规格高】)/100000";
  468. #region 判断装柜方式 是否进箱
  469. if (mattress.packtype == 0)
  470. {
  471. mattress.loading_type = "平压";
  472. fob_expression = "【地区FOB费用】/(【柜型米数】 /(【规格宽】/ 100 +0.1)*(【压包数量】*2))";
  473. if (mattress.packqty == 0) throw new LJCommonException("请填写压包数量!");
  474. }
  475. else if (mattress.packtype == 1)
  476. {
  477. mattress.loading_type = "卷包(非进箱)";
  478. fob_expression = "【地区FOB费用】 /(【柜型立方数】 /( 3.14*( 【卷包直径】 /100/2+0.03)*( 【卷包直径】 /100/2+0.03)*(【规格宽】/ 100 +0.05)))";
  479. cubage_expression = "( 3.14*( 【卷包直径】 /100/2+0.03)*( 【卷包直径】 /100/2+0.03)*(【规格宽】/ 100 +0.05))";
  480. if (mattress.packqty == 0) throw new LJCommonException("请填写卷包直径!");
  481. var bzList = mxlist.Where(t => t.formulatype == 3 && t.formulakind == 19).ToList();
  482. foreach(var bz in bzList)
  483. {
  484. if (bz.mtrlname.IndexOf("箱") > -1) {
  485. mattress.loading_type = "卷包(进箱)";
  486. fob_expression = "【地区FOB费用】/(【柜型立方数】 / (( 【纸箱宽】 /100+0.03)*(【纸箱宽】/100+0.03)*(【规格宽】/ 100 +0.1)))";
  487. cubage_expression = "( 【纸箱宽】 /100+0.03)*(【纸箱宽】/100+0.03)*(【规格宽】/ 100 +0.1)";
  488. AddKeyValue("【纸箱宽】", bz.mtrlname.Substring(0, 2));
  489. break;
  490. }
  491. }
  492. }
  493. else if (mattress.packtype == 2)
  494. {
  495. mattress.loading_type = "国内";
  496. fob_expression = "【地区FOB费用】/(【柜型立方数】/((【规格宽】/100+0.03)*(【规格长】/100+0.03)*(【规格高】/100+0.03)))";
  497. }
  498. #endregion
  499. #region 计算FOB
  500. if (string.IsNullOrEmpty(mattress.area) || string.IsNullOrEmpty(mattress.cabinet_type) || string.IsNullOrEmpty(mattress.loading_type)) return;
  501. //地区FOB费用
  502. if (new List<string>() { "大柜", "小柜" }.Contains(mattress.cabinet_type) && new List<string>() { "普通地区", "特定地区" }.Contains(mattress.area))
  503. {
  504. fob_expression = fob_expression.Replace("【地区FOB费用】", $"【{mattress.cabinet_type.Trim()}-{mattress.area.Trim()}-地区FOB费用】");
  505. }
  506. //柜型立方数
  507. if (new List<string>() { "大柜", "小柜" }.Contains(mattress.cabinet_type))
  508. {
  509. fob_expression = fob_expression.Replace("【柜型立方数】", $"【{mattress.cabinet_type.Trim()}-柜型立方数】");
  510. }
  511. //纸箱宽 见上面
  512. //柜型米数
  513. if (new List<string>() { "大柜", "小柜" }.Contains(mattress.cabinet_type))
  514. {
  515. fob_expression = fob_expression.Replace("【柜型米数】", $"【{mattress.cabinet_type.Trim()}-柜型米数】");
  516. }
  517. try
  518. {
  519. mattress.fob_replace_formula = fob_expression;
  520. var res = Calculate(fob_expression);
  521. mattress.fob = res.DecimalValue;
  522. //半成品:如果PE袋物料是含 半成品专用 的编码,FOB需要除以数量
  523. var bzList = mxlist.Where(t => t.formulatype == 3).ToList();
  524. foreach(var bz in bzList)
  525. {
  526. if(bz.qty.Value > 0 && bz.mtrlname.IndexOf("半成品专用") > -1)
  527. {
  528. mattress.fob /= bz.qty.Value;
  529. mattress.fob_replace_formula = $"{mattress.fob_replace_formula} / {bz.qty.Value}";
  530. }
  531. }
  532. }
  533. catch (Exception ex)
  534. {
  535. throw new LJCommonException($"计算FOB公式错误!expression: {fob_expression}");
  536. }
  537. #endregion
  538. #region 计算体积
  539. if (mattress.fob > 0)
  540. {
  541. try
  542. {
  543. var res = Calculate(cubage_expression);
  544. mattress.cubage = res.DecimalValue;
  545. }
  546. catch (Exception ex)
  547. {
  548. throw new LJCommonException($"计算体积公式错误!expression: {cubage_expression}");
  549. }
  550. }
  551. #endregion
  552. #region 计算人工费用
  553. var mattersstype = new u_mattress_type() { mattresstypeid = mattress.mattresstypeid };
  554. DbSqlHelper.SelectOne(cmd, mattersstype, "hrcost_formula,biandaiqty,zhizao_amt,guanli_rate");
  555. if(mattress.biandai_qty == 0 && mattress.if_m_chai == 0 && mattress.if_z_chai == 0 && mattress.if_d_chai == 0)
  556. {
  557. mattress.biandai_qty = mattersstype.biandaiqty;
  558. }
  559. mattress.hrcost_replace_formula = mattersstype.hrcost_formula;
  560. mattress.zhizao_amt = mattersstype.zhizao_amt;
  561. mattress.guanli_rate = mattersstype.guanli_rate;
  562. var diancengList = mxlist.Where(t => t.formulatype == 1).ToList();
  563. int diancengCount = 0;
  564. foreach(var dianceng in diancengList)
  565. {
  566. if (dianceng.formulatype == 32) diancengCount++;
  567. }
  568. AddKeyValue("垫层数量", diancengCount);
  569. try
  570. {
  571. var res = Calculate(mattress.hrcost_replace_formula);
  572. mattress.hrcost = res.DecimalValue;
  573. }
  574. catch (Exception ex)
  575. {
  576. throw new LJCommonException($"计算款式费用公式错误!expression: {mattress.hrcost_replace_formula}");
  577. }
  578. #endregion
  579. #region 计算边带费用
  580. mattress.biandaicost_replace_formula = "【边带条数】*【边带单价】*((【规格宽】+【规格长】)*2+30)/100";
  581. AddKeyValue("边带条数", mattress.biandai_qty);
  582. try
  583. {
  584. var res = Calculate(mattress.biandaicost_replace_formula);
  585. mattress.biandaicost = res.DecimalValue;
  586. }
  587. catch (Exception ex)
  588. {
  589. throw new LJCommonException($"计算边带费用公式错误!expression: {mattress.biandaicost_replace_formula}");
  590. }
  591. #endregion
  592. #region 辅料 有打钮纽扣 加0.13 工厂利润率
  593. var fuliaoList = mxlist.Where(t => t.formulatype == 2 && t.mtrlname.IndexOf("打钮") > -1).ToList();
  594. if (fuliaoList.Any()) mattress.profitrate += 0.13M;
  595. #endregion
  596. #region 拼侧 最大金额的侧 和 工厂利润率加点
  597. CalCulatePince(mattress, mxlist);
  598. #endregion
  599. #region 内布套特殊加点
  600. if(mattress.if_n_butao == 1) CalCulateNetBuTao(mattress, mxlist);
  601. #endregion
  602. #region 拆装特殊加点
  603. CalCulateChaiZhuang(mattress);
  604. #endregion
  605. #region 海绵款特殊扣点
  606. if (mattress.if_haimian_type == 1) CalCulateHaiMian(mattress);
  607. #endregion
  608. #region 计算主表 总材料成本
  609. mattress.total_material_cost = mxlist.Sum(t => t.costamt);
  610. #endregion
  611. CalCulateCost(mattress, "标准");
  612. CalCulateCost(mattress, "大单");
  613. CalCulateCost(mattress, "散单");
  614. }
  615. /// <summary>
  616. /// 计算拼侧最大金额的侧和工厂利润率加点
  617. /// </summary>
  618. /// <param name="mattress"></param>
  619. /// <param name="mxlist"></param>
  620. private void CalCulatePince(u_mattress mattress, List<u_mattress_mx_mtrl> mxlist)
  621. {
  622. var mianliaoList = mxlist.Where(t => t.formulatype == 0).ToList();
  623. var costAmounts = new Dictionary<string, decimal>
  624. {
  625. { "普通大侧", 0m },
  626. { "上下拼侧1", 0m },
  627. { "上下拼侧2", 0m },
  628. { "上下拼侧3", 0m },
  629. { "左右拼侧1", 0m },
  630. { "左右拼侧2", 0m },
  631. { "左右拼侧3", 0m },
  632. { "左右拼侧4", 0m }
  633. };
  634. var costAmounts2 = new Dictionary<string, decimal>
  635. {
  636. { "小侧1-上下拼侧1", 0m },
  637. { "小侧1-上下拼侧2", 0m },
  638. { "小侧1-上下拼侧3", 0m }
  639. };
  640. foreach (var mianliao in mianliaoList)
  641. {
  642. if (costAmounts.ContainsKey(mianliao.sortcode))
  643. {
  644. costAmounts[mianliao.sortcode] += mianliao.costamt.Value;
  645. }else if (costAmounts2.ContainsKey(mianliao.sortcode))
  646. {
  647. costAmounts2[mianliao.sortcode] += mianliao.costamt.Value;
  648. }
  649. }
  650. // 找出最大拼侧金额及对应的拼侧名称
  651. string lsTempMaxStr = costAmounts.OrderByDescending(x => x.Value).First().Key;
  652. decimal ldeTempMax = costAmounts[lsTempMaxStr];
  653. // 清空不是最大金额的拼侧
  654. foreach (var mianliao in mianliaoList)
  655. {
  656. if (mianliao.sortcode != lsTempMaxStr && new List<int>() { 2, 82, 42, 52, 62, 72 }.Contains(mianliao.formulakind.Value))
  657. {
  658. mianliao.costamt = 0;
  659. }
  660. }
  661. // 找出最大小侧拼侧金额及对应的拼侧名称
  662. string lsTempMaxStr2 = costAmounts2.OrderByDescending(x => x.Value).First().Key;
  663. decimal ldeTempMax2 = costAmounts2[lsTempMaxStr2];
  664. // 清空不是最大金额的拼侧
  665. foreach (var mianliao in mianliaoList)
  666. {
  667. if (mianliao.sortcode != lsTempMaxStr2 && new List<int>() { 3, 83, 43, 53, 63, 73 }.Contains(mianliao.formulakind.Value))
  668. {
  669. mianliao.costamt = 0;
  670. }
  671. }
  672. // 计算拼侧数量
  673. int pinceCnt = costAmounts.Values.Count(value => value > 0);
  674. // 判断是否有大侧
  675. bool hasBigSide = mianliaoList.Any(row => new[] { 7, 8, 9, 10 }.Contains(row.formulakind.Value) && row.mtrlid.Value > 0);
  676. string field = pinceCnt > 3 || (hasBigSide && (pinceCnt == 2 || pinceCnt == 3)) ? "num_3" : hasBigSide ? "num_1" : pinceCnt == 2 || pinceCnt == 3 ? "num_2" : string.Empty;
  677. // 查找点数
  678. var workmanship = new u_workmanship_add() { deptid = mattress.deptid, mattresstypeid = mattress.mattresstypeid, workmanshipname = field };
  679. mattress.profitrate_point = workmanship.rate;
  680. }
  681. /// <summary>
  682. /// 计算内布套特殊加点
  683. /// </summary>
  684. /// <param name="mattress"></param>
  685. /// <param name="mxlist"></param>
  686. private void CalCulateNetBuTao(u_mattress mattress, List<u_mattress_mx_mtrl> mxlist)
  687. {
  688. var butaoList = mxlist.Where(t => t.formulatype == 101 || t.formulatype == 102);
  689. bool butaoFz = false, butaoJd = false;
  690. // 检查内布套是否为复杂款
  691. foreach (var butao in butaoList) {
  692. if (butao.formulakind == 70 && butao.mtrlid > 0) { butaoFz = true; break; }
  693. }
  694. if (butaoFz)
  695. {
  696. foreach (var butao in butaoList)
  697. {
  698. if (butao.formulakind == 203 && butao.mtrlid > 0) { butaoFz = true; break; }
  699. }
  700. }
  701. else
  702. {
  703. butaoJd = true; // 没有找到复杂款即为简单款
  704. }
  705. // 根据款式类型判断查询的字段
  706. string field = butaoJd ? "num_4" : (butaoFz ? "num_5" : "");
  707. // 查找点数
  708. var workmanship = new u_workmanship_add() { deptid = mattress.deptid, mattresstypeid = mattress.mattresstypeid, workmanshipname = field };
  709. mattress.butao_point = workmanship.rate;
  710. }
  711. /// <summary>
  712. /// 拆装特殊加点
  713. /// </summary>
  714. /// <param name="mattress"></param>
  715. private void CalCulateChaiZhuang(u_mattress mattress)
  716. {
  717. int cnt = 0;
  718. // 判断 if_m_chai, if_z_chai, if_d_chai 是否为 1
  719. if (Convert.ToInt32(mattress.if_m_chai) == 1) cnt++;
  720. if (Convert.ToInt32(mattress.if_z_chai) == 1) cnt++;
  721. if (Convert.ToInt32(mattress.if_d_chai) == 1) cnt++;
  722. // 根据款式类型判断查询的字段
  723. string field = cnt == 1 ? "num_6" : (cnt > 1 ? "num_7" : "");
  724. // 查找点数
  725. var workmanship = new u_workmanship_add() { deptid = mattress.deptid, mattresstypeid = mattress.mattresstypeid, workmanshipname = field };
  726. mattress.chaizhuang_point = workmanship.rate;
  727. }
  728. /// <summary>
  729. /// 计算海绵款特殊扣点
  730. /// </summary>
  731. /// <param name="mattress"></param>
  732. private void CalCulateHaiMian(u_mattress mattress)
  733. {
  734. // 根据款式类型判断查询的字段
  735. string field = "num_8";
  736. // 查找点数
  737. var workmanship = new u_workmanship_add() { deptid = mattress.deptid, mattresstypeid = mattress.mattresstypeid, workmanshipname = field };
  738. mattress.haimian_point = workmanship.rate;
  739. }
  740. /// <summary>
  741. /// 计算大小单加点
  742. /// </summary>
  743. /// <param name="mattress"></param>
  744. /// <param name="typename"></param>
  745. private void CalCulateDanNum(u_mattress mattress,string typename)
  746. {
  747. // 根据款式类型判断查询的字段
  748. string field = "散单".Equals(typename) ? "num_9" : "标准".Equals(typename) ? "num_10" : "大单".Equals(typename) ? "num_11" : "";
  749. // 查找点数
  750. var workmanship = new u_workmanship_add() { deptid = mattress.deptid, mattresstypeid = mattress.mattresstypeid, workmanshipname = field };
  751. mattress.dannum_rate = workmanship.rate;
  752. }
  753. /// <summary>
  754. /// 计算成本
  755. /// </summary>
  756. /// <param name="mattress"></param>
  757. /// <param name="typename"></param>
  758. private void CalCulateCost(u_mattress mattress, string typename)
  759. {
  760. #region 计算主表 总成本
  761. CalCulateDanNum(mattress, typename);
  762. mattress.total_cost = mattress.total_material_cost * mattress.dannum_rate + mattress.hrcost + mattress.biandaicost + mattress.extras_cost + mattress.zhizao_amt;
  763. if (mattress.if_zhedie_type == 1) mattress.total_cost *= 2;
  764. #endregion
  765. #region 不含税出厂价=总成本*工厂利润率
  766. mattress.nottax_factory_cost = mattress.total_cost * (mattress.profitrate + mattress.profitrate_point + mattress.butao_point + mattress.chaizhuang_point + mattress.haimian_point) * mattress.guanli_rate;
  767. #endregion
  768. #region 部门不含税价=不含税出厂价*部门利润率*佣金点数 * 额外点数 +FOB
  769. mattress.nottax_dept_cost = mattress.nottax_factory_cost /
  770. (mattress.dept_profitrate
  771. + mattress.dept_profitrate_rangli / 100)
  772. / (1 - (mattress.commission - 1))
  773. * mattress.other_rate
  774. + mattress.fob;
  775. #endregion
  776. #region 税金 = 部门不含税价 * 税率
  777. mattress.taxes = mattress.nottax_dept_cost * (mattress.taxrate - 1);
  778. //问题1,税金增加需加上佣金*0.05 #TODO
  779. decimal lde_rj = 0;
  780. mattress.taxes += lde_rj * 0.05M;
  781. #endregion
  782. #region 部门含税价=(部门不含税价+佣金*0.06)*税率*折扣率(fob>0)
  783. if (mattress.fob == 0) mattress.discount = 1;
  784. mattress.dept_cost = (mattress.nottax_dept_cost + lde_rj * 0.06m)
  785. * mattress.taxrate
  786. * mattress.discount;
  787. #endregion
  788. #region 外币价= 部门含税价/汇率
  789. if(mattress.moneyrate > 0)
  790. {
  791. if ("标准".Equals(typename)) mattress.foreign_cost_bz = mattress.dept_cost / mattress.moneyrate;
  792. else if ("大单".Equals(typename)) mattress.foreign_cost_dd = mattress.dept_cost / mattress.moneyrate;
  793. else if ("散单".Equals(typename)) mattress.foreign_cost = mattress.dept_cost / mattress.moneyrate;
  794. }
  795. #endregion
  796. }
  797. private void AddKeyValue(string key, object value, bool isReplace = true)
  798. {
  799. key = $"【{key}】";
  800. if (!replacements.ContainsKey(key))
  801. {
  802. replacements.Add(key, value);
  803. }
  804. else if (isReplace)
  805. {
  806. replacements[key] = value;
  807. }
  808. }
  809. private string ConvertToEnglishSymbols(string input)
  810. {
  811. input = input.Replace("(", "(")
  812. .Replace(")", ")")
  813. .Replace(",", ",")
  814. .Replace("。", ".")
  815. .Replace(":", ":")
  816. .Replace(";", ";")
  817. .Replace("“", "\"")
  818. .Replace("”", "\"")
  819. .Replace("‘", "'")
  820. .Replace("’", "'");
  821. return input;
  822. }
  823. private TData Calculate(string expression)
  824. {
  825. ConvertToEnglishSymbols(expression);
  826. foreach (var replacement in replacements)
  827. {
  828. expression = expression.Replace(replacement.Key, Convert.ToString(replacement.Value));
  829. }
  830. var res = LJExprParser.Parse(expression);
  831. return res.Result;
  832. }
  833. public void SaveMattress(u_mattress mattress,List<u_mattress_mx_mtrl> mxlist)
  834. {
  835. var fields = "mattressname, deptid, mattresscode, mattresstypeid, mattress_width, mattress_length, mattress_height, packtype, packqty, woodpallettype, total_hr_cost, total_material_cost, fees_dscrp, total_fees_cost, total_cost, taxrate, taxes, commissionrate, commission, fob, profitrate, dept_profitrate, moneyrate, nottax_factory_cost, nottax_dept_cost, foreign_cost, diameter, area, cabinet_type, hrcost, biandaicost, createtime, createby, mattressrelcode, other_rate, flag, dept_profitrate_rangli, profitrate_point, if_moneyrate, discount, if_m_chai, if_z_chai, if_d_chai, if_n_butao, if_w_butao, if_m_wbutao_way, s_cover_qty, z_cover_qty, x_cover_qty, biandai_qty, s_m_cover_qty, z_m_cover_qty, x_m_cover_qty, chaizhuang_point, haimian_point, if_zhedie_type, qr_auditingrep, qr_auditingdate, if_bcp_type, zhizao_amt, foreign_cost_bz, cubage";
  836. var fieldsMx = "mattressmxid,mattressid,formulaid,formula,replace_formula,if_success,priceunit,shrinkage,mtrlid,price,gram_weight,cloth_width,if_inputqty,qty ,costamt,if_areaprice,thickness,chastr,xu,useqty,useformula,replace_useformula,gydscrp";
  837. if (mattress.mattressid <= 0)
  838. {
  839. //新建
  840. mattress.createtime = context.opdate;
  841. mattress.createby = context.tokendata.username;
  842. mattress.mattressid = BllHelper.GetID(cmd, "u_mattress");
  843. fields = "mattressid," + fields;
  844. var mattresstype = new u_mattress_type() { mattresstypeid = mattress.mattresstypeid };
  845. DbSqlHelper.SelectOne(cmd, mattresstype, "typecode");
  846. mattress.mattresscode = $"{mattresstype.typecode}-{context.opdate.ToString("yyyyMMdd")}{(mattress.mattressid % 10000).ToString("D4")}";
  847. DbSqlHelper.Insert(cmd, "u_mattress", null, mattress, fields);
  848. }
  849. else
  850. {
  851. // 删除所有明细
  852. cmd.CommandText = @"DELETE u_mattress_mx_mtrl WHERE mattressid = @mattressid";
  853. cmd.Parameters.Clear();
  854. cmd.Parameters.AddWithValue("@mattressid", mattress.mattressid);
  855. cmd.ExecuteNonQuery();
  856. DbSqlHelper.Update(cmd, "u_mattress", null, mattress, "mattressid", fields);
  857. }
  858. if (mxlist != null && mxlist.Any())
  859. {
  860. foreach (var item in mxlist)
  861. {
  862. item.mattressid = mattress.mattressid;
  863. if (item.mattressmxid == null || item.mattressmxid <= 0)
  864. {
  865. item.mattressmxid = BllHelper.GetID(cmd, "u_mattress_mx_mtrl");
  866. }
  867. DbSqlHelper.Insert(cmd, "u_mattress_mx_mtrl", null, item, fieldsMx);
  868. }
  869. }
  870. // 更新计价历史
  871. var hisprice = new u_his_price
  872. {
  873. bednetid_mattressid = mattress.mattressid,
  874. typeid = 1,
  875. cmpdate = context.opdate,
  876. cmpemp = context.tokendata.username,
  877. nottax_dept_cost = mattress.nottax_dept_cost,
  878. dept_cost = mattress.dept_cost,
  879. foreign_cost = mattress.foreign_cost
  880. };
  881. var fieldsHs = "bednetid_mattressid, typeid, cmpdate, cmpemp, nottax_dept_cost, dept_cost, foreign_cost";
  882. DbSqlHelper.Insert(cmd, "u_his_price", null, hisprice, fieldsHs);
  883. }
  884. }
  885. }