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.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace JLHHJSvr.Helper
{
    internal class BedNetHelper : HelperBase
    {
        private Dictionary<string, object> replacements = new Dictionary<string, object>();
        private Dictionary<string, string> formula_replacements = new Dictionary<string, string>();

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

            InitReplaceMents(bednet);

            CulcalateCost(bednet, mxlist, springList);

            CulcalateWeight(bednet, mxlist, springList);
        }

        private void CulcalateCost(u_bednet bednet, List<u_bednetmx> mxlist, List<u_bednetmx_spring> springList)
        {
            foreach (var mx in mxlist)
            {
                var spring = new u_spring() { springid = mx.springid };
                DbSqlHelper.SelectOne(cmd, spring, "line_diameter,gram_weight,height,center_diameter");

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

                //计算 弹簧材料总成本
                #region 计算 弹簧材料总成本 开始
                if (!string.IsNullOrEmpty(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 = ReplaceWith(mx.spring_mtrl_cost_replace_formula, "【弹簧排列个数-宽】", $"(【弹簧排列个数-宽】 - {hard_around_row})");
                            mx.spring_mtrl_cost_replace_formula = ReplaceWith(mx.spring_mtrl_cost_replace_formula, "【弹簧计算个数(宽)】", $"(【弹簧计算个数(宽)】 - {hard_around_row})");
                            mx.spring_mtrl_cost_replace_formula = ReplaceWith(mx.spring_mtrl_cost_replace_formula, "【弹簧排列个数-长】", $"(【弹簧排列个数-长】 - {hard_around_row})");
                            mx.spring_mtrl_cost_replace_formula = ReplaceWith(mx.spring_mtrl_cost_replace_formula, "【弹簧计算个数(长)】", $"(【弹簧计算个数(长)】 - {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 = ReplaceWith(mx.spring_mtrl_cost_replace_formula, "【弹簧排列个数-宽】", $"(【弹簧排列个数-宽】 - {pocket_around_row})");
                            mx.spring_mtrl_cost_replace_formula = ReplaceWith(mx.spring_mtrl_cost_replace_formula, "【弹簧计算个数(宽)】", $"(【弹簧计算个数(宽)】 - {pocket_around_row})");
                            mx.spring_mtrl_cost_replace_formula = ReplaceWith(mx.spring_mtrl_cost_replace_formula, "【弹簧排列个数-长】", $"(【弹簧排列个数-长】 - {pocket_around_row})");
                            mx.spring_mtrl_cost_replace_formula = ReplaceWith(mx.spring_mtrl_cost_replace_formula, "【弹簧计算个数(长)】", $"(【弹簧计算个数(长)】 - {pocket_around_row})");
                        }

                        mx.spring_mtrl_cost = Calculate(mx.spring_mtrl_cost_replace_formula, "弹簧材料总成本").DecimalValue;
                        bednet.spring_mtrl_cost += mx.spring_mtrl_cost;
                    }
                    else
                    {
                        //多分区
                        foreach (var springItem in springList)
                        {
                            springItem.spring_mtrl_cost_replace_formula = bednet.spring_mtrl_formula;
                            CalSpringMtrlCol(bednet, mx, springItem);

                            springItem.spring_mtrl_cost = Calculate(springItem.spring_mtrl_cost_replace_formula, "弹簧材料总成本").DecimalValue;
                            mx.spring_mtrl_cost += springItem.spring_mtrl_cost;
                            bednet.spring_mtrl_cost += mx.spring_mtrl_cost;
                        }
                    }
                }
                #endregion 计算 弹簧材料总成本 结束

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

                    mx.spring_hr_cost = Calculate(mx.spring_hr_cost_replace_formula, "弹簧总人工成本").DecimalValue;
                    bednet.spring_hr_cost += mx.spring_hr_cost;
                }
                #endregion 计算 弹簧人工总成本 结束

                #region 计算 蛇线材料成本 开始
                if (!string.IsNullOrEmpty(bednet.spring_hr_formula))
                {
                    bednet.snake_wire_mtrl_cost_replace_formula = bednet.snake_wire_mtrl_formula;

                    CalSnakeCol(bednet,spring);

                    bednet.snake_wire_mtrl_cost += Calculate(bednet.snake_wire_mtrl_cost_replace_formula, "蛇线材料成本").DecimalValue;
                }
                #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;

                    mx.pocket_around_spring_cost = Calculate(mx.pocket_around_spring_cost_replace_formula, "四周口袋弹簧成本").DecimalValue;
                    bednet.pocket_around_spring_cost += mx.pocket_around_spring_cost;
                }
                #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;

                    mx.pocket_around_fabrics_cost = Calculate(mx.pocket_around_fabrics_cost_replace_formula, "四周口袋无纺布成本").DecimalValue;
                    bednet.pocket_around_fabrics_cost += mx.pocket_around_fabrics_cost;
                }
                #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;

                    mx.hard_around_mtrl_cost = Calculate(mx.hard_around_mtrl_cost_replace_formula, "四周加硬材料成本").DecimalValue;
                    bednet.hard_around_mtrl_cost += mx.hard_around_mtrl_cost;
                }
                #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;

                    mx.hard_around_hr_cost = Calculate(mx.hard_around_hr_cost_replace_formula, "四周加硬人力成本").DecimalValue;
                    bednet.hard_around_hr_cost += mx.hard_around_hr_cost;
                }
                #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, "入袋无纺布");

                    mx.fabrics1_mtrl_cost = Calculate(mx.fabrics1_mtrl_cost_replace_formula, "入袋无纺布材料成本").DecimalValue;
                    bednet.fabrics1_mtrl_cost += mx.fabrics1_mtrl_cost;
                }
                #endregion 计算 入袋无纺布材料成本 结束

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

                    bednet.glue_mtrl_cost += Calculate(mx.glue_mtrl_cost_replace_formula, "胶水材料成本").DecimalValue;
                }
                #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, "底面无纺布");

                    mx.fabrics2_mtrl_cost = Calculate(mx.fabrics2_mtrl_cost_replace_formula, "底面无纺布材料成本").DecimalValue;
                    bednet.fabrics2_mtrl_cost += mx.fabrics2_mtrl_cost;
                }
                #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;

                    mx.side_iron_hr_cost = Calculate(mx.side_iron_hr_cost_replace_formula, "边铁人力成本").DecimalValue;
                    bednet.side_iron_hr_cost += mx.side_iron_hr_cost;
                }
                #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;

                    mx.side_iron_mtrl_cost = Calculate(mx.side_iron_mtrl_cost_replace_formula, "边铁材料成本").DecimalValue;
                    bednet.side_iron_mtrl_cost += mx.side_iron_mtrl_cost;
                }
                #endregion 计算 边铁材料成本 结束

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

                    mx.cnail_mtrl_cost = Calculate(mx.cnail_mtrl_cost_replace_formula, "C钉/夹码材料成本").DecimalValue;
                    bednet.cnail_mtrl_cost += mx.cnail_mtrl_cost;
                }
                #endregion 计算 C钉/夹码材料 结束

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

                    mx.cnail_hr_cost = Calculate(mx.cnail_hr_cost_replace_formula, "C钉/夹码人力成本").DecimalValue;
                    bednet.cnail_hr_cost += mx.cnail_hr_cost;
                }
                #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, "海绵包边");

                    bednet.sponge_mtrl_cost += Calculate(bednet.sponge_mtrl_cost_replace_formula, "海绵包边材料成本").DecimalValue;
                }
                #endregion 计算 海绵包边材料成本 结束

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

                    bednet.sponge_hr_cost += Calculate(bednet.sponge_hr_cost_replace_formula, "海绵包边人力成本").DecimalValue;
                }
                #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, "填充海绵");

                    bednet.sponge_mtrl_tc_cost += Calculate(bednet.sponge_mtrl_tc_cost_replace_formula, "填充海绵成本").DecimalValue;
                }
                #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, "封边");

                    bednet.edge_mtrl_cost += Calculate(bednet.edge_mtrl_cost_replace_formula, "封边材料成本").DecimalValue;
                }
                #endregion 计算 封边材料成本 结束

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

                    bednet.edge_hr_cost += Calculate(bednet.edge_hr_cost_replace_formula, "封边人力成本").DecimalValue;
                }
                #endregion 计算 封边人力成本 结束

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

                    bednet.fork_mtrl_cost += Calculate(bednet.fork_mtrl_cost_replace_formula, "弹叉材料成本").DecimalValue;
                }
                #endregion 计算 弹叉材料成本 结束

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

                    bednet.fork_hr_cost += Calculate(bednet.fork_hr_cost_replace_formula, "弹叉人力成本").DecimalValue;
                }
                #endregion 计算 弹叉人力成本 结束

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

                    bednet.rsorwa_mtrl_cost += Calculate(bednet.rsorwa_mtrl_cost_replace_formula, "胶条/包角材料成本").DecimalValue;
                }
                #endregion 计算 胶条/包角材料成本 结束

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

                    bednet.rsorwa_hr_cost += Calculate(bednet.rsorwa_hr_cost_replace_formula, "胶条/包角人力成本").DecimalValue;
                }
                #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;

                    bednet.sponge_drilling_hr_cost += Calculate(bednet.sponge_drilling_hr_cost_replace_formula, "海绵打孔人力成本").DecimalValue;
                }
                #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, "上垫层");

                    bednet.felt_mtrl_cost += Calculate(bednet.felt_mtrl_cost_replace_formula, "上垫层物料成本").DecimalValue;
                }
                #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, "下垫层");

                    bednet.felt_mtrl_x_cost += Calculate(bednet.felt_mtrl_x_cost_replace_formula, "下垫层物料成本").DecimalValue;
                }
                #endregion 计算 下垫层物料成本 结束

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

                    bednet.felt_hr_cost += Calculate(bednet.felt_hr_cost_replace_formula, "上垫层人力成本").DecimalValue;
                }
                #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, "下垫层");

                    bednet.felt_hr_x_cost += Calculate(bednet.felt_hr_x_cost_replace_formula, "下垫层人力成本").DecimalValue;
                }
                #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.Substring(0, 2) == "@@";
                    bednet.packet_mtrl_cost_replace_formula = ReplaceWith(bednet.packet_mtrl_cost_replace_formula, "@@", "");

                    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;
                }
                #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.Substring(0, 2) == "@@";
                    bednet.packet_hr_cost_replace_formula = ReplaceWith(bednet.packet_hr_cost_replace_formula, "@@", "");

                    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;
                }
                #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_mtrl_cost);
            //
            AddKeyValue("额外费用", 0);
            AddKeyValue("FOB", 0);

            //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;
        }

        private void CulcalateWeight(u_bednet bednet, List<u_bednetmx> mxlist, List<u_bednetmx_spring> springList)
        {
            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
                    {
                        //多分区
                        foreach (var springItem in springList)
                        {
                            springItem.spring_weight_replace_formula = bednet.spring_weight_formula;
                            CalSpringMtrlCol(bednet, mx, springItem);

                            bednet.spring_weight_qty += Calculate(springItem.spring_mtrl_cost_replace_formula, "钢丝重量").DecimalValue;
                        }
                    }
                }
                #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;
                }
                #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_qty += Calculate(bednet.hard_around_weight_replace_formula, "四周加硬重量").DecimalValue;
                }
                #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;
                }
                #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;
                }
                #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, "上垫层");

                    bednet.felt_weight_qty += Calculate(bednet.felt_weight_formula, "上垫层重量").DecimalValue;
                }
                #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, "下垫层");

                    bednet.felt_weight_qty += Calculate(bednet.felt_weight_formula, "下垫层重量").DecimalValue;
                }

                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;
                }
                #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;
                }
                #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, "填充海绵");

                    bednet.sponge_weight_tc_qty += Calculate(bednet.sponge_weight_tc_replace_formula, "填充海绵重量").DecimalValue;
                }
                #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, "封边");

                    bednet.edge_weight_qty += Calculate(bednet.edge_weight_replace_formula, "封边材料重量").DecimalValue;
                }
                #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;
                }
                #endregion 计算 弹叉材料重量 结束
            }

            // 计算总材料成本 total_mtrl_cost
            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();
        }

        private void InitBedNet(u_bednet bednet)
        {
            var dept = new u_dept() { deptid = bednet.deptid.Value };
            DbSqlHelper.SelectOne(cmd, dept, "pricelistid,profitrate,moneyrate,discount");

            var profirate = new u_factory_profitrate() { deptid = bednet.deptid, bednettypeid_mattresstypeid = bednet.bednettypeid, bednet_or_mattress = 0 };
            DbSqlHelper.SelectOne(cmd, profirate, "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 = profirate.profitrate;
            bednet.dept_profitrate = dept.profitrate;

            bednet.moneyrate = bednet.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 InitReplaceMents(u_bednet bednet)
        {
            replacements.Clear();

            var bednetVarList = new List<u_bednet_var>();
            var 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";
            var 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)");
            var 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);

            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("汇率", bednet.moneyrate);
            AddKeyValue("税率", bednet.taxrate);
            // 公式
            AddFormulaKeyValue("【总成本】", "【总材料成本】+【总人力成本】+ 【额外费用】");
            AddFormulaKeyValue("【不含税出厂价】", "【总成本】*(【工厂利润率】+【外销加点】)");
            AddFormulaKeyValue("【部门不含税价】", "【不含税出厂价】/【部门利润率】*【佣金点数】*【额外点数】+【FOB】");
            AddFormulaKeyValue("【税金】", "(【部门不含税价】*【税率】-1)");
            AddFormulaKeyValue("【部门含税价】", "【部门不含税价】*【税率】");
            AddFormulaKeyValue("【外币价】", "【部门含税价】/【汇率】");

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

            selectStr = @"SELECT varid
	                            ,varkind
	                            ,varcode
	                            ,varname
	                            ,varclass
	                            ,vartype
	                            ,varunit
                                ,formula
                            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", 0, 0, bednetVarList);

            // 添加替换公式变量
            foreach (var netvar in bednetVarList)
            {
                AddFormulaKeyValue(netvar.varname, netvar.formula);
            }
        }
        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);
            }

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

            if (spring.center_diameter > 0)
            {
                AddKeyValue("口袋弹簧心径", spring.center_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);
            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("加硬弹簧单价", price);
                AddKeyValue("口袋弹簧单价", price);
                AddKeyValue("弹簧单价", price);
            }
        }
        /// <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)
        {
            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);

            var spring = new u_spring() { springid = mx.springid };
            DbSqlHelper.SelectOne(cmd, spring, "line_diameter,gram_weight");

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

            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("弹簧单价", price);
            }
        }

        /// <summary>
        /// 代码对照wf_replace_var_dw2
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="mx"></param>
        private void CalSpringMtrlCol2(u_bednet bednet, u_bednetmx mx, string type)
        {
            var spring = new u_spring() { springid = mx.springid };
            DbSqlHelper.SelectOne(cmd, spring, "line_diameter,gram_weight,center_diameter");

            #region 计算 底面无纺布 开始
            //计算 上下无纺布方数 =(B4+C4)*(B4+D4)/10000
            if ("底面无纺布".Equals(type) && mx.fabrics2_mtrlid > 0)
            {
                decimal fabrics = (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)
            {
                decimal fabrics = (mx.bednet_height.Value + spring.center_diameter.Value + 2) * (spring.center_diameter.Value * (decimal)3.14 + 1) / 10000;
                AddKeyValue("入袋无纺布方数", fabrics);

                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);

                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);
                    }
                }
            }
            #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);

                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);
                    }
                }
            }
            #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 void CalSnakeCol(u_bednet bednet,u_spring spring)
        {
            #region 替换蛇线单价  snake_wire_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);
            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("蛇线单价", price);
            }
            #endregion
        }

        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)
        {
            if (!formula_replacements.ContainsKey(key))
            {
                formula_replacements.Add(key, value);
            }
            else if (isReplace)
            {
                formula_replacements[key] = value;
            }
        }
        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 null;
            return Calculate(varname);
        }
        private TData Calculate(string expression,string name = "")
        {
            ConvertToEnglishSymbols(expression);

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

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

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

            // 使用正则表达式匹配输入字符串
            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));
            }

            try
            {
                return LJExprParser.Parse(expression).Result;
            } catch (Exception ex)
            {
                throw new LJCommonException($"计算{name}公式错误!expression: {expression},exception: {ex.Message}");
            }
        }

        private object SqlCalculate(string expression, string name = "")
        {
            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 string value))
                {
                    new_formula_replacements[match.Value] = 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)
            {
                expression = expression.Replace(replacement.Key, Convert.ToString(replacement.Value));
            }

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

        public void GetBedNet(u_bednet bednet)
        {
            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";
            DbSqlHelper.SelectOne(cmd, bednet, outputFields);
        }

        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;
        }

        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)
        {
            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";

            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.bednetid <= 0)
            {
                //新建
                fields += ",bednetid,bednetcode";

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

                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();

                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.bednetmx_partid = bednet.bednetid;
                        spring.bednetmxid = 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 = 0,
                dept_cost = 0,
                foreign_cost = 0
            };
            var fieldsHs = "bednetid_mattressid, typeid, cmpdate, cmpemp, nottax_dept_cost, dept_cost, foreign_cost";
            DbSqlHelper.Insert(cmd, "u_his_price", null, hisprice, fieldsHs);
        }
    }
}
