using CSUST.Data.Expr;
using DirectService.Tools;
using JLHHJSvr.BLL;
using JLHHJSvr.Com.Model;
using JLHHJSvr.LJException;
using JLHHJSvr.LJFramework.Tools;
using LJLib.DAL.SQL;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static JLHHJSvr.Helper.CacheHelper;

namespace JLHHJSvr.Helper
{
    internal class BedNetHelper : HelperBase
    {
        private Dictionary<string, object> replacements = new Dictionary<string, object>();
        /// <summary>
        /// 默认展示公式
        /// </summary>
        private Dictionary<string, formulaItem> formula_replacements = new Dictionary<string, formulaItem>();
        /// <summary>
        /// 隐藏公式
        /// </summary>
        private Dictionary<string, formulaItem> formula_replacements_hide = new Dictionary<string, formulaItem>();
        /// <summary>
        /// 详细展示公式
        /// </summary>
        private Dictionary<string, formulaItem> formula_replacements_mx = new Dictionary<string, formulaItem>();
        /// <summary>
        /// 重量展示公式
        /// </summary>
        private Dictionary<string, formulaItem> formula_replacements_weight = new Dictionary<string, formulaItem>();

        public sealed class formulaItem
        {
            public string value { get; set; }
            public int? ifnotreplace { get; set; }
        }
        public List<replacement> Replacements
        {
            get
            {
                var res = new List<replacement>();
                foreach (var item in replacements)
                {
                    res.Add(new replacement { label = item.Key, value = item.Value, type = 0 });
                }
                return res;
            }
        }
        public List<replacement> FormulaReplacements
        {
            get {
                var res = new List<replacement>();
                foreach (var item in formula_replacements)
                {
                    res.Add(new replacement { label = item.Key, value = item.Value.value, type = 0, ifnotreplace = item.Value.ifnotreplace});
                }
                foreach (var item in formula_replacements_hide)
                {
                    res.Add(new replacement { label = item.Key, value = item.Value.value, type = 1, ifnotreplace = item.Value.ifnotreplace });
                }
                foreach (var item in formula_replacements_mx)
                {
                    res.Add(new replacement { label = item.Key, value = item.Value.value, type = 2, ifnotreplace = item.Value.ifnotreplace });
                }
                foreach (var item in formula_replacements_weight)
                {
                    res.Add(new replacement { label = item.Key, value = item.Value.value, type = 3, ifnotreplace = item.Value.ifnotreplace });
                }
                return res; 
            }
        }

        /// <summary>
        /// 计算床网报价
        /// </summary>
        /// <param name="bednet"></param>
        /// <param name="mxlist"></param>
        /// <param name="springList"></param>
        /// <param name="isCalBed">是否实时获取信息</param>
        /// <param name="isNewFormula">是否获取新的公式计算</param>
        public void CalCulateFormula(u_bednet bednet, List<u_bednetmx> mxlist, List<u_bednetmx_spring> springList, Boolean isCalBed = true, Boolean isNewFormula = true)
        {
            InitBedNet(bednet, isCalBed);

            InitReplaceMents(bednet, isCalBed);

            CulcalateCost(bednet, mxlist, springList, isNewFormula);

            CulcalateWeight(bednet, mxlist, springList);


            if (formula_replacements_hide.Count > 0)
            {
                foreach (var replacement in formula_replacements_hide)
                {
                    var _key = replacement.Key.Replace("【", "").Replace("】", "");
                    var value = CalculateVarFormula(_key).DecimalValue;
                    AddKeyValue(_key, value);
                }
            }
        }
        /// <summary>
        /// 获取损耗率
        /// </summary>
        /// <param name="mtrltype"></param>
        /// <returns></returns>
        public decimal GetSumhaoRate(int mtrltype)
        {
            decimal _rate = 0; //损耗率浮动数 
            var mtrlType = new u_mtrltype() { mtrltypeid = mtrltype };
            DbSqlHelper.SelectOne(cmd, mtrlType, "dannum1_rate, dannum2_rate, dannum3_rate, dannum4_rate");

            var dannumType = 1;
            if (replacements.TryGetValue("【大小单类型】", out object value1))
            {
                dannumType = Convert.ToInt32(value1);
            }
            switch (dannumType)
            {
                case 1:
                    _rate = mtrlType.dannum1_rate.Value;
                    break;
                case 2:
                    _rate = mtrlType.dannum2_rate.Value;
                    break;
                case 3:
                    _rate = mtrlType.dannum3_rate.Value;
                    break;
                case 4:
                    _rate = mtrlType.dannum4_rate.Value;
                    break;
            }

            return _rate;
        }

        private void CulcalateCost(u_bednet bednet, List<u_bednetmx> mxlist, List<u_bednetmx_spring> springList, Boolean isNewFormula = true)
        {
            bednet.spring_mtrl_cost = 0;
            bednet.spring_hr_cost = 0;
            bednet.snake_wire_mtrl_cost = 0;
            bednet.pocket_around_spring_cost = 0;
            bednet.pocket_around_fabrics_cost = 0;
            bednet.hard_around_mtrl_cost = 0;
            bednet.hard_around_hr_cost = 0;
            bednet.fabrics1_mtrl_cost = 0;
            bednet.glue_mtrl_cost = 0;
            bednet.fabrics2_mtrl_cost = 0;
            bednet.side_iron_hr_cost = 0;
            bednet.side_iron_mtrl_cost = 0;
            bednet.cnail_mtrl_cost = 0;
            bednet.cnail_hr_cost = 0;
            bednet.sponge_mtrl_cost = 0;
            bednet.sponge_hr_cost = 0;
            bednet.sponge_mtrl_tc_cost = 0;
            bednet.edge_mtrl_cost = 0;
            bednet.edge_hr_cost = 0;
            bednet.fork_mtrl_cost = 0;
            bednet.fork_hr_cost = 0;
            bednet.rsorwa_mtrl_cost = 0;
            bednet.rsorwa_hr_cost = 0;
            bednet.sponge_drilling_hr_cost = 0;
            bednet.felt_mtrl_cost = 0;
            bednet.felt_mtrl_x_cost = 0;
            bednet.felt_hr_cost = 0;
            bednet.felt_hr_x_cost = 0;
            bednet.packet_mtrl_cost = 0;
            bednet.packet_hr_cost = 0;

            foreach (var mx in mxlist)
            {
                var spring = Cache.GetData<u_spring,SpringMapping>(mx.springid.Value);

                // 处理相同公式部分
                InitMxReplaceMents(bednet, mx, spring);

                //计算 弹簧材料总成本
                #region 计算 弹簧材料总成本 开始
                if (!string.IsNullOrEmpty(bednet.spring_mtrl_formula))
                {
                    AddKeyValue("每米/重", 0.298);
                    var _formula = bednet.spring_mtrl_formula;
                    mx.spring_mtrl_cost_replace_formula = bednet.spring_mtrl_formula;
                    if (mx.if_part == 0)
                    {
                        //单分区
                        //考虑 四周加硬和四周口袋  扣减 排列数情况
                        if (mx.if_hard_around == 1)
                        {
                            decimal hard_around_row = mx.hard_around_row.Value;
                            if (bednet.typename.IndexOf("袋装", StringComparison.Ordinal) >= 0) hard_around_row *= 2;

                            mx.spring_mtrl_cost_replace_formula = mx.spring_mtrl_cost_replace_formula.Replace("【弹簧排列个数-宽】", $"(【弹簧排列个数-宽】 - {hard_around_row})");
                            mx.spring_mtrl_cost_replace_formula = mx.spring_mtrl_cost_replace_formula.Replace("【弹簧计算个数(宽)】", $"(【弹簧计算个数(宽)】 - {hard_around_row})");
                            mx.spring_mtrl_cost_replace_formula = mx.spring_mtrl_cost_replace_formula.Replace("【弹簧排列个数-长】", $"(【弹簧排列个数-长】 - {hard_around_row})");
                            mx.spring_mtrl_cost_replace_formula = mx.spring_mtrl_cost_replace_formula.Replace("【弹簧计算个数(长)】", $"(【弹簧计算个数(长)】 - {hard_around_row})");
                        }

                        if (mx.if_pocket_around == 1)
                        {
                            decimal pocket_around_row = mx.pocket_around_row.Value;
                            if (bednet.typename.IndexOf("袋装", StringComparison.Ordinal) >= 0) pocket_around_row *= 2;

                            mx.spring_mtrl_cost_replace_formula = mx.spring_mtrl_cost_replace_formula.Replace("【弹簧排列个数-宽】", $"(【弹簧排列个数-宽】 - {pocket_around_row})");
                            mx.spring_mtrl_cost_replace_formula = mx.spring_mtrl_cost_replace_formula.Replace("【弹簧计算个数(宽)】", $"(【弹簧计算个数(宽)】 - {pocket_around_row})");
                            mx.spring_mtrl_cost_replace_formula = mx.spring_mtrl_cost_replace_formula.Replace("【弹簧排列个数-长】", $"(【弹簧排列个数-长】 - {pocket_around_row})");
                            mx.spring_mtrl_cost_replace_formula = mx.spring_mtrl_cost_replace_formula.Replace("【弹簧计算个数(长)】", $"(【弹簧计算个数(长)】 - {pocket_around_row})");
                        }

                        var rp_formula = "";
                        mx.spring_mtrl_cost = Calculate(mx.spring_mtrl_cost_replace_formula, out rp_formula, "弹簧材料总成本").DecimalValue;
                        mx.spring_mtrl_cost_replace_formula = rp_formula;

                        #region 获取损耗率，计算
                        if (isNewFormula)
                        {
                            decimal? _rate = GetSumhaoRate(0);
                            bednet.spring_mtrl_cost += mx.spring_mtrl_cost * (1 + _rate);
                            if (_rate != 0)
                            {
                                _formula = "(" + _formula + ")" + "x" + "【弹簧损耗率】";
                                AddKeyValue("弹簧损耗率", (1 + _rate));
                            }
                        }
                        else
                        {
                            bednet.spring_mtrl_cost += mx.spring_mtrl_cost;
                        }
                        #endregion
                    }
                    else
                    {
                        mx.spring_mtrl_cost = 0;
                        decimal? _rate = GetSumhaoRate(0);
                        //多分区
                        var index = 1;
                        foreach (var springItem in springList)
                        {
                            _formula = bednet.spring_mtrl_formula;
                            springItem.spring_mtrl_cost_replace_formula = bednet.spring_mtrl_formula;
                            CalSpringMtrlCol(bednet, mx, springItem,ref _formula, index);

                            var rp_formula = "";
                            springItem.spring_mtrl_cost = Calculate(_formula, out rp_formula, "弹簧材料总成本").DecimalValue;
                            springItem.spring_mtrl_cost_replace_formula = rp_formula;
                            mx.spring_mtrl_cost += springItem.spring_mtrl_cost;

                            #region 获取损耗率，计算
                            if (isNewFormula)
                            {
                                bednet.spring_mtrl_cost += springItem.spring_mtrl_cost * (1 + _rate);
                                if (_rate != 0)
                                {
                                    _formula = "(" + _formula + ")" + "x" + "【弹簧损耗率】";
                                    AddKeyValue("弹簧损耗率", (1 + _rate));
                                }
                            }
                            else
                            {
                                bednet.spring_mtrl_cost += springItem.spring_mtrl_cost;
                            }
                            #endregion
                            AddFormulaMxKeyValue("【" + index + "弹簧材料总成本】", _formula, true);

                            index++;
                        }
                    }

                    AddKeyValue("弹簧排列个数-宽", mx.spring_qty_width);
                    AddKeyValue("弹簧排列个数-长", mx.spring_qty_length);
                    AddKeyValue("弹簧计算个数(宽)", mx.spring_qty_width);
                    AddKeyValue("弹簧计算个数(长)", mx.spring_qty_length);

                    AddKeyValue("弹簧材料总成本", bednet.spring_mtrl_cost);
                    AddFormulaMxKeyValue("【弹簧材料总成本】", _formula, true);
                }
                #endregion 计算 弹簧材料总成本 结束

                #region 计算 弹簧人工总成本 开始
                if (!string.IsNullOrEmpty(bednet.spring_hr_formula))
                {
                    mx.spring_hr_cost_replace_formula = bednet.spring_hr_formula;

                    var rp_formula = "";
                    mx.spring_hr_cost = Calculate(mx.spring_hr_cost_replace_formula, out rp_formula, "弹簧总人工成本").DecimalValue;
                    mx.spring_hr_cost_replace_formula = rp_formula;
                    bednet.spring_hr_cost += mx.spring_hr_cost;
                    AddKeyValue("弹簧总人工成本", bednet.spring_hr_cost);
                    AddFormulaMxKeyValue("【弹簧总人工成本】", bednet.spring_hr_formula, true);
                }
                #endregion 计算 弹簧人工总成本 结束

                #region 计算 蛇线材料成本 开始
                if (bednet.snake_wire_diameter.Value > 0)
                {
                    bednet.snake_wire_mtrl_cost_replace_formula = bednet.snake_wire_mtrl_formula;

                    #region 替换蛇线单价  snake_wire_diameter
                    GetSpringPrice(bednet.pricelistid.Value, "蛇线单价", 0, bednet.snake_wire_diameter.Value);
                    #endregion

                    var rp_formula = "";
                    bednet.snake_wire_mtrl_cost += Calculate(bednet.snake_wire_mtrl_cost_replace_formula, out rp_formula, "蛇线材料成本").DecimalValue;
                    bednet.snake_wire_mtrl_cost_replace_formula = rp_formula;
                    AddKeyValue("蛇线材料成本", bednet.snake_wire_mtrl_cost);
                    AddFormulaMxKeyValue("【蛇线材料成本】", bednet.snake_wire_mtrl_formula);
                }
                #endregion 计算 蛇线材料成本 结束

                #region 计算 四周口袋弹簧成本 开始
                if (!string.IsNullOrEmpty(bednet.pocket_around_spring_formula) && mx.if_pocket_around > 0)
                {
                    mx.pocket_around_spring_cost_replace_formula = bednet.pocket_around_spring_formula;

                    #region wf_cmp_pocket_around_dw2 口袋弹簧单价
                    var springPocket = GetSpringPrice(bednet.pricelistid.Value, "口袋弹簧单价", mx.pocket_around_springid, 0, "口袋");

                    if (springPocket.height > 0)
                    {
                        AddKeyValue("口袋弹簧高度", springPocket.height);
                    }

                    if (springPocket.center_diameter > 0)
                    {
                        AddKeyValue("口袋弹簧心径", springPocket.center_diameter);
                    }
                    #endregion

                    var rp_formula = "";
                    var mx_formula = mx.pocket_around_spring_cost_replace_formula.Replace("【弹簧重/个】", "【口袋弹簧重/个】").Replace("【弹簧重】", "【口袋弹簧重】");
                    mx.pocket_around_spring_cost = Calculate(mx_formula, out rp_formula, "四周口袋弹簧成本").DecimalValue;
                    mx.pocket_around_spring_cost_replace_formula = rp_formula;
                    bednet.pocket_around_spring_cost += mx.pocket_around_spring_cost;
                    AddKeyValue("四周口袋弹簧成本", bednet.pocket_around_spring_cost);
                    AddFormulaMxKeyValue("【四周口袋弹簧成本】", bednet.pocket_around_spring_formula.Replace("【弹簧重/个】", "【口袋弹簧重/个】").Replace("【弹簧重】", "【口袋弹簧重】"));
                }
                else
                {
                    AddKeyValue("口袋弹簧单价", 0);
                }
                #endregion 计算 四周口袋弹簧成本 结束

                #region 计算 四周口袋无纺布成本 开始
                if (!string.IsNullOrEmpty(bednet.pocket_around_fabrics_formula) && mx.if_pocket_around > 0)
                {
                    mx.pocket_around_fabrics_cost_replace_formula = bednet.pocket_around_fabrics_formula;

                    var rp_formula = "";
                    mx.pocket_around_fabrics_cost = Calculate(mx.pocket_around_fabrics_cost_replace_formula, out rp_formula, "四周口袋无纺布成本").DecimalValue;
                    mx.pocket_around_fabrics_cost_replace_formula = rp_formula;
                    bednet.pocket_around_fabrics_cost += mx.pocket_around_fabrics_cost;
                    AddKeyValue("四周口袋无纺布成本", bednet.pocket_around_fabrics_cost);
                    AddFormulaMxKeyValue("【四周口袋无纺布成本】", bednet.pocket_around_fabrics_formula);
                }
                #endregion 计算 四周口袋无纺布成本 结束

                #region 计算 四周加硬材料成本 开始
                if (!string.IsNullOrEmpty(bednet.hard_around_mtrl_formula) && mx.if_hard_around > 0)
                {
                    mx.hard_around_mtrl_cost_replace_formula = bednet.hard_around_mtrl_formula;

                    #region wf_cmp_hard_around_dw2 四周加硬弹簧单价
                    var springHard = GetSpringPrice(bednet.pricelistid.Value, "加硬弹簧单价", mx.hard_around_springid, 0, "加硬");
                    #endregion

                    var rp_formula = "";
                    var mx_formula = mx.hard_around_mtrl_cost_replace_formula.Replace("【弹簧重/个】", "【加硬弹簧重/个】").Replace("【弹簧重】", "【加硬弹簧重】");
                    mx.hard_around_mtrl_cost = Calculate(mx_formula, out rp_formula, "四周加硬材料成本").DecimalValue;
                    mx.hard_around_mtrl_cost_replace_formula = rp_formula;

                    var _formula = bednet.hard_around_mtrl_formula.Replace("【弹簧重/个】", "【加硬弹簧重/个】").Replace("【弹簧重】", "【加硬弹簧重】");
                    #region 获取损耗率，计算
                    if (isNewFormula)
                    {
                        decimal? _rate = GetSumhaoRate(0);
                        bednet.hard_around_mtrl_cost += mx.hard_around_mtrl_cost * (1 + _rate);
                        if (_rate != 0)
                        {
                            _formula = "(" + _formula + ")" + "x" + "【四周加硬损耗率】";
                            AddKeyValue("四周加硬损耗率", (1 + _rate));
                        }
                    }
                    else
                    {
                        bednet.hard_around_mtrl_cost += mx.hard_around_mtrl_cost;
                    }
                    #endregion
                    AddKeyValue("四周加硬材料成本", bednet.hard_around_mtrl_cost);
                    AddFormulaMxKeyValue("【四周加硬材料成本】", _formula);
                }
                else
                {
                    AddKeyValue("加硬弹簧单价", 0);
                }
                #endregion 计算 四周加硬材料成本 结束

                #region 计算 四周加硬人力成本 开始
                if (!string.IsNullOrEmpty(bednet.hard_around_hr_formula) && mx.if_hard_around > 0)
                {
                    mx.hard_around_hr_cost_replace_formula = bednet.hard_around_hr_formula;

                    var rp_formula = "";
                    mx.hard_around_hr_cost = Calculate(mx.hard_around_hr_cost_replace_formula, out rp_formula, "四周加硬人力成本").DecimalValue;
                    mx.hard_around_hr_cost_replace_formula = rp_formula;
                    bednet.hard_around_hr_cost += mx.hard_around_hr_cost;
                    AddKeyValue("四周加硬人力成本", bednet.hard_around_hr_cost);
                    AddFormulaMxKeyValue("【四周加硬人力成本】", bednet.hard_around_hr_formula);
                }
                #endregion 计算 四周加硬人力成本 结束

                #region 计算 入袋无纺布材料成本 开始
                if (!string.IsNullOrEmpty(bednet.hard_around_hr_formula) && bednet.typename.IndexOf("袋装网") > -1 && mx.fabrics1_mtrlid > 0)
                {
                    mx.fabrics1_mtrl_cost_replace_formula = bednet.fabrics1_mtrl_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "入袋无纺布");

                    var rp_formula = "";
                    mx.fabrics1_mtrl_cost = Calculate(mx.fabrics1_mtrl_cost_replace_formula, out rp_formula, "入袋无纺布材料成本").DecimalValue;
                    mx.fabrics1_mtrl_cost_replace_formula = rp_formula;
                    bednet.fabrics1_mtrl_cost += mx.fabrics1_mtrl_cost;


                    #region 获取损耗率，计算
                    var _formula = bednet.fabrics1_mtrl_formula;
                    if (isNewFormula)
                    {
                        var mtrlPrice = new u_mtrl_price() { mtrlid = mx.fabrics1_mtrlid };
                        DbSqlHelper.SelectOne(cmd, mtrlPrice, "mtrltype");

                        if (mtrlPrice != null)
                        {
                            decimal? _rate = GetSumhaoRate(mtrlPrice.mtrltype.Value);
                            bednet.fabrics1_mtrl_cost = bednet.fabrics1_mtrl_cost * (1 + _rate);
                            if (_rate != 0)
                            {
                                _formula = "(" + _formula + ")" + "x" + "【入袋无纺布损耗率】";
                                AddKeyValue("入袋无纺布损耗率", (1 + _rate));
                            }
                        }
                    }
                    #endregion
                    AddKeyValue("入袋无纺布材料成本", bednet.fabrics1_mtrl_cost);
                    AddFormulaMxKeyValue("【入袋无纺布材料成本】", _formula);
                }
                #endregion 计算 入袋无纺布材料成本 结束

                #region 计算 胶水材料成本 开始
                if (!string.IsNullOrEmpty(bednet.glue_mtrl_formula))
                {
                    mx.glue_mtrl_cost_replace_formula = bednet.glue_mtrl_formula;

                    var rp_formula = "";
                    bednet.glue_mtrl_cost += Calculate(mx.glue_mtrl_cost_replace_formula, out rp_formula, "胶水材料成本").DecimalValue;
                    mx.glue_mtrl_cost_replace_formula = rp_formula;
                    AddKeyValue("胶水材料成本", bednet.glue_mtrl_cost);
                    AddFormulaMxKeyValue("【胶水材料成本】", bednet.glue_mtrl_formula);
                }
                #endregion 计算 胶水材料成本 结束

                #region 计算 底面无纺布材料成本 开始
                if (!string.IsNullOrEmpty(bednet.hard_around_hr_formula) && bednet.typename.IndexOf("袋装网") > -1 && mx.fabrics2_mtrlid > 0)
                {
                    mx.fabrics2_mtrl_cost_replace_formula = bednet.fabrics2_mtrl_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "底面无纺布");

                    var rp_formula = "";
                    mx.fabrics2_mtrl_cost = Calculate(mx.fabrics2_mtrl_cost_replace_formula, out rp_formula, "底面无纺布材料成本").DecimalValue;
                    mx.fabrics2_mtrl_cost_replace_formula = rp_formula;
                    bednet.fabrics2_mtrl_cost += mx.fabrics2_mtrl_cost;

                    #region 获取损耗率，计算
                    var _formula = bednet.fabrics2_mtrl_formula;
                    if(isNewFormula)
                    {
                        var mtrlPrice = new u_mtrl_price() { mtrlid = mx.fabrics2_mtrlid };
                        DbSqlHelper.SelectOne(cmd, mtrlPrice, "mtrltype");

                        if (mtrlPrice != null)
                        {
                            decimal? _rate = GetSumhaoRate(mtrlPrice.mtrltype.Value);
                            bednet.fabrics2_mtrl_cost = bednet.fabrics2_mtrl_cost * (1 + _rate);
                            if (_rate != 0)
                            {
                                _formula = "(" + _formula + ")" + "x" + "【底面无纺布损耗率】";
                                AddKeyValue("底面无纺布损耗率", (1 + _rate));
                            }
                        }
                    }
                    #endregion
                    AddKeyValue("底面无纺布材料成本", bednet.fabrics2_mtrl_cost);
                    AddFormulaMxKeyValue("【底面无纺布材料成本】", _formula);
                }
                #endregion 计算 底面无纺布材料成本 结束

                #region 计算 边铁人力成本 开始
                if (!string.IsNullOrEmpty(bednet.side_iron_hr_formula) && bednet.if_side_iron == 1 && mx.if_side_iron > 0)
                {
                    mx.side_iron_hr_cost_replace_formula = bednet.side_iron_hr_formula;

                    var rp_formula = "";
                    mx.side_iron_hr_cost = Calculate(mx.side_iron_hr_cost_replace_formula, out rp_formula, "边铁人力成本").DecimalValue;
                    mx.side_iron_hr_cost_replace_formula = rp_formula;
                    bednet.side_iron_hr_cost += mx.side_iron_hr_cost;
                    AddKeyValue("边铁人力成本", bednet.side_iron_hr_cost);
                    AddFormulaMxKeyValue("【边铁人力成本】", bednet.side_iron_hr_formula);
                }
                #endregion 计算 边铁人力成本 结束

                #region  计算 边铁材料成本 开始
                if (!string.IsNullOrEmpty(bednet.side_iron_mtrl_formula) && bednet.if_side_iron == 1 && mx.if_side_iron > 0)
                {
                    mx.side_iron_mtrl_cost_replace_formula = bednet.side_iron_mtrl_formula;

                    var rp_formula = "";
                    mx.side_iron_mtrl_cost = Calculate(mx.side_iron_mtrl_cost_replace_formula, out rp_formula, "边铁材料成本").DecimalValue;
                    mx.side_iron_mtrl_cost_replace_formula = rp_formula;
                    bednet.side_iron_mtrl_cost += mx.side_iron_mtrl_cost;
                    AddKeyValue("边铁材料成本", bednet.side_iron_mtrl_cost);
                    AddFormulaMxKeyValue("【边铁材料成本】", bednet.side_iron_mtrl_formula);
                }
                #endregion 计算 边铁材料成本 结束

                #region  计算 C钉/夹码材料 开始
                if (!string.IsNullOrEmpty(bednet.cnail_mtrl_formula))
                {
                    mx.cnail_mtrl_cost_replace_formula = bednet.cnail_mtrl_formula;

                    var rp_formula = "";
                    mx.cnail_mtrl_cost = Calculate(mx.cnail_mtrl_cost_replace_formula, out rp_formula, "C钉/夹码材料成本").DecimalValue;
                    mx.cnail_mtrl_cost_replace_formula = rp_formula;
                    bednet.cnail_mtrl_cost += mx.cnail_mtrl_cost;
                    AddKeyValue("C钉/夹码材料成本", bednet.cnail_mtrl_cost);
                    AddFormulaMxKeyValue("【C钉/夹码材料成本】", bednet.cnail_mtrl_formula);
                }
                #endregion 计算 C钉/夹码材料 结束

                #region  计算 C钉/夹码人力成本 开始
                if (!string.IsNullOrEmpty(bednet.cnail_hr_formula))
                {
                    mx.cnail_hr_cost_replace_formula = bednet.cnail_hr_formula;

                    var rp_formula = "";
                    mx.cnail_hr_cost = Calculate(mx.cnail_hr_cost_replace_formula, out rp_formula, "C钉/夹码人力成本").DecimalValue;
                    mx.cnail_hr_cost_replace_formula = rp_formula;
                    bednet.cnail_hr_cost += mx.cnail_hr_cost;
                    AddKeyValue("C钉/夹码人力成本", bednet.cnail_hr_cost);
                    AddFormulaMxKeyValue("【C钉/夹码人力成本】", bednet.cnail_hr_formula);
                }
                #endregion 计算 C钉/夹码人力成本 结束

                #region  计算 海绵包边材料成本 开始
                if (!string.IsNullOrEmpty(bednet.sponge_mtrl_formula) && bednet.sponge_mtrlid > 0)
                {

                    bednet.sponge_mtrl_cost_replace_formula = bednet.sponge_mtrl_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "海绵包边");

                    var rp_formula = "";
                    bednet.sponge_mtrl_cost += Calculate(bednet.sponge_mtrl_cost_replace_formula, out rp_formula, "海绵包边材料成本").DecimalValue;
                    bednet.sponge_mtrl_cost_replace_formula = rp_formula;
                    AddKeyValue("海绵包边材料成本", bednet.sponge_mtrl_cost);
                    AddFormulaMxKeyValue("【海绵包边材料成本】", bednet.sponge_mtrl_formula);
                }
                #endregion 计算 海绵包边材料成本 结束

                #region  计算 海绵包边人力成本 开始
                if (!string.IsNullOrEmpty(bednet.sponge_hr_formula) && bednet.sponge_mtrlid > 0)
                {
                    bednet.sponge_hr_cost_replace_formula = bednet.sponge_hr_formula;

                    var rp_formula = "";
                    bednet.sponge_hr_cost += Calculate(bednet.sponge_hr_cost_replace_formula, out rp_formula, "海绵包边人力成本").DecimalValue;
                    bednet.sponge_hr_cost_replace_formula = rp_formula;
                    AddKeyValue("海绵包边人力成本", bednet.sponge_hr_cost);
                    AddFormulaMxKeyValue("【海绵包边人力成本】", bednet.sponge_hr_formula);
                }
                #endregion 计算 海绵包边人力成本 结束

                #region  计算 填充海绵成本 开始
                if (!string.IsNullOrEmpty(bednet.sponge_mtrl_tc_formula) && bednet.sponge_tc_mtrlid > 0)
                {
                    bednet.sponge_mtrl_tc_cost_replace_formula = bednet.sponge_mtrl_tc_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "填充海绵");

                    var rp_formula = "";
                    bednet.sponge_mtrl_tc_cost += Calculate(bednet.sponge_mtrl_tc_cost_replace_formula, out rp_formula, "填充海绵成本").DecimalValue;
                    bednet.sponge_mtrl_tc_cost_replace_formula = rp_formula;
                    AddKeyValue("填充海绵成本", bednet.sponge_mtrl_tc_cost);
                    AddFormulaMxKeyValue("【填充海绵成本】", bednet.sponge_mtrl_tc_formula);
                }
                #endregion 计算 填充海绵成本 结束

                #region  计算 封边材料成本 开始
                if (!string.IsNullOrEmpty(bednet.edge_mtrl_formula) && bednet.edge_mtrlid > 0)
                {
                    bednet.edge_mtrl_cost_replace_formula = bednet.edge_mtrl_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "封边");

                    var rp_formula = "";
                    bednet.edge_mtrl_cost += Calculate(bednet.edge_mtrl_cost_replace_formula, out rp_formula, "封边材料成本").DecimalValue;
                    bednet.edge_mtrl_cost_replace_formula = rp_formula;
                    AddKeyValue("封边材料成本", bednet.edge_mtrl_cost);
                    AddFormulaMxKeyValue("【封边材料成本】", bednet.edge_mtrl_formula);
                }
                #endregion 计算 封边材料成本 结束

                #region  计算 封边人力成本 开始
                if (!string.IsNullOrEmpty(bednet.edge_hr_formula) && bednet.edge_mtrlid > 0)
                {
                    bednet.edge_hr_cost_replace_formula = bednet.edge_hr_formula;

                    var rp_formula = "";
                    bednet.edge_hr_cost += Calculate(bednet.edge_hr_cost_replace_formula, out rp_formula, "封边人力成本").DecimalValue;
                    bednet.edge_hr_cost_replace_formula = rp_formula;
                    AddKeyValue("封边人力成本", bednet.edge_hr_cost);
                    AddFormulaMxKeyValue("【封边人力成本】", bednet.edge_hr_formula);
                }
                #endregion 计算 封边人力成本 结束

                #region  计算 弹叉材料成本 开始
                if (!string.IsNullOrEmpty(bednet.fork_mtrl_formula) && bednet.fork_qty > 0)
                {
                    bednet.fork_mtrl_cost_replace_formula = bednet.fork_mtrl_formula;

                    var rp_formula = "";
                    bednet.fork_mtrl_cost += Calculate(bednet.fork_mtrl_cost_replace_formula, out rp_formula, "弹叉材料成本").DecimalValue;
                    bednet.fork_mtrl_cost_replace_formula = rp_formula;
                    AddKeyValue("弹叉材料成本", bednet.fork_mtrl_cost);
                    AddFormulaMxKeyValue("【弹叉材料成本】", bednet.fork_mtrl_formula);
                }
                #endregion 计算 弹叉材料成本 结束

                #region  计算 弹叉人力成本 开始
                if (!string.IsNullOrEmpty(bednet.fork_hr_formula) && bednet.fork_qty > 0)
                {
                    bednet.fork_hr_cost_replace_formula = bednet.fork_hr_formula;

                    var rp_formula = "";
                    bednet.fork_hr_cost += Calculate(bednet.fork_hr_cost_replace_formula, out rp_formula, "弹叉人力成本").DecimalValue;
                    bednet.fork_hr_cost_replace_formula = rp_formula;
                    AddKeyValue("弹叉人力成本", bednet.fork_hr_cost);
                    AddFormulaMxKeyValue("【弹叉人力成本】", bednet.fork_hr_formula);
                }
                #endregion 计算 弹叉人力成本 结束

                #region  计算 胶条/包角材料成本 开始
                if (!string.IsNullOrEmpty(bednet.rsorwa_mtrl_formula) && bednet.if_rsorwa == 1)
                {
                    bednet.rsorwa_mtrl_cost_replace_formula = bednet.rsorwa_mtrl_formula;

                    var rp_formula = "";
                    bednet.rsorwa_mtrl_cost += Calculate(bednet.rsorwa_mtrl_cost_replace_formula, out rp_formula, "胶条/包角材料成本").DecimalValue;
                    bednet.rsorwa_mtrl_cost_replace_formula = rp_formula;
                    AddKeyValue("胶条/包角材料成本", bednet.rsorwa_mtrl_cost);
                    AddFormulaMxKeyValue("【胶条/包角材料成本】", bednet.rsorwa_mtrl_formula);
                }
                #endregion 计算 胶条/包角材料成本 结束

                #region  计算 胶条/包角人力成本 开始
                if (!string.IsNullOrEmpty(bednet.rsorwa_hr_formula) && bednet.if_rsorwa == 1)
                {
                    bednet.rsorwa_hr_cost_replace_formula = bednet.rsorwa_hr_formula;

                    var rp_formula = "";
                    bednet.rsorwa_hr_cost += Calculate(bednet.rsorwa_hr_cost_replace_formula, out rp_formula, "胶条/包角人力成本").DecimalValue;
                    bednet.rsorwa_hr_cost_replace_formula = rp_formula;
                    AddKeyValue("胶条/包角人力成本", bednet.rsorwa_hr_cost);
                    AddFormulaMxKeyValue("【胶条/包角人力成本】", bednet.rsorwa_hr_formula);
                }
                #endregion 计算 胶条/包角人力成本 结束

                #region  计算 海绵打孔人力成本 开始
                if (!string.IsNullOrEmpty(bednet.sponge_drilling_hr_formula) && bednet.if_sponge_drilling == 1)
                {
                    bednet.sponge_drilling_hr_cost_replace_formula = bednet.sponge_drilling_hr_formula;

                    var rp_formula = "";
                    bednet.sponge_drilling_hr_cost += Calculate(bednet.sponge_drilling_hr_cost_replace_formula, out rp_formula, "海绵打孔人力成本").DecimalValue;
                    bednet.sponge_drilling_hr_cost_replace_formula = rp_formula;
                    AddKeyValue("海绵打孔人力成本", bednet.sponge_drilling_hr_cost);
                    AddFormulaMxKeyValue("【海绵打孔人力成本】", bednet.sponge_drilling_hr_formula);
                }
                #endregion 计算 海绵打孔人力成本 结束

                #region  计算 上垫层物料成本 开始
                if (!string.IsNullOrEmpty(bednet.felt_mtrl_formula) && bednet.felt_qty > 0)
                {
                    bednet.felt_mtrl_cost_replace_formula = bednet.felt_mtrl_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "上垫层");

                    var rp_formula = "";
                    bednet.felt_mtrl_cost += Calculate(bednet.felt_mtrl_cost_replace_formula, out rp_formula, "上垫层物料成本").DecimalValue;
                    bednet.felt_mtrl_cost_replace_formula = rp_formula;
                    AddKeyValue("上垫层物料成本", bednet.felt_mtrl_cost);
                    AddFormulaMxKeyValue("【上垫层物料成本】", bednet.felt_mtrl_formula);
                }
                #endregion 计算 上垫层物料成本 结束

                #region  计算 下垫层物料成本 开始
                if (!string.IsNullOrEmpty(bednet.felt_mtrl_formula) && bednet.felt_x_qty > 0)
                {
                    bednet.felt_mtrl_x_cost_replace_formula = bednet.felt_mtrl_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "下垫层");

                    var rp_formula = "";
                    bednet.felt_mtrl_x_cost += Calculate(bednet.felt_mtrl_x_cost_replace_formula, out rp_formula, "下垫层物料成本").DecimalValue;
                    bednet.felt_mtrl_x_cost_replace_formula = rp_formula;
                    AddKeyValue("下垫层物料成本", bednet.felt_mtrl_x_cost);
                    AddFormulaMxKeyValue("【下垫层物料成本】", bednet.felt_mtrl_formula);
                }
                #endregion 计算 下垫层物料成本 结束

                #region  计算 上垫层人力成本 开始
                if (!string.IsNullOrEmpty(bednet.felt_hr_formula) && bednet.felt_qty > 0)
                {
                    bednet.felt_hr_cost_replace_formula = bednet.felt_hr_formula;

                    var rp_formula = "";
                    bednet.felt_hr_cost += Calculate(bednet.felt_hr_cost_replace_formula, out rp_formula, "上垫层人力成本").DecimalValue;
                    bednet.felt_hr_cost_replace_formula = rp_formula;
                    AddKeyValue("上垫层人力成本", bednet.felt_hr_cost);
                    AddFormulaMxKeyValue("【上垫层人力成本】", bednet.felt_hr_formula);
                }
                #endregion 计算 上垫层人力成本 结束

                #region  计算 下垫层人力成本 开始
                if (!string.IsNullOrEmpty(bednet.felt_hr_formula) && bednet.felt_x_qty > 0)
                {
                    bednet.felt_hr_x_cost_replace_formula = bednet.felt_hr_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "下垫层");

                    var rp_formula = "";
                    bednet.felt_hr_x_cost += Calculate(bednet.felt_hr_x_cost_replace_formula, out rp_formula, "下垫层人力成本").DecimalValue;
                    bednet.felt_hr_x_cost_replace_formula = rp_formula;
                    AddKeyValue("下垫层人力成本", bednet.felt_hr_x_cost);
                    AddFormulaMxKeyValue("【下垫层人力成本】", bednet.felt_hr_formula);
                }
                #endregion 计算 下垫层人力成本 结束

                #region  计算 包装总成本 开始
                if (!string.IsNullOrEmpty(bednet.packet_mtrl_formula) && !string.IsNullOrEmpty(bednet.packtype))
                {
                    bednet.packet_mtrl_cost_replace_formula = bednet.packet_mtrl_formula;
                    bool sqlCal = !string.IsNullOrEmpty(bednet.packet_mtrl_formula) && bednet.packet_mtrl_formula.TrimStart().Substring(0, 2) == "@@";
                    bednet.packet_mtrl_cost_replace_formula = bednet.packet_mtrl_cost_replace_formula.Replace("@@", "");

                    if(sqlCal) bednet.packet_mtrl_cost += Convert.ToDecimal(SqlCalculate(bednet.packet_mtrl_cost_replace_formula, "包装总成本"));
                    else bednet.packet_mtrl_cost += Calculate(bednet.packet_mtrl_cost_replace_formula, "包装总成本").DecimalValue;

                    AddKeyValue("包装总成本", bednet.packet_mtrl_cost);
                    AddFormulaMxKeyValue("【包装总成本】", bednet.packet_mtrl_formula);
                }
                #endregion 计算 包装总成本 结束

                #region  计算 包装人工成本 开始
                if (!string.IsNullOrEmpty(bednet.packet_hr_formula) && !string.IsNullOrEmpty(bednet.packtype))
                {
                    bednet.packet_hr_cost_replace_formula = bednet.packet_hr_formula;
                    bool sqlCal = !string.IsNullOrEmpty(bednet.packet_hr_formula) && bednet.packet_hr_formula.TrimStart().Substring(0, 2) == "@@";
                    bednet.packet_hr_cost_replace_formula = bednet.packet_hr_cost_replace_formula.Replace("@@", "");

                    if (sqlCal) bednet.packet_hr_cost += Convert.ToDecimal(SqlCalculate(bednet.packet_hr_cost_replace_formula, "包装人工成本"));
                    else bednet.packet_hr_cost += Calculate(bednet.packet_hr_cost_replace_formula, "包装人工成本").DecimalValue;

                    AddKeyValue("包装人工成本", bednet.packet_hr_cost);
                    AddFormulaMxKeyValue("【包装人工成本】", bednet.packet_hr_formula);
                }
                #endregion 计算 包装人工成本 结束

                //有外销的  工厂利润率 增加 0.06
                if (bednet.ifsaleout == 1)
                {
                    bednet.sale_point = 0.06M;
                }
                AddKeyValue("外销加点", bednet.sale_point);
            }

            // 计算总材料成本 total_mtrl_cost
            bednet.total_mtrl_cost = new decimal[]
            {
                bednet.spring_mtrl_cost.Value,
                bednet.snake_wire_mtrl_cost.Value,
                bednet.pocket_around_spring_cost.Value,
                bednet.pocket_around_fabrics_cost.Value,
                bednet.hard_around_mtrl_cost.Value,
                bednet.glue_mtrl_cost.Value,
                bednet.fabrics1_mtrl_cost.Value,
                bednet.fabrics2_mtrl_cost.Value,
                bednet.side_iron_mtrl_cost.Value,
                bednet.cnail_mtrl_cost.Value,
                bednet.sponge_mtrl_cost.Value,
                bednet.sponge_mtrl_tc_cost.Value,
                bednet.edge_mtrl_cost.Value,
                bednet.fork_mtrl_cost.Value,
                bednet.rsorwa_mtrl_cost.Value,
                bednet.felt_mtrl_cost.Value,
                bednet.felt_mtrl_x_cost.Value,
                bednet.packet_mtrl_cost.Value
            }.Sum();
            AddKeyValue("总材料成本", bednet.total_mtrl_cost);

            // 计算总人力费用 total_mtrl_cost
            bednet.total_hr_cost = new decimal[]
            {
                bednet.spring_hr_cost.Value,
                bednet.hard_around_hr_cost.Value,
                bednet.side_iron_hr_cost.Value,
                bednet.cnail_hr_cost.Value,
                bednet.sponge_hr_cost.Value,
                bednet.edge_hr_cost.Value,
                bednet.fork_hr_cost.Value,
                bednet.rsorwa_hr_cost.Value,
                bednet.felt_hr_cost.Value,
                bednet.felt_hr_x_cost.Value,
                bednet.packet_hr_cost.Value,
                bednet.sponge_drilling_hr_cost.Value
            }.Sum();
            AddKeyValue("总人力费用", bednet.total_hr_cost);

            //1.总成本=总材料成本+总人力费用+ 额外费用
            //bednet.total_cost = bednet.total_mtrl_cost + bednet.total_hr_cost + bednet.total_fees_cost;
            bednet.total_cost = CalculateVarFormula("车间成本").DecimalValue;
            AddKeyValue("车间成本", bednet.total_cost);

            //2-不含税出厂价=总成本* ( 工厂利润率 +  外销加点 )
            //bednet.nottax_factory_cost = bednet.total_cost * (bednet.profitrate + bednet.sale_point);
            bednet.nottax_factory_cost = CalculateVarFormula("不含税出厂价").DecimalValue;
            AddKeyValue("不含税出厂价", bednet.nottax_factory_cost);

            // 3 - 部门不含税价 = 不含税出厂价 / 部门利润率 * 佣金点数 * 额外点数 + fob
            //bednet.nottax_dept_cost = bednet.nottax_factory_cost / bednet.dept_profitrate / (1 - (bednet.commission - 1)) * bednet.other_rate + bednet.fob;
            bednet.nottax_dept_cost = CalculateVarFormula("部门不含税价").DecimalValue;
            AddKeyValue("部门不含税价", bednet.nottax_dept_cost);

            // 4 - 税金 = (部门不含税价 * 税率 - 1)
            //bednet.taxes = bednet.nottax_dept_cost * (bednet.taxrate - 1);
            bednet.taxes = CalculateVarFormula("税金").DecimalValue;
            AddKeyValue("税金", bednet.taxes);

            // 5 - 部门含税价 = 部门不含税价 * 税率
            //bednet.dept_cost = bednet.nottax_dept_cost * bednet.taxrate;
            bednet.dept_cost = CalculateVarFormula("部门含税价").DecimalValue;
            AddKeyValue("部门含税价", bednet.dept_cost);

            // 6 - 外币价 = 部门含税价 / 汇率
            //if (bednet.moneyrate != 0)
            //{
            //    bednet.foreign_cost = bednet.dept_cost / bednet.moneyrate;
            //}
            bednet.foreign_cost = CalculateVarFormula("外币价").DecimalValue;
            AddKeyValue("外币价", bednet.foreign_cost);

            decimal computed_plan = bednet.total_cost.Value - bednet.sponge_mtrl_cost.Value - bednet.felt_mtrl_cost.Value - bednet.felt_mtrl_x_cost.Value - bednet.packet_mtrl_cost.Value - bednet.packet_hr_cost.Value;
            AddKeyValue("计划价", computed_plan);
        }

        private void CulcalateWeight(u_bednet bednet, List<u_bednetmx> mxlist, List<u_bednetmx_spring> springList)
        {
            bednet.spring_weight_qty = 0;
            bednet.side_iron_weight_qty = 0;
            bednet.hard_around_weight_qty = 0;
            bednet.fabrics1_weight_qty = 0;
            bednet.fabrics2_weight_qty = 0;
            bednet.felt_weight_qty = 0;
            bednet.cnail_weight_qty = 0;
            bednet.sponge_weight_tc_qty = 0;
            bednet.sponge_weight_qty = 0;
            bednet.edge_weight_qty = 0;
            bednet.fork_weight_qty = 0;
            foreach (var mx in mxlist)
            {

                #region 计算 钢丝重量 开始
                if (!string.IsNullOrEmpty(bednet.spring_weight_formula))
                {
                    mx.spring_weight_replace_formula = bednet.spring_weight_formula;
                    if (mx.if_part == 0)
                    {
                        //单分区
                        bednet.spring_weight_qty += Calculate(mx.spring_weight_replace_formula, "钢丝重量").DecimalValue;
                    }
                    else
                    {
                        var index = 1;
                        //多分区
                        foreach (var springItem in springList)
                        {
                            var _formula = bednet.spring_weight_formula;
                            springItem.spring_weight_replace_formula = bednet.spring_weight_formula;
                            CalSpringMtrlCol(bednet, mx, springItem,ref _formula, index);

                            var rp_formula = "";
                            bednet.spring_weight_qty += Calculate(_formula, out rp_formula, "钢丝重量").DecimalValue;
                            springItem.spring_weight_replace_formula = rp_formula;

                            AddFormulaWeightKeyValue("【" + index + "钢丝重量】", _formula, true);

                            index++;
                        }
                    }
                    AddKeyValue("弹簧排列个数-宽", mx.spring_qty_width);
                    AddKeyValue("弹簧排列个数-长", mx.spring_qty_length);
                    AddKeyValue("弹簧计算个数(宽)", mx.spring_qty_width);
                    AddKeyValue("弹簧计算个数(长)", mx.spring_qty_length);

                    AddKeyValue("钢丝重量", bednet.spring_weight_qty);
                    AddFormulaWeightKeyValue("【钢丝重量】", bednet.spring_weight_formula, true);
                }
                else
                {
                    AddKeyValue("钢丝重量", 0);
                }
                #endregion 计算 钢丝重量 结束

                #region  计算 边铁重量 开始
                if (!string.IsNullOrEmpty(bednet.side_iron_weight_formula) && bednet.if_side_iron == 1 && mx.if_side_iron > 0)
                {
                    bednet.side_iron_weight_replace_formula = bednet.side_iron_weight_formula;

                    bednet.side_iron_weight_qty += Calculate(bednet.side_iron_weight_replace_formula, "边铁重量").DecimalValue;
                    AddKeyValue("边铁重量", bednet.side_iron_weight_qty);
                    AddFormulaWeightKeyValue("【边铁重量】", bednet.side_iron_weight_formula);
                }
                else
                {
                    AddKeyValue("边铁重量", 0);
                }
                #endregion 计算 边铁重量 结束

                #region  计算 四周加硬重量 开始
                if (!string.IsNullOrEmpty(bednet.hard_around_weight_formula) && mx.if_hard_around > 0)
                {
                    bednet.hard_around_weight_replace_formula = bednet.hard_around_weight_formula;
                    
                    bednet.hard_around_weight_replace_formula = bednet.hard_around_weight_replace_formula.Replace("【弹簧重/个】", "【加硬弹簧重/个】").Replace("【弹簧重】", "【加硬弹簧重】");

                    bednet.hard_around_weight_qty += Calculate(bednet.hard_around_weight_replace_formula, "四周加硬重量").DecimalValue;
                    AddKeyValue("四周加硬重量", bednet.hard_around_weight_qty);
                    AddFormulaWeightKeyValue("【四周加硬重量】", bednet.hard_around_weight_formula.Replace("【弹簧重/个】", "【加硬弹簧重/个】").Replace("【弹簧重】", "【加硬弹簧重】"));
                }
                else
                {
                    AddKeyValue("四周加硬重量", 0);
                }
                #endregion 计算 四周加硬重量 结束

                #region  计算 入袋无纺布重量 开始
                if (!string.IsNullOrEmpty(bednet.fabrics1_weight_formula) && bednet.typename.IndexOf("袋装网") > -1 && mx.fabrics1_mtrlid > 0)
                {
                    bednet.fabrics1_weight_replace_formula = bednet.fabrics1_weight_formula;

                    bednet.fabrics1_weight_qty += Calculate(bednet.fabrics1_weight_replace_formula, "入袋无纺布重量").DecimalValue;
                    AddKeyValue("入袋无纺布重量", bednet.fabrics1_weight_qty);
                    AddFormulaWeightKeyValue("【入袋无纺布重量】", bednet.fabrics1_weight_formula);
                }
                else
                {
                    AddKeyValue("入袋无纺布重量", 0);
                }
                #endregion 计算 入袋无纺布重量 结束

                #region  计算 面底无纺布重量 开始
                if (!string.IsNullOrEmpty(bednet.fabrics2_weight_formula) && bednet.typename.IndexOf("袋装网") > -1 && mx.fabrics2_mtrlid > 0)
                {
                    bednet.fabrics2_weight_replace_formula = bednet.fabrics2_weight_formula;

                    bednet.fabrics2_weight_qty += Calculate(bednet.fabrics2_weight_replace_formula, "面底无纺布重量").DecimalValue;
                    AddKeyValue("面底无纺布重量", bednet.fabrics2_weight_qty);
                    AddFormulaWeightKeyValue("【面底无纺布重量】", bednet.fabrics2_weight_formula);
                }
                else
                {
                    AddKeyValue("面底无纺布重量", 0);
                }
                #endregion 计算 面底无纺布重量 结束

                #region  计算 上垫层重量 开始
                string felt_weight_formula_replace_formula = "";
                if (!string.IsNullOrEmpty(bednet.felt_mtrl_formula) && bednet.felt_qty > 0)
                {
                    felt_weight_formula_replace_formula = bednet.felt_weight_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "上垫层");

                    bednet.felt_weight_qty += Calculate(felt_weight_formula_replace_formula, "上/下垫层重量").DecimalValue;
                    AddKeyValue("上/下垫层重量", bednet.felt_weight_qty);
                    AddFormulaWeightKeyValue("【上/下垫层重量】", bednet.felt_weight_formula);
                }
                else
                {
                    AddKeyValue("上/下垫层重量", 0);
                }
                #endregion 计算 上垫层重量 结束

                #region  计算 下垫层重量 开始
                string felt_x_weight_formula_replace_formula = "";
                if (!string.IsNullOrEmpty(bednet.felt_weight_formula) && bednet.felt_x_qty > 0)
                {
                    felt_x_weight_formula_replace_formula = bednet.felt_weight_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "下垫层");

                    bednet.felt_weight_qty += Calculate(felt_x_weight_formula_replace_formula, "上/下垫层重量").DecimalValue;
                    AddKeyValue("上/下垫层重量", bednet.felt_weight_qty);
                    AddFormulaWeightKeyValue("【上/下垫层重量】", bednet.felt_weight_formula);
                }
                else
                {
                    AddKeyValue("上/下垫层重量", 0);
                }

                bednet.felt_weight_replace_formula += felt_weight_formula_replace_formula;
                bednet.felt_weight_replace_formula += Environment.NewLine;
                bednet.felt_weight_replace_formula += felt_x_weight_formula_replace_formula;
                #endregion 计算 下垫层重量 结束


                #region  计算 C钉/夹码重量 开始
                if (!string.IsNullOrEmpty(bednet.cnail_weight_formula))
                {
                    bednet.cnail_weight_replace_formula = bednet.cnail_weight_formula;

                    bednet.cnail_weight_qty += Calculate(bednet.cnail_weight_replace_formula, "C钉/夹码重量").DecimalValue;
                    AddKeyValue("C钉/夹码重量", bednet.cnail_weight_qty);
                    AddFormulaWeightKeyValue("【C钉/夹码重量】", bednet.cnail_weight_formula);
                }
                else
                {
                    AddKeyValue("C钉/夹码重量", 0);
                }
                #endregion 计算 C钉/夹码重量 结束

                #region  计算 海绵包边重量 开始
                if (!string.IsNullOrEmpty(bednet.sponge_weight_formula) && bednet.sponge_mtrlid > 0)
                {
                    bednet.sponge_weight_replace_formula = bednet.sponge_weight_formula;

                    bednet.sponge_weight_qty += Calculate(bednet.sponge_weight_replace_formula, "海绵包边重量").DecimalValue;
                    AddKeyValue("海绵包边重量", bednet.sponge_weight_qty);
                    AddFormulaWeightKeyValue("【海绵包边重量】", bednet.sponge_weight_formula);
                }
                else
                {
                    AddKeyValue("海绵包边重量", 0);
                }
                #endregion 计算 海绵包边重量 结束

                #region  计算 填充海绵重量 开始
                if (!string.IsNullOrEmpty(bednet.sponge_weight_tc_formula) && bednet.sponge_tc_mtrlid > 0)
                {
                    bednet.sponge_weight_tc_replace_formula = bednet.sponge_weight_tc_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "填充海绵");

                    bednet.sponge_weight_tc_qty += Calculate(bednet.sponge_weight_tc_replace_formula, "填充海绵重量").DecimalValue;
                    AddKeyValue("填充海绵重量", bednet.sponge_weight_tc_qty);
                    AddFormulaWeightKeyValue("【填充海绵重量】", bednet.sponge_weight_tc_formula);
                }
                else
                {
                    AddKeyValue("填充海绵重量", 0);
                }
                #endregion 计算 填充海绵重量 结束

                #region  计算 封边材料重量 开始
                if (!string.IsNullOrEmpty(bednet.edge_weight_formula) && bednet.edge_mtrlid > 0)
                {
                    bednet.edge_weight_replace_formula = bednet.edge_weight_formula;

                    CalSpringMtrlCol2(bednet, mx, springList, "封边");

                    bednet.edge_weight_qty += Calculate(bednet.edge_weight_replace_formula, "封边材料重量").DecimalValue;
                    AddKeyValue("封边材料重量", bednet.edge_weight_qty);
                    AddFormulaWeightKeyValue("【封边材料重量】", bednet.edge_weight_formula);
                }
                else
                {
                    AddKeyValue("封边材料重量", 0);
                }
                #endregion 计算 封边材料重量 结束

                #region  计算 弹叉材料重量 开始
                if (!string.IsNullOrEmpty(bednet.fork_weight_formula) && bednet.fork_qty > 0)
                {
                    bednet.fork_weight_replace_formula = bednet.fork_weight_formula;

                    bednet.fork_weight_qty += Calculate(bednet.fork_weight_replace_formula, "弹叉材料重量").DecimalValue;
                    AddKeyValue("弹叉材料重量", bednet.fork_weight_qty);
                    AddFormulaWeightKeyValue("【弹叉材料重量】", bednet.fork_weight_formula);
                }
                else
                {
                    AddKeyValue("弹叉材料重量", 0);
                }
                #endregion 计算 弹叉材料重量 结束
            }

            // 计算总材料重量
            bednet.sum_weight = new decimal[]
            {
                bednet.spring_weight_qty.Value,
                bednet.side_iron_weight_qty.Value,
                bednet.hard_around_weight_qty.Value,
                bednet.fabrics1_weight_qty.Value,
                bednet.fabrics2_weight_qty.Value,
                bednet.felt_weight_qty.Value,
                bednet.cnail_weight_qty.Value,
                bednet.sponge_weight_qty.Value,
                bednet.sponge_weight_tc_qty.Value,
                bednet.edge_weight_qty.Value,
                bednet.fork_weight_qty.Value
            }.Sum();

            AddKeyValue("总重量", bednet.sum_weight);
            if (!formula_replacements_hide.ContainsKey("【总重量】")) AddFormulaHideKeyValue("总重量", "【钢丝重量】+【边铁重量】+【四周加硬重量】+【入袋无纺布重量】+【面底无纺布重量】+【上/下垫层重量】+【C钉/夹码重量】+【海绵包边重量】+【填充海绵重量】+【封边材料重量】+【弹叉材料重量】");
        }

        private void InitBedNet(u_bednet bednet, Boolean isCalBed = true)
        {
            var dept = Cache.GetData<u_dept,DeptMapping>(bednet.deptid.Value);

            //var profirate = new u_factory_profitrate() { deptid = bednet.deptid, bednettypeid_mattresstypeid = bednet.bednettypeid, bednet_or_mattress = 0 };
            //DbSqlHelper.SelectOne(cmd, profirate, "profitrate");
            decimal profitrate = 0;
            cmd.CommandText = @"SELECT profitrate FROM u_factory_profitrate 
                            WHERE deptid = @deptid 
                                AND  bednettypeid_mattresstypeid = @bednettypeid_mattresstypeid 
                                AND  bednet_or_mattress = 0";
            cmd.Parameters.Clear();
            cmd.Parameters.AddWithValue("@deptid", bednet.deptid);
            cmd.Parameters.AddWithValue("@bednettypeid_mattresstypeid", bednet.bednettypeid);
            using (var reader = cmd.ExecuteReader())
            {
                if (reader.Read())
                {
                    profitrate = Convert.ToDecimal(reader["profitrate"]);
                }
            }

            var bednetType = new u_bednet_type() { bednettypeid = bednet.bednettypeid };
            DbSqlHelper.SelectOne(cmd, bednetType, "typename");

            bednet.pricelistid = dept.pricelistid;
            bednet.typename = bednetType.typename;

            
            bednet.profitrate = profitrate;
            bednet.dept_profitrate = dept.profitrate;

            bednet.moneyrate = dept.moneyrate ?? 1;
            bednet.commission = bednet.commission ?? 1;
            bednet.taxrate = bednet.taxrate ?? 1;
            bednet.other_rate = bednet.other_rate ?? 1;
            bednet.dept_profitrate = bednet.dept_profitrate ?? 0;

            // 检查佣金是否小于1
            if (bednet.commission < 1)
            {
                throw new LJCommonException("佣金点数不能小于1!");
            }

            // 检查税率是否小于1
            if (bednet.taxrate < 1)
            {
                throw new LJCommonException("税率不能小于1!");
            }

            // 检查额外点数是否小于1
            if (bednet.other_rate < 1)
            {
                throw new LJCommonException("税率不能小于1!");
            }

            // 检查部门利润率是否为0
            if (bednet.dept_profitrate == 0)
            {
                throw new LJCommonException("部门利润率不能为0!");
            }
        }
        private void InitSptringRepaceMents(u_spring spring)
        {
            AddKeyValue("中心直径", spring.center_diameter);
            AddKeyValue("线径MM", spring.line_diameter);
            AddKeyValue("高度CM", spring.height);
            AddKeyValue("口径CM", spring.caliber);
            AddKeyValue("圈数", spring.cyclenum);
            AddKeyValue("克重KG", spring.gram_weight);
            AddKeyValue("卷排列宽", spring.roll_width == null ? 0 : spring.roll_width);
            AddKeyValue("卷排列长", spring.roll_length == null ? 0 : spring.roll_length);
            AddKeyValue("排列宽", spring.arrangement_width == null ? 0 : spring.arrangement_width);
            AddKeyValue("排列长", spring.arrangement_height == null ? 0 : spring.arrangement_height);
            AddKeyValue("弹簧类型id", spring.springtypeid);
        }
        private void InitReplaceMents(u_bednet bednet, Boolean isCalBed = true, int dannumType = 2, decimal dannumRate = 0)
        {
            replacements.Clear();

            var bednetVarList = new List<u_bednet_var>();
            var selectStr = "";
            var whereList = new List<string>();
            var param = new Dictionary<string, object>();

            // 公式
            AddFormulaKeyValue("车间成本", "【总材料成本】+【总人力费用】+ 【额外费用】");
            AddFormulaKeyValue("不含税出厂价", "【车间成本】*(【工厂利润率】+【外销加点】)");
            AddFormulaKeyValue("部门不含税价", "【不含税出厂价】/【部门利润率】/( 1 - (【佣金点数】- 1))*【额外点数】+【FOB】");
            AddFormulaKeyValue("税金", "【部门不含税价】* (【税率】-1)");
            AddFormulaKeyValue("部门含税价", "【部门不含税价】*【税率】");
            AddFormulaKeyValue("外币价", "【部门含税价】/【汇率】");
            AddFormulaKeyValue("计划价", "【车间成本】 - 【海绵包边材料成本】 - 【上垫层物料成本】 - 【下垫层物料成本】 - 【包装总成本】 - 【包装人工成本】");
            //AddFormulaHideKeyValue("总材料成本", "【弹簧材料总成本】+【蛇线材料成本】+【四周口袋弹簧成本】+【四周口袋无纺布成本】+【四周加硬材料成本】+【胶水材料成本】+【入袋无纺布材料成本】+【底面无纺布材料成本】+【边铁材料成本】+【C钉/夹码材料成本】+【海绵包边材料成本】+【填充海绵成本】+【封边材料成本】+【弹叉材料成本】+【胶条/包角材料成本】+【上垫层物料成本】+【下垫层物料成本】+【包装总成本】");
            //AddFormulaHideKeyValue("总人力费用", "【弹簧总人工成本】+【四周加硬人力成本】+【边铁人力成本】+【C钉/夹码人力成本】+【海绵包边人力成本】+【封边人力成本】+【弹叉人力成本】+【胶条/包角人力成本】+【上垫层人力成本】+【下垫层人力成本】+【包装人工成本】+【海绵打孔人力成本】");

            // 初始变量

            AddKeyValue("床垫宽", bednet.mattress_width);
            AddKeyValue("床垫长", bednet.mattress_length);
            AddKeyValue("床垫高", bednet.mattress_height);
            AddKeyValue("规格宽", bednet.mattress_width);
            AddKeyValue("规格长", bednet.mattress_length);
            AddKeyValue("规格高", bednet.mattress_height);
            AddKeyValue("双簧", bednet.if_doublespring);
            AddKeyValue("弹叉数量", bednet.fork_qty);
            AddKeyValue("包装方式", bednet.packtype);
            AddKeyValue("包装数量", bednet.packqty);
            AddKeyValue("运输方式", bednet.transport_type);
            AddKeyValue("包装材料", bednet.packmtrl);
            AddKeyValue("床网类别", bednet.typename);
            AddKeyValue("工厂利润率", bednet.profitrate);
            AddKeyValue("部门利润率", bednet.dept_profitrate);
            AddKeyValue("佣金点数", bednet.commission);
            AddKeyValue("额外点数", bednet.other_rate);
            AddKeyValue("额外费用", bednet.extras_cost); 
            AddKeyValue("FOB", bednet.fob);
            AddKeyValue("汇率", bednet.moneyrate);
            AddKeyValue("税率", bednet.taxrate);
            AddKeyValue("卷包", bednet.if_jb);
            AddKeyValue("海绵包边", !string.IsNullOrEmpty(bednet.sponge_mtrl_formula) && bednet.sponge_mtrlid > 0 ? 1 : 0);

            AddKeyValue("大小单系数", bednet.dannum_rate != null ? bednet.dannum_rate : 0);
            var _dannumType = 0;
            // 备货床网，勾选则不按床垫大小单系数，统一使用标准系数计算
            if (bednet.if_stock_up == 1)
            {
                _dannumType = 2;
            }
            else
            {
                _dannumType = bednet.dannum_type != null ? bednet.dannum_type.Value : 2;
            }
            AddKeyValue("大小单类型", _dannumType);
            // 实时获取变量

            selectStr = @"SELECT u_bednet_varmx.varid AS varid
	                            ,varkind
	                            ,varcode
	                            ,varname
	                            ,varclass
	                            ,vartype
	                            ,varunit
	                            ,u_bednet_varmx.varvalue AS varvalue
                            FROM u_bednet_var
                            INNER JOIN u_bednet_varmx ON u_bednet_varmx.varid = u_bednet_var.varid";
            whereList = new List<string>();
            whereList.Add("u_bednet_var.varclass < 2"); // 非公式
            whereList.Add("u_bednet_var.varkind = @varkind");
            whereList.Add("u_bednet_varmx.pricelistid = @pricelistid");
            whereList.Add(@"(u_bednet_var.varclass = 1
			                    AND (
				                    u_bednet_varmx.bednettypeid = @bednettypeid
				                    OR @bednettypeid = 0
				                    )
			                    )
		                    OR (u_bednet_var.varclass = 0)");
            param = new Dictionary<string, object>();
            param.Add("@varkind", 0);
            param.Add("@pricelistid", bednet.pricelistid);
            param.Add("@bednettypeid", bednet.bednettypeid);
            DbSqlHelper.SelectJoin(cmd, selectStr, ListEx.GetWhereStr(whereList), param, "varid", "varid,varkind,varcode,varname,varclass,vartype,varunit,varvalue", 0, 0, bednetVarList);

            foreach (var netvar in bednetVarList)
            {
                AddKeyValue(netvar.varname, netvar.varvalue);
            }

            if (isCalBed)
            {
                selectStr = @"SELECT varid
	                                ,varkind
	                                ,varcode
	                                ,varname
	                                ,varclass
	                                ,vartype
	                                ,varunit
                                    ,formula
                                    ,ifmxformula
                                FROM u_bednet_var";
                bednetVarList = new List<u_bednet_var>();
                whereList = new List<string>();
                whereList.Add("u_bednet_var.varkind = @varkind");
                whereList.Add("u_bednet_var.varclass = @varclass");
                param = new Dictionary<string, object>();
                param.Add("@varkind", 0);
                param.Add("@varclass", 2); // 公式
                DbSqlHelper.SelectJoin(cmd, selectStr, ListEx.GetWhereStr(whereList), param, "varid", "varid,varkind,varcode,varname,varclass,vartype,varunit,formula,ifmxformula", 0, 0, bednetVarList);

                string[] keys = { "车间成本", "不含税出厂价", "部门不含税价", "税金", "部门含税价", "外币价", "计划价"};
                // 添加替换公式变量
                foreach (var netvar in bednetVarList)
                {
                    if (netvar.ifmxformula > 0)
                    {
                        AddFormulaKeyValue(netvar.varname, netvar.formula);
                    }
                    else if (keys.Contains(netvar.varname))
                    {
                        AddFormulaKeyValue(netvar.varname, netvar.formula);
                    }
                    else
                    {
                        AddFormulaHideKeyValue(netvar.varname, netvar.formula);
                    }
                }

                string[] formula_keys = { "大小单系数" };
                // 参数型公式，先执行
                foreach (var replacement in formula_replacements_hide)
                {
                    if (formula_keys.Contains(replacement.Key))
                    {
                        var _key = replacement.Key.Replace("【", "").Replace("】", "");
                        var value = CalculateVarFormula(_key).DecimalValue;
                        AddKeyValue(_key, value);
                    }
                }
            }
        }
        private void InitMxReplaceMents(u_bednet bednet,u_bednetmx mx, u_spring spring)
        {
            AddKeyValue("弹簧排列个数-宽", mx.spring_qty_width);
            AddKeyValue("弹簧排列个数-长", mx.spring_qty_length);
            AddKeyValue("弹簧计算个数(宽)", mx.spring_qty_width);
            AddKeyValue("弹簧计算个数(长)", mx.spring_qty_length);
            AddKeyValue("边铁条数", mx.side_iron_qty);
            AddKeyValue("条数", mx.side_iron_qty);
            AddKeyValue("四周口袋-排数", mx.pocket_around_row);
            AddKeyValue("四周口袋", mx.if_pocket_around);
            AddKeyValue("四周加硬-排数", mx.hard_around_row);
            AddKeyValue("四周加硬", mx.if_hard_around);

            spring.gram_weight /= 1000;
            if (spring.gram_weight > 0)
            {
                AddKeyValue("弹簧重/个", spring.gram_weight);
                AddKeyValue("弹簧重", spring.gram_weight);
                AddKeyValue("弹簧克重", spring.gram_weight * 1000);
            }

            if (mx.bednet_height > 0)
            {
                AddKeyValue("床网高", mx.bednet_height);
            }

            GetSpringPrice(bednet.pricelistid.Value, "弹簧单价", 0, spring.line_diameter ?? 0);
        }
        /// <summary>
        /// 用于床网报价 弹簧材料总成本 弹簧人工总成本
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="dept"></param>
        /// <param name="mx"></param>
        /// <param name="mx2"></param>
        private void CalSpringMtrlCol(u_bednet bednet, u_bednetmx mx, u_bednetmx_spring mx2,ref string formula, int index)
        {
            AddKeyValue(index + "弹簧排列个数-宽", mx2.spring_qty_width);
            AddKeyValue(index + "弹簧排列个数-长", mx2.spring_qty_length);
            AddKeyValue(index + "弹簧计算个数(宽)", mx2.spring_qty_width);
            AddKeyValue(index + "弹簧计算个数(长)", mx2.spring_qty_length);
            formula = formula.Replace("【弹簧排列个数-宽】", "【" + index +"弹簧排列个数-宽】");
            formula = formula.Replace("【弹簧排列个数-长】", "【" + index + "弹簧排列个数-长】");
            formula = formula.Replace("【弹簧计算个数(宽)】", "【" + index + "弹簧计算个数(宽)】");
            formula = formula.Replace("【弹簧计算个数(长)】", "【" + index + "弹簧计算个数(长)】");
            AddKeyValue("边铁条数", mx.side_iron_qty);
            AddKeyValue("条数", mx.side_iron_qty);

            var spring = Cache.GetData<u_spring,SpringMapping>(mx2.springid.Value);

            spring.gram_weight /= 1000;
            if (spring.gram_weight > 0)
            {
                AddKeyValue(index + "弹簧重/个", spring.gram_weight);
                AddKeyValue(index + "弹簧重", spring.gram_weight);
                formula = formula.Replace("【弹簧重/个】", "【" + index + "弹簧重/个】");
                formula = formula.Replace("【弹簧重】", "【" + index + "弹簧重】");
            }

            cmd.CommandText = @"SELECT TOP 1 isnull(u_mtrl_price_pricelist.price, 0) AS price
                                FROM u_mtrl_price_pricelist
                                INNER JOIN u_mtrl_price ON u_mtrl_price.mtrlid = u_mtrl_price_pricelist.mtrlid
                                WHERE cast(u_mtrl_price.name AS DECIMAL(18, 5)) = @line_diameter
	                                AND u_mtrl_price.mtrltype = 0
	                                AND u_mtrl_price_pricelist.pricelistid = @pricelistid";
            cmd.Parameters.Clear();
            cmd.Parameters.AddWithValue("@line_diameter", spring.line_diameter);
            cmd.Parameters.AddWithValue("@pricelistid", bednet.pricelistid);
            decimal price = 0;
            using (var reader = cmd.ExecuteReader())
            {
                if (reader.Read())
                {
                    price = Convert.ToDecimal(reader["price"]);

                    price /= 1000;
                }
            }

            if (price > 0)
            {
                AddKeyValue(index + "弹簧单价", price);
                formula = formula.Replace("【弹簧单价】", "【" + index + "弹簧单价】");
            }
        }

        /// <summary>
        /// 代码对照wf_replace_var_dw2
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="mx"></param>
        private void CalSpringMtrlCol2(u_bednet bednet, u_bednetmx mx, List<u_bednetmx_spring> springList, string type)
        {
            var spring = Cache.GetData<u_spring, SpringMapping>(mx.springid.Value);

            #region 计算 底面无纺布 开始
            //计算 上下无纺布方数 =(B4+C4)*(B4+D4)/10000
            if ("底面无纺布".Equals(type) && mx.fabrics2_mtrlid > 0)
            {
                decimal fabrics = (decimal)((mx.bednet_height.Value + bednet.mattress_width.Value) * (mx.bednet_height.Value + bednet.mattress_length.Value)) / 10000;
                AddKeyValue("上下无纺布方数", fabrics);

                decimal fabrics_price = getMtrlPrice(2, bednet.pricelistid.Value, mx.fabrics2_mtrlid.Value);
                if (fabrics_price > 0) AddKeyValue("无纺布单价", fabrics_price);
            }
            #endregion 计算 底面无纺布 结束

            #region 计算 入袋无纺布 开始
            //计算 入袋无纺布方数 = (B4+I4+2)*((I4*3.14)+1)/10000
            if ("入袋无纺布".Equals(type) && mx.fabrics1_mtrlid > 0)
            {
                var _springid = mx.springid;
                if (_springid == 0 && springList.Count > 0)
                {
                    _springid = springList[0].springid;
                }
                var _spring = Cache.GetData<u_spring, SpringMapping>(_springid.Value);

                spring.center_diameter = _spring.center_diameter == null ? 0 : _spring.center_diameter;

                decimal fabrics = (decimal)((mx.bednet_height.Value + _spring.center_diameter.Value + 2) * (_spring.center_diameter.Value * (decimal)3.14 + 1)) / 10000;
                string fabrics_str = fabrics.ToString("###0.#####");
                AddKeyValue("入袋无纺布方数", fabrics_str);

                decimal fabrics_price = getMtrlPrice(2, bednet.pricelistid.Value, mx.fabrics1_mtrlid.Value);
                if (fabrics_price > 0) AddKeyValue("无纺布单价", fabrics_price);
            }
            #endregion 计算 入袋无纺布 结束

            #region 计算 四周加硬弹簧 开始
            // 主要是要替换  【弹簧克重】   【弹簧单价】
            // 因相同部分已存在，不需要后续
            #endregion 计算 四周加硬弹簧 结束

            #region 计算 海绵包边 开始
            if ("海绵包边".Equals(type) && bednet.sponge_thickness.Value > 0 && bednet.sponge_mtrlid.Value > 0)
            {
                var mtrl_price = new u_mtrl_price() { mtrlid = bednet.sponge_mtrlid };
                DbSqlHelper.SelectOne(cmd, mtrl_price, "name");

                AddKeyValue("物料名称", mtrl_price.name);

                AddKeyValue("裥棉厚度", bednet.sponge_thickness.Value);
                AddKeyValue("海绵厚度", bednet.sponge_thickness.Value);
                AddKeyValue("海绵包边厚度", bednet.sponge_thickness.Value);

                if (bednet.sponge_height.Value > 0)
                {
                    AddKeyValue("海绵高", bednet.sponge_height.Value);
                }

                cmd.CommandText = @"SELECT isnull(u_mtrl_price_pricelist.price, 0) AS price
                                    FROM u_mtrl_price_pricelist
                                    WHERE u_mtrl_price_pricelist.mtrlid = @mtrlid
	                                    AND u_mtrl_price_pricelist.pricelistid = @pricelistid";
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@mtrlid", bednet.sponge_mtrlid);
                cmd.Parameters.AddWithValue("@pricelistid", bednet.pricelistid);
                using (var reader = cmd.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        decimal sponge_price = Convert.ToDecimal(reader["price"]);

                        AddKeyValue("裥棉单价", sponge_price);
                        AddKeyValue("海绵单价", sponge_price);
                    }
                }
            }
            else
            {
                AddKeyValue("海绵包边厚度", 0);
            }
            #endregion 计算 海绵包边 结束

            #region 计算 填充海绵 开始
            if ("填充海绵".Equals(type) && bednet.sponge_tc_thickness.Value > 0 && bednet.sponge_tc_mtrlid.Value > 0)
            {
                var mtrl_price = new u_mtrl_price() { mtrlid = bednet.sponge_tc_mtrlid };
                DbSqlHelper.SelectOne(cmd, mtrl_price, "name");

                AddKeyValue("物料名称", mtrl_price.name);

                AddKeyValue("裥棉厚度", bednet.sponge_tc_thickness.Value);
                AddKeyValue("海绵厚度", bednet.sponge_tc_thickness.Value);
                AddKeyValue("填充海绵厚度", bednet.sponge_tc_thickness.Value);

                if (bednet.sponge_tc_height.Value > 0)
                {
                    AddKeyValue("海绵高", bednet.sponge_tc_height.Value);
                }

                cmd.CommandText = @"SELECT isnull(u_mtrl_price_pricelist.price, 0) AS price
                                    FROM u_mtrl_price_pricelist
                                    WHERE u_mtrl_price_pricelist.mtrlid = @mtrlid
	                                    AND u_mtrl_price_pricelist.pricelistid = @pricelistid";
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@mtrlid", bednet.sponge_tc_mtrlid);
                cmd.Parameters.AddWithValue("@pricelistid", bednet.pricelistid);
                using (var reader = cmd.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        decimal sponge_price = Convert.ToDecimal(reader["price"]);

                        AddKeyValue("裥棉单价", sponge_price);
                        AddKeyValue("海绵单价", sponge_price);
                    }
                }
            }
            else
            {
                AddKeyValue("填充海绵厚度", 0);
            }
            #endregion 计算 填充海绵 结束

            #region 计算 封边 开始
            if ("封边".Equals(type) && bednet.edge_mtrlid > 0)
            {
                AddKeyValue("有边铁", mx.if_side_iron);

                cmd.CommandText = @"SELECT isnull(u_mtrl_price_pricelist.price, 0) AS price
	                                    ,u_mtrl_price.gram_weight
                                    FROM u_mtrl_price_pricelist
                                    INNER JOIN u_mtrl_price ON u_mtrl_price.mtrlid = u_mtrl_price_pricelist.mtrlid
                                    WHERE u_mtrl_price_pricelist.mtrlid = @mtrlid
	                                    AND u_mtrl_price_pricelist.pricelistid = @pricelistid";
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@mtrlid", bednet.edge_mtrlid);
                cmd.Parameters.AddWithValue("@pricelistid", bednet.pricelistid);
                using (var reader = cmd.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        decimal edge_price = Convert.ToDecimal(reader["price"]);
                        decimal edge_weight = Convert.ToDecimal(reader["gram_weight"]);

                        if (edge_price > 0) AddKeyValue("毡单价", edge_price);
                        if (edge_weight > 0) AddKeyValue("毡克重", edge_weight);
                    }
                }

                if (bednet.edge_height > 0) AddKeyValue("封边高", bednet.edge_height);
            }
            #endregion 计算 封边 结束

            #region 计算 上垫层 开始
            if ("上垫层".Equals(type) && bednet.felt_mtrlid > 0)
            {
                cmd.CommandText = @"SELECT isnull(u_mtrl_price_pricelist.price, 0) AS price
	                                    ,u_mtrl_price.gram_weight
                                    FROM u_mtrl_price_pricelist
                                    INNER JOIN u_mtrl_price ON u_mtrl_price.mtrlid = u_mtrl_price_pricelist.mtrlid
                                    WHERE u_mtrl_price_pricelist.mtrlid = @mtrlid
	                                    AND u_mtrl_price_pricelist.pricelistid = @pricelistid";
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@mtrlid", bednet.felt_mtrlid);
                cmd.Parameters.AddWithValue("@pricelistid", bednet.pricelistid);
                using (var reader = cmd.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        decimal felt_price = Convert.ToDecimal(reader["price"]);
                        decimal felt_weight = Convert.ToDecimal(reader["gram_weight"]);

                        if (felt_price > 0) AddKeyValue("垫层物料单价", felt_price);
                        if (felt_weight > 0) AddKeyValue("垫层物料克重", felt_weight);
                    }
                }

                if (bednet.felt_qty > 0) AddKeyValue("垫层物料数量", bednet.felt_qty);
            }
            #endregion 计算 上垫层 结束

            #region 计算 下垫层 开始
            if ("下垫层".Equals(type) && bednet.felt_x_mtrlid > 0)
            {
                cmd.CommandText = @"SELECT isnull(u_mtrl_price_pricelist.price, 0) AS price
	                                    ,u_mtrl_price.gram_weight
                                    FROM u_mtrl_price_pricelist
                                    INNER JOIN u_mtrl_price ON u_mtrl_price.mtrlid = u_mtrl_price_pricelist.mtrlid
                                    WHERE u_mtrl_price_pricelist.mtrlid = @mtrlid
	                                    AND u_mtrl_price_pricelist.pricelistid = @pricelistid";
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@mtrlid", bednet.felt_x_mtrlid);
                cmd.Parameters.AddWithValue("@pricelistid", bednet.pricelistid);
                using (var reader = cmd.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        decimal felt_price = Convert.ToDecimal(reader["price"]);
                        decimal felt_weight = Convert.ToDecimal(reader["gram_weight"]);

                        if (felt_price > 0) AddKeyValue("垫层物料单价", felt_price);
                        if (felt_weight > 0) AddKeyValue("垫层物料克重", felt_weight);
                    }
                }

                if (bednet.felt_x_qty > 0) AddKeyValue("垫层物料数量", bednet.felt_x_qty);
            }
            #endregion 计算 下垫层 结束
        }

        private u_spring GetSpringPrice(int pricelistid, string KeyName, int? springId, decimal line_diameter = 0, string springName = "")
        {
            var spring = new u_spring() { springid = springId };
            if (line_diameter == 0)
            {
                spring = Cache.GetData<u_spring, SpringMapping>(springId.Value);
                AddKeyValue(springName + "弹簧重/个", spring.gram_weight / 1000);
                AddKeyValue(springName + "弹簧重", spring.gram_weight / 1000);
            } 
            else
            {
                spring.line_diameter = line_diameter;
            }

            cmd.CommandText = @"SELECT TOP 1 isnull(u_mtrl_price_pricelist.price, 0) AS price
                                FROM u_mtrl_price_pricelist
                                INNER JOIN u_mtrl_price ON u_mtrl_price.mtrlid = u_mtrl_price_pricelist.mtrlid
                                WHERE cast(u_mtrl_price.name AS DECIMAL(18, 5)) = @line_diameter
	                                AND u_mtrl_price.mtrltype = 0
	                                AND u_mtrl_price_pricelist.pricelistid = @pricelistid";
            cmd.Parameters.Clear();
            cmd.Parameters.AddWithValue("@line_diameter", spring.line_diameter ?? 0);
            cmd.Parameters.AddWithValue("@pricelistid", pricelistid);
            decimal price = 0;
            using (var reader = cmd.ExecuteReader())
            {
                if (reader.Read())
                {
                    price = Convert.ToDecimal(reader["price"]);

                    price /= 1000;
                }
            }

            AddKeyValue(KeyName, price);
            return spring;
        }

        private decimal getMtrlPrice(int mtrltype, int pricelistid, int mtrlid)
        {
            decimal price = 0;
            cmd.CommandText = @"SELECT TOP 1 isnull(u_mtrl_price_pricelist.price, 0) AS price
                                FROM u_mtrl_price_pricelist
                                INNER JOIN u_mtrl_price ON u_mtrl_price.mtrlid = u_mtrl_price_pricelist.mtrlid
                                WHERE u_mtrl_price.mtrlid = @mtrlid
	                                AND u_mtrl_price.mtrltype = @mtrltype
	                                AND u_mtrl_price_pricelist.pricelistid = @pricelistid";
            cmd.Parameters.Clear();
            cmd.Parameters.AddWithValue("@mtrlid", mtrlid);
            cmd.Parameters.AddWithValue("@mtrltype", mtrltype);
            cmd.Parameters.AddWithValue("@pricelistid", pricelistid);
            using (var reader = cmd.ExecuteReader())
            {
                if (reader.Read())
                {
                    price = Convert.ToDecimal(reader["price"]);

                    //price /= 1000;
                }
            }

            return price;
        }

        private string ConvertToEnglishSymbols(string input)
        {
            input = input.Replace("（", "(")
                 .Replace("）", ")")
                 .Replace("，", ",")
                 .Replace("。", ".")
                 .Replace("：", ":")
                 .Replace("；", ";")
                 .Replace("“", "\"")
                 .Replace("”", "\"")
                 .Replace("‘", "'")
                 .Replace("’", "'");

            return input;
        }

        private void AddKeyValue(string key, object value, bool isReplace = true)
        {
            key = $"【{key}】";
            if (!replacements.ContainsKey(key))
            {
                replacements.Add(key, value);
            }
            else if (isReplace)
            {
                replacements[key] = value;
            }
        }
        private void AddFormulaKeyValue(string key, string value, bool isReplace = true, int ifnotreplace = 0)
        {
            var formulaItem = new formulaItem()
            {
                value = value,
                ifnotreplace = ifnotreplace
            };
            key = $"【{key}】";
            if (!formula_replacements.ContainsKey(key))
            {
                formula_replacements.Add(key, formulaItem);
            }
            else if (isReplace)
            {
                formula_replacements[key] = formulaItem;
            }
        }
        /// <summary>
        /// 记录隐藏公式
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="isReplace"></param>
        private void AddFormulaHideKeyValue(string key, string value, bool isReplace = true, int ifnotreplace = 0)
        {
            var formulaItem = new formulaItem()
            {
                value = value,
                ifnotreplace = ifnotreplace
            };
            key = $"【{key}】";
            if (!formula_replacements_hide.ContainsKey(key))
            {
                formula_replacements_hide.Add(key, formulaItem);
            }
            else if (isReplace)
            {
                formula_replacements_hide[key] = formulaItem;
            }
        }
        /// <summary>
        /// 记录详细公式
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="isReplace"></param>
        private void AddFormulaMxKeyValue(string key, string value, bool isReplace = true, int ifnotreplace = 0)
        {
            var formulaItem = new formulaItem()
            {
                value = value,
                ifnotreplace = ifnotreplace
            };
            if (!formula_replacements_mx.ContainsKey(key))
            {
                formula_replacements_mx.Add(key, formulaItem);
            }
            else if (isReplace)
            {
                formula_replacements_mx[key] = formulaItem;
            }
        }
        /// <summary>
        /// 记录重量公式
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="isReplace"></param>
        private void AddFormulaWeightKeyValue(string key, string value, bool isReplace = true, int ifnotreplace = 0)
        {
            var formulaItem = new formulaItem()
            {
                value = value,
                ifnotreplace = ifnotreplace
            };
            if (!formula_replacements_weight.ContainsKey(key))
            {
                formula_replacements_weight.Add(key, formulaItem);
            }
            else if (isReplace)
            {
                formula_replacements_weight[key] = formulaItem;
            }
        }
        private string ReplaceWith(string input, string oldValue, string newValue)
        {
            return input.Replace(oldValue, newValue);
        }
        private TData CalculateVarFormula(string varname)
        {
            varname = $"【{varname}】";
            if (formula_replacements.ContainsKey(varname)) return Calculate(formula_replacements[varname].value, varname);
            if (formula_replacements_hide.ContainsKey(varname)) return Calculate(formula_replacements_hide[varname].value, varname);
            return null;
        }
        private void replaceFormulas(ref string expression)
        {
            bool hasReplace = false;

            foreach (var replacement in formula_replacements)
            {
                if (expression.IndexOf(replacement.Key) > -1)
                {
                    expression = expression.Replace(replacement.Key, "(" + replacement.Value.value + ")");
                    hasReplace = true;
                }
            }
            if (hasReplace)
            {
                replaceFormulas(ref expression);
            }
        }
        private void replaceFormulasHide(ref string expression)
        {
            bool hasReplace = false;

            foreach (var replacement in formula_replacements_hide)
            {
                if (expression.IndexOf(replacement.Key) > -1)
                {
                    expression = expression.Replace(replacement.Key, "(" + replacement.Value.value + ")");
                    hasReplace = true;
                }
            }
            if (hasReplace)
            {
                replaceFormulasHide(ref expression);
            }
        }
        private void FormatExpression(ref string expression)
        {
            // 替换相互嵌套的公式
            replaceFormulas(ref expression);
            replaceFormulasHide(ref expression);

            expression = ConvertToEnglishSymbols(expression);

            // 定义正则表达式模式，匹配包含【】的内容
            string pattern = @"【(.*?)】";

            // 创建正则表达式对象
            Regex regex = new Regex(pattern);

            // 使用正则表达式匹配输入字符串
            MatchCollection matches = regex.Matches(expression);

            var new_replacements = new Dictionary<string, object>();

            foreach (Match match in matches)
            {
                if (replacements.TryGetValue(match.Value, out object value2))
                {
                    new_replacements[match.Value] = value2;
                }
            }

            foreach (var replacement in new_replacements)
            {
                expression = expression.Replace(replacement.Key, Convert.ToString(replacement.Value));
            }
        }
        private TData Calculate(string expression,string name = "")
        {
            FormatExpression(ref expression);

            try
            {
                return LJExprParser.Parse(expression).Result;
            } catch (Exception ex)
            {
                throw new LJCommonException($"计算{name}公式错误!expression: {expression},exception: {ex.Message}");
            }
        }
        private TData Calculate(string expression, out string expressionOut, string name = "")
        {
            FormatExpression(ref expression);
            expressionOut = expression;
            try
            {
                return LJExprParser.Parse(expression).Result;
            }
            catch (Exception ex)
            {
                throw new LJCommonException($"计算{name}公式错误!expression: {expression},exception: {ex.Message}");
            }
        }

        public static bool IsNumber(string input)
        {
            // 正则表达式匹配数字，包括正负号和小数点
            string pattern = @"^[+-]?(\d+(\.\d*)?|\.\d+)$";
            return Regex.IsMatch(input, pattern);
        }

        private object SqlCalculate(string expression, string name = "")
        {
            expression = ConvertToEnglishSymbols(expression);
            expression = ReplaceWith(expression, "@@", "");

            // 定义正则表达式模式，匹配包含【】的内容
            string pattern = @"【(.*?)】";

            // 创建正则表达式对象
            Regex regex = new Regex(pattern);

            // 使用正则表达式匹配输入字符串
            MatchCollection matches = regex.Matches(expression);

            var new_formula_replacements = new Dictionary<string, string>();
            var new_replacements = new Dictionary<string, object>();

            foreach (Match match in matches)
            {
                // 检查原始字典中是否存在该键，并添加到新字典中
                if (formula_replacements.TryGetValue(match.Value, out formulaItem item))
                {
                    new_formula_replacements[match.Value] = item.value;
                }

                if (replacements.TryGetValue(match.Value, out object value2))
                {
                    new_replacements[match.Value] = value2;
                }
            }

            foreach (var replacement in new_formula_replacements)
            {
                expression = expression.Replace(replacement.Key, replacement.Value);
            }

            foreach (var replacement in new_replacements)
            {
                var _rep = Convert.ToString(replacement.Value);
                if (!IsNumber(_rep))
                {
                    _rep = "'" + _rep + "'";
                }
                expression = expression.Replace(replacement.Key, " " + _rep);
            }

            try
            {
                cmd.CommandText = $@"{expression}";
                cmd.Parameters.Clear();
                var result = cmd.ExecuteScalar();
                return result != null && result != DBNull.Value ? result : 0;
            }
            catch (Exception ex)
            {
                throw new LJCommonException($"计算{name}公式错误!expression: {expression},exception: {ex.Message}");
            }
        }

        public u_bednet GetBedNet(int bednetid)
        {
            var bednet = new u_bednet() { bednetid = bednetid };
            var outputFields = @"bednetid,deptid,bednettypeid,mattress_width,mattress_length,mattress_height,if_doublenet,if_doublespring,snake_wire_diameter,
                                snake_wire_mtrl_formula,snake_wire_mtrl_cost,pocket_around_spring_formula,pocket_around_spring_cost,pocket_around_fabrics_formula,
                                pocket_around_fabrics_cost,hard_around_mtrl_formula,hard_around_mtrl_cost,hard_around_hr_formula,hard_around_hr_cost,
                                spring_mtrl_cost,spring_hr_cost,glue_price,glue_mtrl_formula,glue_mtrl_cost,fabrics1_mtrl_formula,fabrics1_mtrl_cost,
                                fabrics2_mtrl_formula,fabrics2_mtrl_cost,if_side_iron,side_iron_lossrate,side_iron_price,side_iron_mtrl_formula,
                                side_iron_mtrl_cost,side_iron_hr_formula,side_iron_hr_cost,cnail_price,cnail_mtrl_formula,cnail_mtrl_cost,cnail_hr_formula,
                                cnail_hr_cost,sponge_mtrlid,sponge_thickness,sponge_price,sponge_mtrl_formula,sponge_mtrl_cost,sponge_hr_formula,
                                sponge_hr_cost,edge_mtrlid,edge_price,edge_mtrl_formula,edge_mtrl_cost,edge_hr_formula,edge_hr_cost,fork_qty,fork_price,
                                fork_mtrl_formula,fork_mtrl_cost,fork_hr_formula,fork_hr_cost,if_rsORwa,rsORwa_price,rsORwa_mtrl_formula,rsORwa_mtrl_cost,
                                rsORwa_hr_formula,rsORwa_hr_cost,if_sponge_drilling,sponge_drilling_hr_formula,sponge_drilling_hr_cost,total_hr_cost,
                                total_mtrl_cost,total_fees_cost,total_cost,createtime,createby,bednetcode,bednetname,spring_mtrl_formula,spring_hr_formula,
                                sponge_mtrl_cost_replace_formula,sponge_hr_cost_replace_formula,edge_mtrl_cost_replace_formula,edge_hr_cost_replace_formula,
                                fork_mtrl_cost_replace_formula,fork_hr_cost_replace_formula,rsORwa_mtrl_cost_replace_formula,rsORwa_hr_cost_replace_formula,
                                sponge_drilling_hr_cost_replace_formula,snake_wire_mtrl_cost_replace_formula,flag,taxrate,taxes,commissionrate,commission,fob,
                                profitrate,nottax_factory_cost,nottax_dept_cost,dept_cost,foreign_cost,extras_cost,dept_profitrate,moneyrate,temp_flag,felt_mtrlid,
                                felt_qty,felt_price,felt_dscrp,felt_mtrl_formula,felt_mtrl_cost,felt_hr_formula,felt_hr_cost,felt_mtrl_cost_replace_formula,
                                felt_hr_cost_replace_formula,extras_cost_dscrp,iffork,ifsaleout,autotype,felt_mtrl_x_cost,felt_hr_x_cost,felt_x_qty,
                                felt_mtrl_x_cost_replace_formula,felt_hr_x_cost_replace_formula,felt_x_mtrlid,sale_point,packtype,packqty,other_rate,
                                transport_type,packmtrl,packet_mtrl_formula,packet_hr_formula,packet_mtrl_cost,packet_hr_cost,packet_mtrl_cost_replace_formula,
                                packet_hr_cost_replace_formula,sponge_height,edge_height,sponge_tc_thickness,sponge_tc_height,sponge_tc_mtrlid,sponge_mtrl_tc_cost,
                                sponge_mtrl_tc_formula,sponge_mtrl_tc_cost_replace_formula,sum_weight,spring_weight,snake_weight,side_weight,duo_qv_str,
                                spring_weight_formula,side_iron_weight_formula,hard_around_weight_formula,fabrics1_weight_formula,fabrics2_weight_formula,
                                felt_weight_formula,cnail_weight_formula,sponge_weight_formula,sponge_weight_tc_formula,edge_weight_formula,fork_weight_formula,
                                spring_weight_replace_formula,side_iron_weight_replace_formula,hard_around_weight_replace_formula,fabrics1_weight_replace_formula,
                                fabrics2_weight_replace_formula,felt_weight_replace_formula,cnail_weight_replace_formula,sponge_weight_replace_formula,
                                sponge_weight_tc_replace_formula,edge_weight_replace_formula,fork_weight_replace_formula,spring_weight_qty,
                                side_iron_weight_qty,hard_around_weight_qty,fabrics1_weight_qty,fabrics2_weight_qty,felt_weight_qty,
                                cnail_weight_qty,sponge_weight_qty,sponge_weight_tc_qty,edge_weight_qty,fork_weight_qty,if_jb,if_stock_up";
            DbSqlHelper.SelectOne(cmd, bednet, outputFields);

            return bednet;
        }

        public u_bednet GetBedNet(int bednetid,string fields)
        {
            if (bednetid <= 0)
            {
                throw new LJCommonException("查找床网报价失败,ID错误!");
            }
            var bednet = new u_bednet() { bednetid = bednetid };
            var outputFields = fields ?? @"bednetid,deptid,bednettypeid,mattress_width,mattress_length,mattress_height,if_doublenet,if_doublespring,snake_wire_diameter,
                                snake_wire_mtrl_formula,snake_wire_mtrl_cost,pocket_around_spring_formula,pocket_around_spring_cost,pocket_around_fabrics_formula,
                                pocket_around_fabrics_cost,hard_around_mtrl_formula,hard_around_mtrl_cost,hard_around_hr_formula,hard_around_hr_cost,
                                spring_mtrl_cost,spring_hr_cost,glue_price,glue_mtrl_formula,glue_mtrl_cost,fabrics1_mtrl_formula,fabrics1_mtrl_cost,
                                fabrics2_mtrl_formula,fabrics2_mtrl_cost,if_side_iron,side_iron_lossrate,side_iron_price,side_iron_mtrl_formula,
                                side_iron_mtrl_cost,side_iron_hr_formula,side_iron_hr_cost,cnail_price,cnail_mtrl_formula,cnail_mtrl_cost,cnail_hr_formula,
                                cnail_hr_cost,sponge_mtrlid,sponge_thickness,sponge_price,sponge_mtrl_formula,sponge_mtrl_cost,sponge_hr_formula,
                                sponge_hr_cost,edge_mtrlid,edge_price,edge_mtrl_formula,edge_mtrl_cost,edge_hr_formula,edge_hr_cost,fork_qty,fork_price,
                                fork_mtrl_formula,fork_mtrl_cost,fork_hr_formula,fork_hr_cost,if_rsORwa,rsORwa_price,rsORwa_mtrl_formula,rsORwa_mtrl_cost,
                                rsORwa_hr_formula,rsORwa_hr_cost,if_sponge_drilling,sponge_drilling_hr_formula,sponge_drilling_hr_cost,total_hr_cost,
                                total_mtrl_cost,total_fees_cost,total_cost,createtime,createby,bednetcode,bednetname,spring_mtrl_formula,spring_hr_formula,
                                sponge_mtrl_cost_replace_formula,sponge_hr_cost_replace_formula,edge_mtrl_cost_replace_formula,edge_hr_cost_replace_formula,
                                fork_mtrl_cost_replace_formula,fork_hr_cost_replace_formula,rsORwa_mtrl_cost_replace_formula,rsORwa_hr_cost_replace_formula,
                                sponge_drilling_hr_cost_replace_formula,snake_wire_mtrl_cost_replace_formula,flag,taxrate,taxes,commissionrate,commission,fob,
                                profitrate,nottax_factory_cost,nottax_dept_cost,dept_cost,foreign_cost,extras_cost,dept_profitrate,moneyrate,temp_flag,felt_mtrlid,
                                felt_qty,felt_price,felt_dscrp,felt_mtrl_formula,felt_mtrl_cost,felt_hr_formula,felt_hr_cost,felt_mtrl_cost_replace_formula,
                                felt_hr_cost_replace_formula,extras_cost_dscrp,iffork,ifsaleout,autotype,felt_mtrl_x_cost,felt_hr_x_cost,felt_x_qty,
                                felt_mtrl_x_cost_replace_formula,felt_hr_x_cost_replace_formula,felt_x_mtrlid,sale_point,packtype,packqty,other_rate,
                                transport_type,packmtrl,packet_mtrl_formula,packet_hr_formula,packet_mtrl_cost,packet_hr_cost,packet_mtrl_cost_replace_formula,
                                packet_hr_cost_replace_formula,sponge_height,edge_height,sponge_tc_thickness,sponge_tc_height,sponge_tc_mtrlid,sponge_mtrl_tc_cost,
                                sponge_mtrl_tc_formula,sponge_mtrl_tc_cost_replace_formula,sum_weight,spring_weight,snake_weight,side_weight,duo_qv_str,
                                spring_weight_formula,side_iron_weight_formula,hard_around_weight_formula,fabrics1_weight_formula,fabrics2_weight_formula,
                                felt_weight_formula,cnail_weight_formula,sponge_weight_formula,sponge_weight_tc_formula,edge_weight_formula,fork_weight_formula,
                                spring_weight_replace_formula,side_iron_weight_replace_formula,hard_around_weight_replace_formula,fabrics1_weight_replace_formula,
                                fabrics2_weight_replace_formula,felt_weight_replace_formula,cnail_weight_replace_formula,sponge_weight_replace_formula,
                                sponge_weight_tc_replace_formula,edge_weight_replace_formula,fork_weight_replace_formula,spring_weight_qty,
                                side_iron_weight_qty,hard_around_weight_qty,fabrics1_weight_qty,fabrics2_weight_qty,felt_weight_qty,
                                cnail_weight_qty,sponge_weight_qty,sponge_weight_tc_qty,edge_weight_qty,fork_weight_qty,if_jb,if_stock_up";
            DbSqlHelper.SelectOne(cmd, bednet, outputFields);

            return bednet;
        }

        public List<u_bednetmx_spring> GetBedNetSpringList(int bednetid)
        {
            var springList = new List<u_bednetmx_spring>();
            var outputFields = @"bednetmx_partid,bednetmxid,springid,spring_qty_width,spring_qty_length,fabrics1_mtrl_cost,spring_mtrl_cost,spring_hr_cost,spring_mtrl_cost_replace_formula,spring_hr_cost_replace_formula,spring_weight_replace_formula";
            var selectStr = @"SELECT bednetmx_partid
	                            ,u_bednetmx_spring.bednetmxid AS bednetmxid
	                            ,u_bednetmx_spring.springid AS springid
	                            ,u_bednetmx_spring.spring_qty_width AS spring_qty_width
	                            ,u_bednetmx_spring.spring_qty_length AS spring_qty_length
	                            ,u_bednetmx_spring.fabrics1_mtrl_cost AS fabrics1_mtrl_cost
	                            ,u_bednetmx_spring.spring_mtrl_cost AS spring_mtrl_cost
	                            ,u_bednetmx_spring.spring_hr_cost AS spring_hr_cost
	                            ,u_bednetmx_spring.spring_mtrl_cost_replace_formula AS spring_mtrl_cost_replace_formula
	                            ,u_bednetmx_spring.spring_hr_cost_replace_formula AS spring_hr_cost_replace_formula
	                            ,u_bednetmx_spring.spring_weight_replace_formula AS spring_weight_replace_formula
                            FROM u_bednetmx_spring
                            INNER JOIN u_bednetmx ON u_bednetmx.bednetmxid = u_bednetmx_spring.bednetmxid";
            DbSqlHelper.SelectJoin(cmd,selectStr, "u_bednetmx.bednetid = @bednetid",new Dictionary<string, object>() { { "@bednetid",bednetid } }, "bednetmx_partid",outputFields,0,0,springList);

            return springList;
        }

        /// <summary>
        /// 获取床网分区系数
        /// </summary>
        /// <param name="areaid"></param>
        /// <returns></returns>
        public u_bednet_area GetBedNetArea(int areaid)
        {
            var outputFields = @"u_bednet_area.areaid, u_bednet_area.areaname, u_bednet_area.area_1, u_bednet_area.area_2, u_bednet_area.area_3, u_bednet_area.area_4, u_bednet_area.area_5, u_bednet_area.area_6, u_bednet_area.area_7, u_bednet_area.area_8, u_bednet_area.area_9, u_bednet_area.area_10, u_bednet_area.area_11, u_bednet_area.area_12, u_bednet_area.area_13, u_bednet_area.area_14, u_bednet_area.area_15
                                ,u_bednet_area.sponge_1 ,u_bednet_area.sponge_2 ,u_bednet_area.sponge_3 ,u_bednet_area.sponge_4 ,u_bednet_area.sponge_5 ,u_bednet_area.sponge_6 ,u_bednet_area.sponge_7 ,u_bednet_area.sponge_8 ,u_bednet_area.sponge_9 ,u_bednet_area.sponge_10 ,u_bednet_area.sponge_11 ,u_bednet_area.sponge_12 ,u_bednet_area.sponge_13 ,u_bednet_area.sponge_14 ,u_bednet_area.sponge_15";
            var bedentArea = new u_bednet_area() { areaid = areaid };
            DbSqlHelper.SelectOne(cmd, bedentArea, outputFields);

            return bedentArea;
        }

        /// <summary>
        /// 计算分配弹簧分区
        /// </summary>
        /// <param name="areaid"></param>
        public void GetSpringListQty(u_bednet bednet, u_bednetmx bednetMx, ref List<u_bednetmx_spring> springList)
        {
            if (bednetMx.if_part == 1 && springList.Count > 0)
            {

                if (!new List<string> { "2", "3", "5", "7", "三", "三区", "五", "五区", "七", "七区","左右区" }.Contains(bednet.duo_qv_str))
                {
                    throw new LJCommonException("主规格的床网多区设置有误，请重新设置");
                    return;
                }

                var _duoQty = bednet.duo_qv_str;
                if (new List<string> { "2", "左右", "左右区" }.Contains(bednet.duo_qv_str))
                {
                    _duoQty = "2";
                } else if (new List<string> { "三", "三区" }.Contains(bednet.duo_qv_str))
                {
                    _duoQty = "3";
                } 
                else if (new List<string> { "五", "五区" }.Contains(bednet.duo_qv_str))
                {
                    _duoQty = "5";
                }
                else if (new List<string> { "七", "七区" }.Contains(bednet.duo_qv_str))
                {
                    _duoQty = "7";
                }

                var _areaid = Convert.ToInt32(_duoQty);

                var bedentArea = GetBedNetArea(_areaid);

                if (bedentArea.area_1 == null) {
                    // 无匹配终止
                    throw new LJCommonException("主规格的床网多区设置有误，请重新设置");
                    return;
                }
                var attrKey = "area_";


                if (bednet.sponge_mtrlid > 0)
                {
                    // 有包边读取另外的配置
                    attrKey = "sponge_";
                }

                var bednetAreaDic = ToDictionary(bedentArea);

                var rateList = GetDuoquVal(bednetAreaDic, attrKey);
                if(bednet.sponge_mtrlid > 0 && rateList.Count <= 0)
                {
                    throw new LJCommonException("包边物料没有设置床网分区包边比例");
                }
                rateList = rateList.GetRange(0, springList.Count);
                var totality = rateList.Sum();

                var index = 0;
                var lengthValSum = 0;
                var sumLength = bednetMx.spring_qty_length.Value;
                var sumWidth = bednetMx.spring_qty_width.Value;

                if (bednetMx.if_hard_around > 0 && bednetMx.hard_around_row.Value > 0)
                {
                    sumLength = sumLength - bednetMx.hard_around_row.Value * 2;
                    sumWidth = sumWidth - bednetMx.hard_around_row.Value * 2;
                }
                foreach (var _spr in springList)
                {
                    var lengthVal = 0;
                    if (rateList.Count >= index + 1)
                    {
                        if (index <= rateList.Count - 1)
                        {
                            if (index == rateList.Count - 1)
                            {
                                lengthVal = sumLength - lengthValSum;
                            }
                            else
                            {
                                lengthVal = (int)Math.Round((rateList[index] / totality) * sumLength);
                                lengthValSum += lengthVal;
                            }
                        }
                        else
                        {
                            lengthVal = 0;
                        }
                    }
                    _spr.spring_qty_width = sumWidth;
                    _spr.spring_qty_length = lengthVal;
                    index++;
                }
            }
        }

        public Dictionary<string, object> ToDictionary(object obj)
        {
            var result = new Dictionary<string, object>();
            if (obj == null) return result;

            foreach (var prop in obj.GetType().GetProperties())
            {
                result[prop.Name] = prop.GetValue(obj);
            }

            return result;
        }
        public List<decimal> GetDuoquVal(Dictionary<string, object> item, string attr = "area_")
        {
            var arr = new List<decimal>();

            foreach (var key in item.Keys)
            {
                if (key.Contains(attr))
                {
                    // 尝试将值转换为 double
                    if (decimal.TryParse(item[key]?.ToString(), out decimal value))
                    {
                        arr.Add(value);
                    }
                }
            }

            // 忽略数组末尾连续的 0
            int i = arr.Count - 1;
            while (i >= 0 && arr[i] == 0)
            {
                i--;
            }

            return arr.Take(i + 1).ToList();
        }

        public List<u_bednetmx_mtrl> GetBedNetMxMtrlList(int bednetid)
        {
            var mxList = new List<u_bednetmx_mtrl>();
            var outputFields = @"bednetmtrlid,bednetid,formulakind,formula,mtrlid,price,gram_weight,cloth_width,if_inputqty,qty,costamt,if_success,replace_formula,priceunit,shrinkage";
            var selectStr = @"SELECT u_bednetmx_mtrl.bednetmtrlid AS bednetmtrlid
	                            ,u_bednetmx_mtrl.bednetid AS bednetid
	                            ,u_bednetmx_mtrl.formulakind AS formulakind
	                            ,u_bednetmx_mtrl.formula AS formula
	                            ,u_bednetmx_mtrl.mtrlid
	                            ,u_bednetmx_mtrl.price
	                            ,u_bednetmx_mtrl.gram_weight
	                            ,u_bednetmx_mtrl.cloth_width
	                            ,u_bednetmx_mtrl.if_inputqty
	                            ,u_bednetmx_mtrl.qty
	                            ,u_bednetmx_mtrl.costamt
	                            ,u_bednetmx_mtrl.if_success
	                            ,u_bednetmx_mtrl.replace_formula
	                            ,u_bednetmx_mtrl.priceunit
	                            ,u_bednetmx_mtrl.shrinkage
                            FROM u_bednetmx_mtrl";
            DbSqlHelper.SelectJoin(cmd, selectStr, "u_bednetmx_mtrl.bednetid = @bednetid", new Dictionary<string, object>() { { "@bednetid", bednetid } }, "bednetmtrlid", outputFields, 0, 0, mxList);

            return mxList;
        }

        public List<u_bednetmx> GetBedNetMxList(int bednetid)
        {
            var mxList = new List<u_bednetmx>();
            var outputFields = @"bednetmxid,bednetid,spring_qty_width,spring_qty_length,bednet_height,wire_mtrlid,springid,if_part,if_15strip,if_pocket_around,
                                pocket_around_springid,pocket_around_row,pocket_around_wire_price,pocket_around_spring_cost,pocket_around_fabrics_cost,
                                if_hard_around,hard_around_springid,hard_around_row,hard_around_wire_price,hard_around_mtrl_cost,hard_around_hr_cost,
                                fabrics1_mtrlid,fabrics1_price,fabrics1_mtrl_cost,fabrics2_mtrlid,fabrics2_price,fabrics2_mtrl_cost,if_side_iron,
                                side_iron_qty,side_iron_mtrl_cost,side_iron_hr_cost,pocket_around_spring_cost_replace_formula,pocket_around_fabrics_cost_replace_formula,
                                hard_around_mtrl_cost_replace_formula,hard_around_hr_cost_replace_formula,fabrics1_mtrl_cost_replace_formula,
                                fabrics2_mtrl_cost_replace_formula,side_iron_mtrl_cost_replace_formula,side_iron_hr_cost_replace_formula,
                                cnail_mtrl_cost_replace_formula,cnail_mtrl_cost,cnail_hr_cost_replace_formula,cnail_hr_cost,
                                glue_mtrl_cost_replace_formula,glue_mtrl_cost,spring_mtrl_cost,spring_hr_cost,spring_mtrl_cost_replace_formula,
                                spring_hr_cost_replace_formula,if_show,spring_weight_replace_formula";
            var selectStr = @"SELECT bednetmxid
	                                ,bednetid
	                                ,spring_qty_width
	                                ,spring_qty_length
	                                ,bednet_height
	                                ,wire_mtrlid
	                                ,springid
	                                ,if_part
	                                ,if_15strip
	                                ,if_pocket_around
	                                ,pocket_around_springid
	                                ,pocket_around_row
	                                ,pocket_around_wire_price
	                                ,pocket_around_spring_cost
	                                ,pocket_around_fabrics_cost
	                                ,if_hard_around
	                                ,hard_around_springid
	                                ,hard_around_row
	                                ,hard_around_wire_price
	                                ,hard_around_mtrl_cost
	                                ,hard_around_hr_cost
	                                ,fabrics1_mtrlid
	                                ,fabrics1_price
	                                ,fabrics1_mtrl_cost
	                                ,fabrics2_mtrlid
	                                ,fabrics2_price
	                                ,fabrics2_mtrl_cost
	                                ,if_side_iron
	                                ,side_iron_qty
	                                ,side_iron_mtrl_cost
	                                ,side_iron_hr_cost
	                                ,pocket_around_spring_cost_replace_formula
	                                ,pocket_around_fabrics_cost_replace_formula
	                                ,hard_around_mtrl_cost_replace_formula
	                                ,hard_around_hr_cost_replace_formula
	                                ,fabrics1_mtrl_cost_replace_formula
	                                ,fabrics2_mtrl_cost_replace_formula
	                                ,side_iron_mtrl_cost_replace_formula
	                                ,side_iron_hr_cost_replace_formula
	                                ,cnail_mtrl_cost_replace_formula
	                                ,cnail_mtrl_cost
	                                ,cnail_hr_cost_replace_formula
	                                ,cnail_hr_cost
	                                ,glue_mtrl_cost_replace_formula
	                                ,glue_mtrl_cost
	                                ,spring_mtrl_cost
	                                ,spring_hr_cost
	                                ,spring_mtrl_cost_replace_formula
	                                ,spring_hr_cost_replace_formula
	                                ,1 AS if_show
	                                ,spring_weight_replace_formula
                                FROM u_bednetmx";
            DbSqlHelper.SelectJoin(cmd, selectStr, "u_bednetmx.bednetid = @bednetid", new Dictionary<string, object>() { { "@bednetid", bednetid } }, "bednetmxid", outputFields, 0, 0, mxList);

            return mxList;
        }

        public void SaveBedNet(u_bednet bednet, List<u_bednetmx> mxlist, List<u_bednetmx_spring> springList)
        {
            //
            CalCulateFormula(bednet, mxlist, springList);
            // 
            SaveBedNetCheck(bednet, mxlist,springList);

            var dtNow = DateTime.Now;
            var fields = @"deptid,bednettypeid,mattress_width,mattress_length,mattress_height,if_doublenet,if_doublespring,snake_wire_diameter,
                                        snake_wire_mtrl_formula,snake_wire_mtrl_cost,pocket_around_spring_formula,pocket_around_spring_cost,
                                        pocket_around_fabrics_formula,pocket_around_fabrics_cost,hard_around_mtrl_formula,hard_around_mtrl_cost,
                                        hard_around_hr_formula,hard_around_hr_cost,spring_mtrl_cost,spring_hr_cost,glue_price,glue_mtrl_formula,
                                        glue_mtrl_cost,fabrics1_mtrl_formula,fabrics1_mtrl_cost,fabrics2_mtrl_formula,fabrics2_mtrl_cost,
                                        if_side_iron,side_iron_lossrate,side_iron_price,side_iron_mtrl_formula,side_iron_mtrl_cost,side_iron_hr_formula,
                                        side_iron_hr_cost,cnail_price,cnail_mtrl_formula,cnail_mtrl_cost,cnail_hr_formula,cnail_hr_cost,sponge_mtrlid,
                                        sponge_thickness,sponge_price,sponge_mtrl_formula,sponge_mtrl_cost,sponge_hr_formula,sponge_hr_cost,edge_mtrlid,
                                        edge_price,edge_mtrl_formula,edge_mtrl_cost,edge_hr_formula,edge_hr_cost,fork_qty,fork_price,fork_mtrl_formula,
                                        fork_mtrl_cost,fork_hr_formula,fork_hr_cost,if_rsORwa,rsORwa_price,rsORwa_mtrl_formula,rsORwa_mtrl_cost,rsORwa_hr_formula,
                                        rsORwa_hr_cost,if_sponge_drilling,sponge_drilling_hr_formula,sponge_drilling_hr_cost,total_hr_cost,total_mtrl_cost,
                                        total_fees_cost,total_cost,createtime,createby,bednetname,spring_mtrl_formula,spring_hr_formula,
                                        sponge_mtrl_cost_replace_formula,sponge_hr_cost_replace_formula,edge_mtrl_cost_replace_formula,edge_hr_cost_replace_formula,
                                        fork_mtrl_cost_replace_formula,fork_hr_cost_replace_formula,rsORwa_mtrl_cost_replace_formula,rsORwa_hr_cost_replace_formula,
                                        sponge_drilling_hr_cost_replace_formula,snake_wire_mtrl_cost_replace_formula,taxrate,taxes,commissionrate,commission,fob,
                                        profitrate,nottax_factory_cost,nottax_dept_cost,dept_cost,foreign_cost,extras_cost,dept_profitrate,moneyrate,temp_flag,
                                        felt_mtrlid,felt_qty,felt_price,felt_dscrp,felt_mtrl_formula,felt_mtrl_cost,felt_hr_formula,felt_hr_cost,
                                        felt_mtrl_cost_replace_formula,felt_hr_cost_replace_formula,extras_cost_dscrp,iffork,ifsaleout,autotype,
                                        felt_mtrl_x_cost,felt_hr_x_cost,felt_x_qty,felt_mtrl_x_cost_replace_formula,felt_hr_x_cost_replace_formula,
                                        felt_x_mtrlid,sale_point,packtype,packqty,other_rate,transport_type,packmtrl,packet_mtrl_formula,
                                        packet_hr_formula,packet_mtrl_cost,packet_hr_cost,packet_mtrl_cost_replace_formula,packet_hr_cost_replace_formula,
                                        sponge_height,edge_height,sponge_tc_thickness,sponge_tc_height,sponge_tc_mtrlid,sponge_mtrl_tc_formula,
                                        sponge_mtrl_tc_cost,sponge_mtrl_tc_cost_replace_formula,duo_qv_str,spring_weight_formula,side_iron_weight_formula,
                                        hard_around_weight_formula,fabrics1_weight_formula,fabrics2_weight_formula,felt_weight_formula,cnail_weight_formula,
                                        sponge_weight_formula,sponge_weight_tc_formula,edge_weight_formula,fork_weight_formula,spring_weight_replace_formula,
                                        side_iron_weight_replace_formula,hard_around_weight_replace_formula,fabrics1_weight_replace_formula,
                                        fabrics2_weight_replace_formula,felt_weight_replace_formula,cnail_weight_replace_formula,sponge_weight_replace_formula,
                                        sponge_weight_tc_replace_formula,edge_weight_replace_formula,fork_weight_replace_formula,spring_weight_qty,
                                        side_iron_weight_qty,hard_around_weight_qty,fabrics1_weight_qty,fabrics2_weight_qty,felt_weight_qty,cnail_weight_qty,
                                        sponge_weight_qty,sponge_weight_tc_qty,edge_weight_qty,fork_weight_qty,sum_weight,if_jb,flag,if_stock_up,version";

            var fieldsMx = @"bednetmxid,bednetid,spring_qty_width,spring_qty_length,bednet_height,wire_mtrlid,springid,if_part,if_15strip,
                                        if_pocket_around,pocket_around_springid,pocket_around_row,pocket_around_wire_price,pocket_around_spring_cost,
                                        pocket_around_fabrics_cost,if_hard_around,hard_around_springid,hard_around_row,hard_around_wire_price,
                                        hard_around_mtrl_cost,hard_around_hr_cost,fabrics1_mtrlid,fabrics1_price,fabrics1_mtrl_cost,fabrics2_mtrlid,
                                        fabrics2_price,fabrics2_mtrl_cost,if_side_iron,side_iron_qty,side_iron_mtrl_cost,side_iron_hr_cost,
                                        pocket_around_spring_cost_replace_formula,pocket_around_fabrics_cost_replace_formula,hard_around_mtrl_cost_replace_formula,
                                        hard_around_hr_cost_replace_formula,fabrics1_mtrl_cost_replace_formula,fabrics2_mtrl_cost_replace_formula,
                                        side_iron_mtrl_cost_replace_formula,side_iron_hr_cost_replace_formula,cnail_mtrl_cost_replace_formula,cnail_mtrl_cost,
                                        cnail_hr_cost_replace_formula,cnail_hr_cost,glue_mtrl_cost_replace_formula,glue_mtrl_cost,spring_mtrl_cost,spring_hr_cost,
                                        spring_mtrl_cost_replace_formula,spring_hr_cost_replace_formula,spring_weight_replace_formula";

            var fieldsMx_spring = @"bednetmx_partid,bednetmxid,springid,spring_qty_width,spring_qty_length,fabrics1_mtrl_cost,spring_mtrl_cost,
                                                spring_hr_cost,spring_mtrl_cost_replace_formula,spring_hr_cost_replace_formula,spring_weight_replace_formula";

            if (bednet.if_stock_up == null)
            {
                bednet.if_stock_up = 0;
            }

            if (bednet.bednetid <= 0)
            {
                //新建
                fields += ",bednetid,bednetcode";

                bednet.bednetid = BllHelper.GetID(cmd, "u_bednet");
                bednet.createtime = dtNow;
                bednet.createby = context.tokendata.username;
                bednet.version = 1;

                if (string.IsNullOrEmpty(bednet.bednetcode))
                {
                    var nettype = new u_bednet_type() { bednettypeid = bednet.bednettypeid };
                    DbSqlHelper.SelectOne(cmd, nettype, "typecode");

                    // 编号-年月日+流水
                    bednet.bednetcode = $"{nettype.typecode}-{dtNow.ToString("yyyyMMdd")}{(bednet.bednetid.Value % 10000).ToString("D4")}";
                }

                DbSqlHelper.Insert(cmd, "u_bednet", null, bednet, fields);
            }
            else
            {
                //修改
                foreach (var mx in mxlist)
                {
                    cmd.CommandText = @"DELETE FROM u_bednetmx_spring WHERE bednetmxid = @bednetmxid";
                    cmd.Parameters.Clear();
                    cmd.Parameters.AddWithValue("@bednetmxid", mx.bednetmxid);
                    cmd.ExecuteNonQuery();
                }

                cmd.CommandText = @"DELETE FROM u_bednetmx WHERE bednetid = @bednetid";
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@bednetid", bednet.bednetid);
                cmd.ExecuteNonQuery();

                bednet.update_date = dtNow;
                bednet.update_emp = context.tokendata.username;
                bednet.version++;
                fields += ",update_date,update_emp";
                DbSqlHelper.Update(cmd, "u_bednet", null, bednet, "bednetid", fields);
            }

            foreach (var mx in mxlist)
            {
                mx.bednetid = bednet.bednetid;
                mx.bednetmxid = BllHelper.GetID(cmd, "u_bednetmx");

                DbSqlHelper.Insert(cmd, "u_bednetmx", null, mx, fieldsMx);

                if (springList != null && springList.Any())
                {
                    foreach (var spring in springList)
                    {
                        spring.bednetmxid = mx.bednetmxid;
                        spring.bednetmx_partid = BllHelper.GetID(cmd, "u_bednetmx_spring");

                        DbSqlHelper.Insert(cmd, "u_bednetmx_spring", null, spring, fieldsMx_spring);
                    }
                }
            }

            var hisprice = new u_his_price
            {
                bednetid_mattressid = bednet.bednetid,
                typeid = 0,
                cmpdate = dtNow,
                cmpemp = context.tokendata.username,
                nottax_dept_cost = bednet.nottax_dept_cost,
                dept_cost = bednet.dept_cost,
                foreign_cost = bednet.foreign_cost
            };
            var fieldsHs = "bednetid_mattressid, typeid, cmpdate, cmpemp, nottax_dept_cost, dept_cost, foreign_cost";
            DbSqlHelper.Insert(cmd, "u_his_price", null, hisprice, fieldsHs);

            // 解锁
            LockHelper.UnLockBill(cmd, BillKeyWord, bednet.bednetid.Value, context.tokendata.username, 0);
        }
        /// <summary>
        /// 保存床网检测
        /// </summary>
        /// <param name="mattress"></param>
        /// <exception cref="LJCommonException"></exception>
        public void SaveBedNetCheck(u_bednet bednet, List<u_bednetmx> mxlist, List<u_bednetmx_spring> springList)
        {
            if (bednet == null) throw new LJCommonException("床网报价保存失败,数据异常!");
            if (mxlist == null || mxlist.Count <= 0) throw new LJCommonException("床网报价保存失败，明细内容为空!");

            if (bednet.bednetid > 0)
            {
                // 检查锁
                if (LockHelper.CheckIsLock(cmd, MattressHelper.BillKeyWord, bednet.bednetid.Value, context.tokendata.username, out string arg_msg)) throw new LJCommonException(arg_msg);
                // 检测版本控制
                CheckBillVersion<u_bednet>(cmd, bednet.bednetid.Value, bednet.version);
            }
        }
        public void CopyBedNet(u_bednet bednet,u_bednetmx bednetmx,out int newId)
        {
            var bedNet_copy = GetBedNet(bednet.bednetid.Value);

            var bedNetMxList = GetBedNetMxList(bednet.bednetid.Value);
            var springList = GetBedNetSpringList(bednet.bednetid.Value);

            // 判断copy_bedNet.bednetcode是否存在@@字符串，如果存在，则删除@@后面的字符串，包括@@
            if (bedNet_copy.bednetcode.IndexOf("@@") > -1)
            {
                bedNet_copy.bednetcode = bedNet_copy.bednetcode.Substring(bedNet_copy.bednetcode.IndexOf("@@"));
            }

            bedNet_copy.bednetcode += " @@";
            bedNet_copy.bednetcode += DateTime.Now.ToString("yyyMMdd_mmhhss");
            bedNet_copy.bednetid = 0;
            bedNet_copy.mattress_width = bednet.mattress_width;
            bedNet_copy.mattress_length = bednet.mattress_length;

            foreach(var mx in bedNetMxList)
            {
                if(bednetmx.spring_qty_width > 0 && bednetmx.spring_qty_length > 0)
                {
                    mx.spring_qty_length = bednetmx.spring_qty_length;
                    mx.spring_qty_width = bednetmx.spring_qty_width;
                }
            }

            SaveBedNet(bedNet_copy, bedNetMxList, springList);

            newId = bedNet_copy.bednetid.Value;
        }

        public List<u_bednet_qingdan> GetBedNetQingDan(int bednetid)
        {
            string bednetName = string.Empty;
            string areaType = string.Empty;
            string rollPackage = string.Empty;
            string specifications = string.Empty;
            string arrangement = string.Empty;
            string bednetHeight = string.Empty;
            string springs = string.Empty;
            string edgeIron = string.Empty;
            string bottomNonwovenFabric = string.Empty;
            string topPadMaterial = string.Empty;
            string bottomPadMaterial = string.Empty;
            string bagNonwovenFabric = string.Empty;
            string surroundingReinforcementRows = string.Empty;
            string springPins = string.Empty;
            string foamBorderMaterial = string.Empty;
            string fillingFoamMaterial = string.Empty;

            var bednet = GetBedNet(bednetid);

            var mxList = GetBedNetMxList(bednetid);
            var springList = GetBedNetSpringList(bednetid);
            
            var dept = Cache.GetData<u_dept, DeptMapping>(bednet.deptid.Value); ;

            if(bednet.deptid == null || bednet.deptid.Value <= 0)
            {
                throw new LJCommonException("获取床网清单，deptid错误");
            }

            if (bednet.bednettypeid == null || bednet.bednettypeid.Value <= 0)
            {
                throw new LJCommonException("获取床网清单，bednettypeid错误");
            }

            if (dept.pricelistid <= 0)
            {
                throw new LJCommonException("获取床网清单，pricelistid错误");
            }

            var bednetType = new u_bednet_type() { bednettypeid = bednet.bednettypeid };
            DbSqlHelper.SelectOne(cmd, bednetType, "typename");

            var mx = mxList[0];

            var qdList = new List<u_bednet_qingdan>();
            var nameList = new Dictionary<string,string>();

            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "床网名称"
            });

            var sprint_type_name = GetSpringTypeName(mx.springid.Value);
            bednetName = $"{("高压缩".Equals(sprint_type_name) ? "高压缩" + bednetType.typename : bednetType.typename)}";
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "床网类型",
                pznamemx = bednetName,
                amt = 0,
                useqty = 0
            });
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "规格",
                pznamemx = $"{bednet.mattress_width}*{bednet.mattress_length}*{bednet.mattress_height}",
                amt = 0,
                useqty = 0
            });
            specifications = $"{bednet.mattress_width}*{bednet.mattress_length}";
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "排列",
                pznamemx = $"{mx.spring_qty_width}*{mx.spring_qty_length}",
                amt = 0,
                useqty = 0
            });
            arrangement = $"{mx.spring_qty_width}*{mx.spring_qty_length}";
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "床网高度",
                pznamemx = $"{mx.bednet_height.Value.ToString("#,##0.##")}高",
                amt = 0,
                useqty = 0
            });
            bednetHeight = $"{mx.bednet_height.Value.ToString("#,##0.##")}高";
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "弹簧线径/高度/口径/中心直径/圈数",
                pznamemx = mx.if_part == 0 ? GetSpringName(mx.springid.Value) : string.Empty,
                amt = 0,
                useqty = 0
            });
            if (mx.if_part == 0)
            {
                springs = GetSpringName(mx.springid.Value);
            }
            else
            {
                string ls_left = string.Empty;
                string ls_right = string.Empty;
                string ls_t_temp = string.Empty;
                string ls_t_name = string.Empty;

                if (springList.Count >= 1)
                {
                    ls_t_name = GetSpringName(springList[0].springid.Value);
                    int pos = ls_t_name.IndexOf('/');
                    if (pos > 0 && springList.Count > 1)
                    {
                        ls_left = ls_t_name.Substring(0, pos);
                        ls_right = ls_t_name.Substring(pos);
                        ls_t_temp = ls_left;

                        // Use StringBuilder to efficiently build ls_t_temp
                        StringBuilder sb = new StringBuilder(ls_t_temp);
                        for (int i = 1; i < springList.Count; i++)
                        {
                            ls_t_name = GetSpringName(springList[i].springid.Value);
                            pos = ls_t_name.IndexOf('/');
                            if (pos > 0)
                            {
                                ls_left = ls_t_name.Substring(0, pos);
                                sb.Append("+").Append(ls_left);
                            }
                        }

                        ls_t_temp = sb.ToString();
                    }
                }

                springs = ls_t_temp + "/" + ls_right;
            }


            for (int i = 1;i <= 5;i++)
            {
                qdList.Add(new u_bednet_qingdan()
                {
                    pzname = $"多区弹簧{i}/高度/口径/中心直径/圈数",
                    pznamemx = springList.Count >= 1 && i <= springList.Count ? GetSpringName(springList[i - 1].springid.Value) : string.Empty,
                    amt = 0,
                    useqty = 0
                });
            }
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "边铁条数",
                pznamemx = mx.side_iron_qty > 0 ? $"{mx.side_iron_qty.Value.ToString("#,##0.##")}条" : string.Empty,
                amt = 0,
                useqty = 0
            });
            edgeIron = mx.side_iron_qty > 0 ? $"{mx.side_iron_qty.Value.ToString("#,##0.##")}条边铁" : "无边铁";
            var mtrldef1 = new u_mtrl_price();
            DbSqlHelper.SelectOne(cmd, "u_mtrl_price", "mtrltype = 2 AND mtrlid = @mtrlid", new Dictionary<string, object>() { { "mtrlid", mx.fabrics2_mtrlid } },mtrldef1, "name");
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "底面无纺布",
                pznamemx = mx.fabrics2_mtrlid > 0 ? mtrldef1.name : string.Empty,
                amt = 0,
                useqty = 0
            });
            bottomNonwovenFabric = mx.fabrics2_mtrlid > 0 ? mtrldef1.name : string.Empty;
            var mtrldef2 = new u_mtrl_price();
            DbSqlHelper.SelectOne(cmd, "u_mtrl_price", "mtrltype = 2 AND mtrlid = @mtrlid", new Dictionary<string, object>() { { "mtrlid", mx.fabrics1_mtrlid } }, mtrldef2, "name");
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "入袋无纺布",
                pznamemx = mx.fabrics1_mtrlid > 0 ? mtrldef2.name : string.Empty,
                amt = 0,
                useqty = 0
            });
            bagNonwovenFabric = mx.fabrics1_mtrlid > 0 ? mtrldef2.name : string.Empty;
            var mtrldef3 = new u_mtrl_price();
            DbSqlHelper.SelectOne(cmd, "u_mtrl_price", "mtrlid = @mtrlid", new Dictionary<string, object>() { { "mtrlid", bednet.felt_mtrlid } }, mtrldef3, "name");
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "上垫层物料",
                pznamemx = !string.IsNullOrEmpty(mtrldef3.name) ? mtrldef3.name : string.Empty,
                amt = 0,
                useqty = 0
            });
            topPadMaterial = !string.IsNullOrEmpty(mtrldef3.name) ? mtrldef3.name : string.Empty;
            var mtrldef4 = new u_mtrl_price();
            DbSqlHelper.SelectOne(cmd, "u_mtrl_price", "mtrlid = @mtrlid", new Dictionary<string, object>() { { "mtrlid", bednet.felt_x_mtrlid } }, mtrldef4, "name");
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "下垫层物料",
                pznamemx = !string.IsNullOrEmpty(mtrldef4.name) ? mtrldef4.name : string.Empty,
                amt = 0,
                useqty = 0
            });
            bottomPadMaterial = !string.IsNullOrEmpty(mtrldef4.name) ? mtrldef4.name : string.Empty;
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "四周加硬排数",
                pznamemx = mx.hard_around_row > 0 ? $"{mx.hard_around_row.Value.ToString("#,##0.##")}排{GetSpringName(mx.hard_around_springid.Value)}" : string.Empty,
                amt = 0,
                useqty = 0
            });
            surroundingReinforcementRows = mx.hard_around_row > 0 ? $"四周加硬{mx.hard_around_row.Value.ToString("#,##0.##")}排{GetSpringName(mx.hard_around_springid.Value)}" : string.Empty;
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "四周加硬弹簧线径/高度/口径/中心直径/圈数",
                pznamemx = mx.if_hard_around > 0 ? GetSpringName(mx.hard_around_springid.Value) : string.Empty,
                amt = 0,
                useqty = 0
            });
            var mtrldef5 = new u_mtrl_price();
            DbSqlHelper.SelectOne(cmd, "u_mtrl_price", "mtrlid = @mtrlid", new Dictionary<string, object>() { { "mtrlid", bednet.sponge_mtrlid } }, mtrldef5, "name");
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "海绵包边物料",
                pznamemx = !string.IsNullOrEmpty(mtrldef5.name) ? mtrldef5.name : string.Empty,
                amt = 0,
                useqty = 0
            });
            foamBorderMaterial = !string.IsNullOrEmpty(mtrldef5.name) ? $"{bednet.sponge_thickness.Value.ToString("#,##0.##")}分{bednet.sponge_height.Value.ToString("#,##0.##")}高{mtrldef5.name}" : string.Empty;
            var mtrldef6 = new u_mtrl_price();
            DbSqlHelper.SelectOne(cmd, "u_mtrl_price", "mtrlid = @mtrlid", new Dictionary<string, object>() { { "mtrlid", bednet.sponge_tc_mtrlid } }, mtrldef6, "name");
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "填充海绵物料",
                pznamemx = !string.IsNullOrEmpty(mtrldef6.name) ? mtrldef6.name : string.Empty,
                amt = 0,
                useqty = 0
            });
            fillingFoamMaterial = !string.IsNullOrEmpty(mtrldef6.name) ? $"{bednet.sponge_tc_thickness.Value.ToString("#,##0.##")}分{bednet.sponge_tc_height.Value.ToString("#,##0.##")}高{mtrldef6.name}" : string.Empty;
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "填充包边物料厚度",
                pznamemx = bednet.sponge_tc_thickness > 0 ? $"{bednet.sponge_tc_thickness.Value.ToString("#,##0.##")}分厚,{bednet.sponge_tc_height.Value.ToString("#,##0.##")}分高,{mtrldef6.name}" : string.Empty,
                amt = 0,
                useqty = 0
            });

            var mtrldef7 = new u_mtrl_price();
            DbSqlHelper.SelectOne(cmd, "u_mtrl_price", "mtrlid = @mtrlid", new Dictionary<string, object>() { { "mtrlid", bednet.edge_mtrlid } }, mtrldef7, "name");
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "封边物料",
                pznamemx = !string.IsNullOrEmpty(mtrldef7.name) ? mtrldef7.name : string.Empty,
                amt = 0,
                useqty = 0
            });

            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "封边高度",
                pznamemx = bednet.edge_height > 0 ? $"{bednet.edge_height.Value.ToString("#,##0.##")}高" : string.Empty,
                amt = 0,
                useqty = 0
            });

            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "胶条包角",
                pznamemx = bednet.if_rsorwa > 0 ? "有" : string.Empty,
                amt = 0,
                useqty = 0
            });
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "海绵打孔",
                pznamemx = bednet.if_sponge_drilling > 0 ? "有" : string.Empty,
                amt = 0,
                useqty = 0
            });
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "弹叉数量",
                pznamemx = bednet.fork_qty > 0 ? $"{bednet.fork_qty.Value.ToString("#,##0.##")}只弹叉" : string.Empty,
                amt = 0,
                useqty = 0
            });
            springPins = bednet.fork_qty > 0 ? $"{bednet.fork_qty.Value.ToString("#,##0.##")}只弹叉" : string.Empty;
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "15分布条",
                pznamemx = mx.if_15strip > 0 ? "有" : string.Empty,
                amt = 0,
                useqty = 0
            });
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "蛇线线径",
                pznamemx = bednet.snake_wire_diameter > 0 ? $"{bednet.snake_wire_diameter}" : string.Empty,
                amt = 0,
                useqty = 0
            });
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "四周口袋弹簧排数",
                pznamemx = mx.pocket_around_row > 0 ? $"{mx.pocket_around_row.Value.ToString("#,##0.##")}排" : string.Empty,
                amt = 0,
                useqty = 0
            });
            qdList.Add(new u_bednet_qingdan()
            {
                pzname = "四周口袋弹簧线径/高度/口径/中心直径/圈数",
                pznamemx = mx.if_pocket_around > 0 ? GetSpringName(mx.pocket_around_springid.Value) : string.Empty,
                amt = 0,
                useqty = 0
            });

            //设置床网名称
            //床网类型丨规格丨排列丨高度丨单/多区丨线径丨边铁丨海绵包边丨四周加硬丨弹叉丨底面物料
            StringBuilder ls_temp_name = new StringBuilder();

            ls_temp_name.Append(qdList[1].pznamemx)
                        .Append("丨")
                        .Append(qdList[3].pznamemx)
                        .Append("丨")
                        .Append(qdList[4].pznamemx);

            if (!string.IsNullOrEmpty(bednet.duo_qv_str))
            {
                areaType = $"{bednet.duo_qv_str}区";
                ls_temp_name.Append("丨")
                            .Append(bednet.duo_qv_str)
                            .Append("区");
            }
            else
            {
                areaType = string.IsNullOrEmpty(qdList[5].pznamemx) ? "多区" : "单区";
                ls_temp_name.Append("丨")
                            .Append(string.IsNullOrEmpty(qdList[5].pznamemx) ? "多区" : "单区");
            }

            if (string.IsNullOrEmpty(qdList[5].pznamemx))
            {
                for (int i = 6; i <= 10; i++)
                {
                    if (!string.IsNullOrEmpty(qdList[i].pznamemx))
                    {
                        ls_temp_name.Append("+" + qdList[i].pznamemx.Substring(0, Math.Min(qdList[i].pznamemx.IndexOf('/') - 1, qdList[i].pznamemx.Length)));
                    }
                }
            }
            else
            {
                ls_temp_name.Append("丨")
                            .Append(qdList[5].pznamemx);
            }

            AppendSpecialFields(ls_temp_name,qdList);

            rollPackage = bednet.if_jb == 0 ? string.Empty : "卷包";

            if (ls_temp_name.ToString().Contains("袋装"))
            {
                ls_temp_name.Clear();
                ls_temp_name.Append(bednetName)
                            .Append("丨")
                            .Append(areaType)
                            .Append("丨")
                            .Append(rollPackage)
                            .Append("丨")
                            .Append(specifications)
                            .Append("丨")
                            .Append(arrangement)
                            .Append("丨")
                            .Append(bednetHeight)
                            .Append("丨")
                            .Append(springs)
                            .Append("丨")
                            .Append(edgeIron)
                            .Append("丨")
                            .Append(bottomNonwovenFabric)
                            .Append("丨")
                            .Append(topPadMaterial)
                            .Append("丨")
                            .Append(bottomPadMaterial)
                            .Append("丨")
                            .Append(bagNonwovenFabric)
                            .Append("丨")
                            .Append(surroundingReinforcementRows)
                            .Append("丨")
                            .Append(springPins)
                            .Append("丨")
                            .Append(foamBorderMaterial)
                            .Append("丨")
                            .Append(fillingFoamMaterial);
            }

            qdList[0].pznamemx = ls_temp_name.ToString();
            qdList[0].amt = bednet.nottax_factory_cost;

            return qdList;
        }

        private void AppendSpecialFields(StringBuilder ls_temp_name,List<u_bednet_qingdan> qdList)
        {
            if (!string.IsNullOrEmpty(qdList[11].pznamemx))
            {
                ls_temp_name.Append("丨")
                            .Append(qdList[11].pznamemx == "" ? "无边铁" : "有边铁");
            }

            if (!string.IsNullOrEmpty(qdList[19].pznamemx))
            {
                ls_temp_name.Append("丨")
                            .Append(qdList[19].pznamemx)
                            .Append(qdList[19].pznamemx)
                            .Append("海绵包边");
            }

            if (!string.IsNullOrEmpty(qdList[16].pznamemx))
            {
                ls_temp_name.Append("丨")
                            .Append("四周加硬")
                            .Append(qdList[16].pznamemx);
            }

            if (!string.IsNullOrEmpty(qdList[26].pznamemx))
            {
                ls_temp_name.Append("丨")
                            .Append(qdList[26].pznamemx);
            }

            if (!string.IsNullOrEmpty(qdList[12].pznamemx))
            {
                ls_temp_name.Append("丨")
                            .Append("底面")
                            .Append(qdList[12].pznamemx);
            }
            else
            {
                if (string.IsNullOrEmpty(qdList[14].pznamemx))
                {
                    ls_temp_name.Append("丨")
                                .Append("底一张")
                                .Append(qdList[15].pznamemx);
                }
                else if (string.IsNullOrEmpty(qdList[15].pznamemx))
                {
                    ls_temp_name.Append("丨")
                                .Append("面一张")
                                .Append(qdList[14].pznamemx);
                }
                else
                {
                    ls_temp_name.Append("丨")
                                .Append("面底各一张")
                                .Append(qdList[14].pznamemx);
                }
            }

            if (!string.IsNullOrEmpty(qdList[21].pznamemx))
            {
                ls_temp_name.Append("丨")
                            .Append(qdList[21].pzname)
                            .Append(qdList[21].pznamemx);
            }
        }
        public string GetSpringName(int springid)
        {
            //var spring = new u_spring() { springid = springid };
            //DbSqlHelper.SelectOne(cmd, spring, "line_diameter,gram_weight,height,center_diameter,cyclenum,caliber");
            var spring = Cache.GetData<u_spring, SpringMapping>(springid);
            return spring.name;
        }

        public string GetSpringTypeName(int springid)
        {
            string sprintname = "";
            cmd.CommandText = @"SELECT u_springtype.springtypename FROM u_spring INNER JOIN u_springtype ON u_springtype.springtypeid = u_spring.springtypeid WHERE u_spring.springid = @springid";
            cmd.Parameters.Clear();
            cmd.Parameters.AddWithValue("@springid", springid);
            using(var reader = cmd.ExecuteReader())
            {
                if(reader.Read())
                {
                    sprintname = Convert.ToString(reader["springtypename"]);
                }
            }

            return sprintname;
        }

        public void CalCulateSpringQty(u_bednet bednet, List<u_bednetmx> mxlist, List<u_bednetmx_spring> springList)
        {

            // 默认方法
            AddFormulaKeyValue("计算弹簧排列个数-宽", "if（【卷包】=1，round((【床垫宽】- 2)/(【中心直径】-【卷排列宽】),0）,round((【床垫宽】- 2)/(【中心直径】-【排列宽】),0))");
            AddFormulaKeyValue("计算弹簧排列个数-长", "if（【卷包】=1，round((【床垫长】- 2)/(【中心直径】-【卷排列长】),0）,round((【床垫长】- 2)/(【中心直径】-【排列长】),0))");

            InitReplaceMents(bednet);

            foreach (var mx in mxlist)
            {
                var _springid = mx.springid;
                if (mx.if_part.Value == 1 && springList.Count > 0)
                {
                    //多区
                    _springid = springList[0].springid;
                }
                var spring = Cache.GetData<u_spring, SpringMapping>(_springid.Value);

                // 处理相同公式部分
                InitMxReplaceMents(bednet, mx, spring);

                InitSptringRepaceMents(spring);

                #region  计算 海绵包边材料成本 开始
                CalSpringMtrlCol2(bednet, mx, springList, "海绵包边");
                #endregion 计算 海绵包边材料成本 结束

                #region 弹簧排列个数-宽
                mx.spring_qty_width = Convert.ToInt32(CalculateVarFormula("计算弹簧排列个数-宽").DecimalValue);
                AddKeyValue("弹簧排列个数-宽", mx.spring_qty_width);
                #endregion


                #region 弹簧排列个数-长
                mx.spring_qty_length = Convert.ToInt32(CalculateVarFormula("计算弹簧排列个数-长").DecimalValue);
                AddKeyValue("弹簧排列个数-长", mx.spring_qty_length);
                #endregion
            }
        }

        public void SaveBedNetInterface(int bednetid, List<u_bednet_interface> mxlist, List<u_bednet_interface_qd> qdlist)
        {
            cmd.CommandText = @"DELETE u_bednet_interface WHERE bednetid = @bednetid";
            cmd.Parameters.Clear();
            cmd.Parameters.AddWithValue("@bednetid", bednetid);
            cmd.ExecuteNonQuery();

            cmd.CommandText = @"DELETE u_bednet_interface_qd WHERE bednetid = @bednetid";
            cmd.Parameters.Clear();
            cmd.Parameters.AddWithValue("@bednetid", bednetid);
            cmd.ExecuteNonQuery();

            foreach (var mx in mxlist)
            {
                mx.bednetid = bednetid;
                DbSqlHelper.Insert(cmd, mx, "bednetid,printid,itemname,bj_pzname,bj_namemx,actual_size,erp_pzid,bj_inputtype");
            }

            foreach (var mx in qdlist)
            {
                mx.bednetid = bednetid;
                DbSqlHelper.Insert(cmd, mx, "bednetid,printid,itemname,bj_pzname,bj_pzname_mx,bj_pzname_mx_mx,mtrlid,erp_mtrlid,wrkgrpid,wrkgrpid2,useqty,dscrp,actual_useqty,qd_actual_size,qd_pfgroupqty,formulaid,wrkgrpcode1,wrkgrpcode2");
            }
        }
        /// <summary>
        /// 床网报价审核
        /// </summary>
        /// <param name="bednetid"></param>
        /// <exception cref="LJCommonException"></exception>
        public void BedNetAudit(int bednetid)
        {
            var power63 = UserHelper.CheckFuncPower(cmd, context.tokendata.empid, 63);
            if (!power63)
            {
                throw new LJCommonException("你没有审核权限");
            }
            // 检查锁
            if (LockHelper.CheckIsLock(cmd, MattressHelper.BillKeyWord, bednetid, context.tokendata.username, out string arg_msg)) throw new LJCommonException(arg_msg);

            var bednet = GetBedNet(bednetid, "flag,bednetcode,version");

            if (bednet.flag == 1)
            {
                throw new LJCommonException($"床网报价【{bednet.bednetcode}】已审核，不能审核!");
            }

            bednet.flag = 1;
            bednet.version++;
            DbSqlHelper.Update(cmd, "u_bednet", null, bednet, "bednetid", "flag,version");
        }
        /// <summary>
        /// 床网报价撤销审核
        /// </summary>
        /// <param name="bednetid"></param>
        /// <exception cref="LJCommonException"></exception>
        public void BedNetCAudit(int bednetid)
        {
            var power64 = UserHelper.CheckFuncPower(cmd, context.tokendata.empid, 64);
            if (!power64)
            {
                throw new LJCommonException("你没有审核权限");
            }
            // 检查锁
            if (LockHelper.CheckIsLock(cmd, MattressHelper.BillKeyWord, bednetid, context.tokendata.username, out string arg_msg)) throw new LJCommonException(arg_msg);

            var bednet = GetBedNet(bednetid, "flag,bednetcode,version");
            if (bednet.flag == 0)
            {
                throw new LJCommonException($"床网报价【{bednet.bednetcode}】未审核，不能撤审!");
            }

            bednet.flag = 0;
            bednet.version++;
            DbSqlHelper.Update(cmd, "u_bednet", null, bednet, "bednetid", "flag,version");
        }

        #region 常量
        private static string BillKeyWord = BillNames.BedNetQuote;
        #endregion
    }
}
