package pkg2024 import ( "errors" "math" "strings" "zhiyuan/models/final" "zhiyuan/pkg/db" "zhiyuan/pkg/utils" "zhiyuan/services/form" "zhiyuan/services/material/bid" "zhiyuan/services/structs" ) type ItemContext struct { Pkg *PkgForm ItemMap map[string]BuildItem //RegionMap map[int][]map[string]Region MatCache map[int64]final.FinalMat MatTypeCache map[int64]final.FinalMatType Space Space SpaceType int SpaceIndex int ItemNumber float64 Item BuildItem Region Region oldRoomData RoomData } func (context *ItemContext) GetSpaceName() string { spaces := map[int]string{ -1: "开工", 0: "卧室", 1: "客餐厅", 2: "厨房", 3: "卫生间", 4: "阳台", } spaceName := spaces[context.SpaceType] if context.SpaceType >= 0 { if context.Pkg.RoomData.Pkg.Layout[context.SpaceType] > 1 { spaceName += db.ToString(context.SpaceIndex + 1) } } return spaceName } type BuildBudgetItem struct { Type int `json:"type"` Name string `json:"name"` Unit string `json:"unit"` Number float64 `json:"number"` Price float64 `json:"price"` Total float64 `json:"total"` Remark string `json:"remark"` Index int `json:"index"` } type BuildBudgetCost struct { Direct float64 `json:"direct"` TransportProportion float64 `json:"transport_proportion"` Transport float64 `json:"transport"` SanitationProportion float64 `json:"sanitation_proportion"` Sanitation float64 `json:"sanitation"` ManageProportion float64 `json:"manage_proportion"` Manage float64 `json:"manage"` AdjustmentNumber float64 `json:"adjustment_number"` AdjustmentPrice float64 `json:"adjustment_price"` Adjustment float64 `json:"adjustment"` DesignNumber float64 `json:"design_number"` DesignPrice float64 `json:"design_price"` Design float64 `json:"design"` Total float64 `json:"total"` } type MaterialItem struct { Material int64 `json:"material"` Name string `json:"name"` Type string `json:"type"` Unit string `json:"unit"` Number float64 `json:"number"` Price float64 `json:"price"` Total float64 `json:"total"` CostNumber float64 `json:"cost_number"` CostTotal float64 `json:"cost_total"` Index int `json:"index"` } type DeductionData map[int][][]int type Contract struct { PkgPrice float64 `json:"pkg_price"` ToiletPrice []float64 `json:"toilet_price"` PkgTotal float64 `json:"pkg_total"` MaterialTotal float64 `json:"material_total"` PersonalBuildTotal float64 `json:"personal_build_total"` PersonalAmount float64 `json:"personal_amount"` PersonalTransportProportion float64 `json:"personal_transport_proportion"` PersonalTransport float64 `json:"personal_transport"` PersonalSanitationProportion float64 `json:"personal_sanitation_proportion"` PersonalSanitation float64 `json:"personal_sanitation"` PersonalManageProportion float64 `json:"personal_manage_proportion"` PersonalManage float64 `json:"personal_manage"` PersonalTotal float64 `json:"personal_total"` DesignPrice float64 `json:"design_price"` ChartPrice float64 `json:"chart_price"` //DesignTotal float64 `json:"design_total"` DirectTotal float64 `json:"direct_total"` DirectCost float64 `json:"direct_cost"` MaterialPurchaseTotal float64 `json:"material_purchase_total"` SpecialProjectTotal float64 `json:"special_project_total"` PurchaseTotal float64 `json:"purchase_total"` Cost float64 `json:"cost"` Taxes float64 `json:"taxes"` CostTotal float64 `json:"cost_total"` MaterialDeductionTotal float64 `json:"material_deduction_total"` BuildDeductionTotal float64 `json:"build_deduction_total"` } type BuildBudget struct { Items map[int][][]BuildBudgetItem `json:"items"` Cost BuildBudgetCost `json:"cost"` ControlAmount map[int]float64 `json:"control_amount"` Materials map[int][][]MaterialItem `json:"materials"` BuildAdditionalItems []PersonalItem `json:"build_additional_items"` MaterialAdditionalItems []PersonalItem `json:"material_additional_items"` BuildDeductionItems []PersonalItem `json:"build_deduction_items"` MaterialDeductionItems []PersonalItem `json:"material_deduction_items"` MaterialPurchaseItems []PersonalItem `json:"material_purchase_items"` BuildSpecialItems []PersonalItem `json:"build_special_items"` PersonalBuildItems []BuildBudgetItem `json:"personal_build_items"` PersonalBuildCost BuildBudgetCost `json:"personal_build_cost"` SpecialProjectItems []BuildBudgetItem `json:"special_project_items"` SpecialProjectTotal float64 `json:"special_project_total"` Contract Contract `json:"contract"` PackageAmount float64 `json:"package_amount"` SubsidyItems []SubsidyItem `json:"subsidy_items"` SubsidyTotal float64 `json:"subsidy_total"` SubsidyCollect float64 `json:"subsidy_collect"` MaterialCost float64 `json:"material_cost"` Profit float64 `json:"profit"` ProfitMargin float64 `json:"profit_margin"` } type BuildAdditionalItem struct { Item string `json:"item"` Number float64 `json:"number"` } type MaterialAdditionalItem struct { Material int64 `json:"material"` Number float64 `json:"number"` Purchase bool `json:"purchase"` } type SpecialProjectItem struct { Name string `json:"name"` Type int `json:"type"` Number float64 `json:"number"` Price float64 `json:"price"` Unit string `json:"unit"` Remark string `json:"remark"` } type AdditionalData struct { Builds []BuildAdditionalItem `json:"builds"` Materials []MaterialAdditionalItem `json:"materials"` Specials []SpecialProjectItem `json:"specials"` } type PersonalItem struct { Material int64 `json:"material"` Type int `json:"type"` Name string `json:"name"` Unit string `json:"unit"` Number float64 `json:"number"` Price float64 `json:"price"` Total float64 `json:"total"` Remark string `json:"remark"` SpaceType int `json:"space_type"` SpaceIndex int `json:"space_index"` Index int `json:"index"` Purchase bool `json:"purchase"` } type SubsidyItem struct { Name string `json:"name"` Unit string `json:"unit"` Number float64 `json:"number"` Price float64 `json:"price"` Total float64 `json:"total"` } func (from *PkgForm) NewContext() *ItemContext { context := new(ItemContext) context.Pkg = from context.ItemMap = make(map[string]BuildItem) for _, item := range BuildItems { context.ItemMap[item.Name] = item } context.MatCache = make(map[int64]final.FinalMat) matIds := make([]int64, 0) //context.RegionMap = make(map[int][]map[string]Region) for spaceType, spaceRegion := range from.RegionData { //context.RegionMap[spaceType] = make([]map[string]Region, 0) for _, regions := range spaceRegion { regionMap := make(map[string]Region) for regionIndex, region := range regions { regionMap[Regions[spaceType][regionIndex].Name] = region matIds = append(matIds, region.Material) } //context.RegionMap[spaceType] = append(context.RegionMap[spaceType], regionMap) } } mats := make([]final.FinalMat, 0) db.GetModel(map[string]interface{}{ "id in": matIds, "deleted_at": 0, }, &mats) for _, mat := range mats { context.MatCache[mat.ID] = mat } if context.MatTypeCache == nil { context.MatTypeCache = make(map[int64]final.FinalMatType) types := make([]final.FinalMatType, 0) db.GetModel(map[string]interface{}{ "deleted_at": 0, }, &types) for _, typ := range types { context.MatTypeCache[typ.ID] = typ } } return context } func (context *ItemContext) GetMat(id int64) *final.FinalMat { if context.MatCache == nil { context.MatCache = make(map[int64]final.FinalMat) } if _, ok := context.MatCache[id]; !ok { var mat final.FinalMat db.GetModel(map[string]interface{}{ "id": id, "deleted_at": 0, }, &mat) if mat.ID != 0 { context.MatCache[id] = mat } } if mat, ok := context.MatCache[id]; ok { return &mat } return nil } func (context *ItemContext) GetMatTopType(id int64) *final.FinalMatType { for { if typ, ok := context.MatTypeCache[id]; ok { if typ.Pid != 0 { id = typ.Pid } else { break } } else { break } } if typ, ok := context.MatTypeCache[id]; ok { return &typ } return nil } func (from *PkgForm) Calc() error { context := from.NewContext() context.oldRoomData = from.RoomData return from.CalcInContext(context) } func (from *PkgForm) CalcInContext(context *ItemContext) error { from.RefreshRegion(context) err := CalcBuildBudget(context) if err != nil { return err } return nil } func CalcBuildBudget(context *ItemContext) error { context.Pkg.BuildBudget = BuildBudget{} context.Pkg.BuildBudget.ControlAmount = make(map[int]float64) context.Pkg.BuildBudget.Items = make(map[int][][]BuildBudgetItem) context.Pkg.BuildBudget.Materials = make(map[int][][]MaterialItem) context.Pkg.BuildBudget.BuildAdditionalItems = make([]PersonalItem, 0) context.Pkg.BuildBudget.MaterialAdditionalItems = make([]PersonalItem, 0) context.Pkg.BuildBudget.BuildDeductionItems = make([]PersonalItem, 0) context.Pkg.BuildBudget.MaterialDeductionItems = make([]PersonalItem, 0) context.Pkg.BuildBudget.MaterialPurchaseItems = make([]PersonalItem, 0) context.Pkg.BuildBudget.BuildSpecialItems = make([]PersonalItem, 0) context.Pkg.BuildBudget.PersonalBuildItems = make([]BuildBudgetItem, 0) for spaceType, items := range PkgItems { var spaces []Space if spaceType < 0 { spaces = []Space{{Area: context.Pkg.RoomData.Pkg.Area}} } else { spaces = context.Pkg.RoomData.Space[spaceType] } context.SpaceType = spaceType if _, ok := context.Pkg.BuildBudget.Items[spaceType]; !ok { context.Pkg.BuildBudget.Items[spaceType] = make([][]BuildBudgetItem, 0) context.Pkg.BuildBudget.Materials[spaceType] = make([][]MaterialItem, 0) } for spaceIndex, space := range spaces { context.Space = space context.SpaceIndex = spaceIndex buildBudgetItems := make([]BuildBudgetItem, 0) materialItems := make([]MaterialItem, 0) for n, io := range items { var regionObject RegionObject if io.Region == "" { context.Region = Region{} } else { index := -1 for i, o := range Regions[spaceType] { if o.Name == io.Region { regionObject = o index = i break } } region, ok := context.Pkg.RegionData[spaceType][spaceIndex][index] if !ok { if spaceType >= 0 { for i, o := range Regions[-1] { if o.Name == io.Region { regionObject = o index = i break } } region, ok = context.Pkg.RegionData[-1][0][index] } if !ok { return errors.New("找不到选材: " + io.Region) } } context.Region = region } name, err := io.GetItem(context) if err != nil { return err } if name == "" { context.Item = BuildItem{} } else { item, ok := context.ItemMap[name] if !ok { return errors.New("找不到项目: " + io.Item) } context.Item = item } number, err := io.GetNumber(context) context.ItemNumber = number if err != nil { return err } if number == 0 { continue } deduction := false for _, d := range context.Pkg.DeductionData[context.SpaceType][context.SpaceIndex] { if d == n { deduction = true break } } price, err := context.Item.GetPrice(context) if err != nil { return err } if price != 0 { total := utils.FloatMul(price, number, 3) if deduction { context.Pkg.BuildBudget.BuildDeductionItems = append(context.Pkg.BuildBudget.BuildDeductionItems, PersonalItem{ Name: context.GetSpaceName() + " " + context.Item.Name, Unit: context.Item.Unit, Number: number, Price: price, Total: total, Remark: context.Item.Remark, SpaceType: spaceType, SpaceIndex: spaceIndex, Index: n, }) } else { buildBudgetItems = append(buildBudgetItems, BuildBudgetItem{ Type: context.Item.Type, Name: context.Item.Name, Unit: context.Item.Unit, Number: number, Price: price, Total: total, Remark: context.Item.Remark, Index: n, }) context.Pkg.BuildBudget.Cost.Direct = utils.FloatAdd(context.Pkg.BuildBudget.Cost.Direct, total, 3) diffNumber, err := io.GetDiffNumber(context) if err != nil { return err } if diffNumber != 0 { diffPrice, err := io.GetDiffPrice(context) if err != nil { return err } if diffPrice != 0 { diffTotal := math.Round(utils.FloatMul(diffPrice, diffNumber, 3)) context.Pkg.BuildBudget.BuildAdditionalItems = append(context.Pkg.BuildBudget.BuildAdditionalItems, PersonalItem{ Type: context.Item.Type, Name: context.Item.Name + " 升级补差", Unit: context.Item.Unit, Number: diffNumber, Price: diffPrice, Total: diffTotal, Index: -1, }) } } } } if !deduction { for _, split := range context.Item.Splits { total := float64(0) if split.TotalCalc != nil { total, err = split.TotalCalc(context, number) if err != nil { return err } } else { price := split.Price if split.PriceCalc != nil { price, err = split.PriceCalc(context) if err != nil { return err } } total = utils.FloatMul(price, number, 3) } context.Pkg.BuildBudget.ControlAmount[split.Type] = utils.FloatAdd(context.Pkg.BuildBudget.ControlAmount[split.Type], total, 3) } } if context.Region.Material != 0 || regionObject.MaterialPriceCalc != nil { typeName := io.Region if io.MaterialType != "" { typeName = io.MaterialType } if deduction { pkgNumber, err := io.GetPkgNumber(context) if err != nil { return err } if pkgNumber != 0 { deductionPrice, err := io.GetDeductionPrice(context) if err != nil { return err } //if deductionPrice != 0 { unit, err := io.GetUnit(context) if err != nil { return err } total := math.Round(utils.FloatMul(deductionPrice, pkgNumber, 3)) context.Pkg.BuildBudget.MaterialDeductionItems = append(context.Pkg.BuildBudget.MaterialDeductionItems, PersonalItem{ Name: context.GetSpaceName() + " " + typeName, Unit: unit, Number: pkgNumber, Price: deductionPrice, Total: total, SpaceType: spaceType, SpaceIndex: spaceIndex, Index: n, }) //} } } else { var mat *final.FinalMat if context.Region.Material != 0 { mat = context.GetMat(context.Region.Material) if mat == nil { return errors.New("找不到材料: " + db.ToString(context.Region.Material)) } } materialPrice := float64(0) if mat == nil && regionObject.MaterialPriceCalc != nil { price, err := regionObject.MaterialPriceCalc(context) if err != nil { return err } materialPrice = price } materialNumber, err := io.GetMaterialNumber(context) if err != nil { return err } if materialNumber == 0 { continue } { controlPrice := materialPrice if mat != nil { controlPrice = mat.ControlPrices() } upgradePrice, err := io.GetUpgradePrice(context, controlPrice) if err != nil { return err } if upgradePrice != 0 { upgradeNumber, err := io.GetUpgradeNumber(context) if err != nil { return err } if upgradeNumber != 0 { matUnit := regionObject.Unit matName := "" if mat != nil { typ := context.GetMatTopType(mat.TypeId) if typ.ID == 2 { upgradeNumber = utils.FloatMul(upgradeNumber, 1.1, 2) } unit, err := io.GetMatUnit(context, mat) if err != nil { return err } matUnit = unit matName = "(" + mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color + ")" } upgradeTotal := math.Round(utils.FloatMul(upgradePrice, upgradeNumber, 3)) context.Pkg.BuildBudget.MaterialPurchaseItems = append(context.Pkg.BuildBudget.MaterialPurchaseItems, PersonalItem{ Material: context.Region.Material, Name: "升级 " + context.GetSpaceName() + " " + typeName + matName, Unit: matUnit, Number: upgradeNumber, Price: upgradePrice, Total: upgradeTotal, Index: -1, }) } } } { salesPrice := materialPrice if mat != nil { salesPrice = mat.SalesPrices() } matPrice, err := io.GetMatSalesPrice(context, salesPrice) if err != nil { return err } if matPrice != 0 { addNumber, err := io.GetAdditionalNumber(context) if err != nil { return err } if addNumber != 0 { matUnit := regionObject.Unit matName := "" if mat != nil { unit, err := io.GetMatUnit(context, mat) if err != nil { return err } matUnit = unit matName = "(" + mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color + ")" } addTotal := math.Round(utils.FloatMul(matPrice, addNumber, 3)) context.Pkg.BuildBudget.MaterialAdditionalItems = append(context.Pkg.BuildBudget.MaterialAdditionalItems, PersonalItem{ Material: context.Region.Material, Name: context.GetSpaceName() + " " + typeName + matName, Unit: matUnit, Number: addNumber, Price: matPrice, Total: addTotal, Index: -1, }) } } } if mat != nil { typ, ok := context.MatTypeCache[mat.TypeId] if !ok { return errors.New("找不到材料类型: " + db.ToString(mat.TypeId)) } total := utils.FloatMul(mat.Price, materialNumber, 3) costMaterialNumber, err := io.GetCostMaterialNumber(context) if err != nil { return err } costTotal := utils.FloatMul(mat.Price, costMaterialNumber, 3) materialItems = append(materialItems, MaterialItem{ Material: context.Region.Material, Name: mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color, Type: typeName, Unit: typ.Unit, Number: materialNumber, Price: mat.Price, Total: total, CostNumber: costMaterialNumber, CostTotal: costTotal, Index: n, }) } if io.AdditionalMaterialCalc != nil { items, err := io.AdditionalMaterialCalc(context) if err != nil { return err } materialItems = append(materialItems, items...) } if io.MaterialAdditionalItemCalc != nil { items, err := io.MaterialAdditionalItemCalc(context) if err != nil { return err } context.Pkg.BuildBudget.MaterialAdditionalItems = append(context.Pkg.BuildBudget.MaterialAdditionalItems, items...) } } } } context.Pkg.BuildBudget.Items[spaceType] = append(context.Pkg.BuildBudget.Items[spaceType], buildBudgetItems) context.Pkg.BuildBudget.Materials[spaceType] = append(context.Pkg.BuildBudget.Materials[spaceType], materialItems) } } context.Space = Space{} context.SpaceType = 0 context.SpaceIndex = 0 context.Item = BuildItem{} context.ItemNumber = 0 context.Region = Region{} context.Pkg.BuildBudget.Cost.TransportProportion = 0.025 context.Pkg.BuildBudget.Cost.SanitationProportion = 0.025 context.Pkg.BuildBudget.Cost.ManageProportion = 0.1 context.Pkg.BuildBudget.Cost.AdjustmentNumber = context.Pkg.RoomData.Pkg.Area context.Pkg.BuildBudget.Cost.AdjustmentPrice = 10 context.Pkg.BuildBudget.Cost.DesignNumber = context.Pkg.RoomData.Pkg.Area context.Pkg.BuildBudget.Cost.DesignPrice = 15 context.Pkg.BuildBudget.Cost.Transport = utils.FloatMul(context.Pkg.BuildBudget.Cost.Direct, context.Pkg.BuildBudget.Cost.TransportProportion, 3) context.Pkg.BuildBudget.Cost.Sanitation = utils.FloatMul(context.Pkg.BuildBudget.Cost.Direct, context.Pkg.BuildBudget.Cost.SanitationProportion, 3) context.Pkg.BuildBudget.Cost.Manage = utils.FloatMul(utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.Cost.Direct, context.Pkg.BuildBudget.Cost.Transport, context.Pkg.BuildBudget.Cost.Sanitation}, 3), context.Pkg.BuildBudget.Cost.ManageProportion, 3) context.Pkg.BuildBudget.Cost.Adjustment = utils.FloatMul(context.Pkg.BuildBudget.Cost.AdjustmentNumber, context.Pkg.BuildBudget.Cost.AdjustmentPrice, 3) context.Pkg.BuildBudget.Cost.Design = utils.FloatMul(context.Pkg.BuildBudget.Cost.DesignNumber, context.Pkg.BuildBudget.Cost.DesignPrice, 3) context.Pkg.BuildBudget.Cost.Total = utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.Cost.Direct, context.Pkg.BuildBudget.Cost.Transport, context.Pkg.BuildBudget.Cost.Sanitation, context.Pkg.BuildBudget.Cost.Manage, context.Pkg.BuildBudget.Cost.Adjustment, context.Pkg.BuildBudget.Cost.Design}, 3) for _, item := range SubsidyItems { price, err := item.GetPrice(context) if err != nil { return err } if price == 0 { continue } number, err := item.GetNumber(context) if err != nil { return err } if number == 0 { continue } total := utils.FloatMul(price, number, 3) context.Pkg.BuildBudget.SubsidyItems = append(context.Pkg.BuildBudget.SubsidyItems, SubsidyItem{ Name: item.Name, Unit: item.Unit, Number: number, Price: price, Total: total, }) context.Pkg.BuildBudget.SubsidyTotal = utils.FloatAdd(context.Pkg.BuildBudget.SubsidyTotal, total, -1) } for i, build := range context.Pkg.AdditionalData.Builds { item, ok := context.ItemMap[build.Item] if !ok { return errors.New("找不到项目: " + build.Item) } context.Item = item context.ItemNumber = build.Number price, err := item.GetPrice(context) if err != nil { return err } total := math.Round(utils.FloatMul(price, build.Number, 3)) context.Pkg.BuildBudget.BuildAdditionalItems = append(context.Pkg.BuildBudget.BuildAdditionalItems, PersonalItem{ Type: context.Item.Type, Name: context.Item.Name, Unit: context.Item.Unit, Number: build.Number, Price: price, Total: total, Remark: context.Item.Remark, Index: i, }) specialProject, err := item.GetSpecialProject(context) if err != nil { return err } if specialProject { context.Pkg.BuildBudget.SpecialProjectItems = append(context.Pkg.BuildBudget.SpecialProjectItems, BuildBudgetItem{ Type: context.Item.Type, Name: context.Item.Name, Unit: context.Item.Unit, Number: build.Number, Price: price, Total: total, Remark: context.Item.Remark, }) context.Pkg.BuildBudget.SpecialProjectTotal = utils.FloatAdd(context.Pkg.BuildBudget.SpecialProjectTotal, total, 3) } else { context.Pkg.BuildBudget.PersonalBuildItems = append(context.Pkg.BuildBudget.PersonalBuildItems, BuildBudgetItem{ Type: context.Item.Type, Name: context.Item.Name, Unit: context.Item.Unit, Number: build.Number, Price: price, Total: total, Remark: context.Item.Remark, }) context.Pkg.BuildBudget.PersonalBuildCost.Direct = utils.FloatAdd(context.Pkg.BuildBudget.PersonalBuildCost.Direct, total, 3) } for _, split := range context.Item.Splits { total := float64(0) if split.TotalCalc != nil { total, err = split.TotalCalc(context, build.Number) if err != nil { return err } } else { price := split.Price if split.PriceCalc != nil { price, err = split.PriceCalc(context) if err != nil { return err } } total = utils.FloatMul(price, build.Number, 3) } context.Pkg.BuildBudget.ControlAmount[split.Type] = utils.FloatAdd(context.Pkg.BuildBudget.ControlAmount[split.Type], total, 3) } } context.Item = BuildItem{} context.ItemNumber = 0 context.Pkg.BuildBudget.SubsidyCollect = utils.FloatAdd(context.Pkg.BuildBudget.SubsidyTotal, context.Pkg.BuildBudget.SpecialProjectTotal, -1) for i, material := range context.Pkg.AdditionalData.Materials { mat := context.GetMat(material.Material) if mat == nil { return errors.New("找不到材料: " + db.ToString(material.Material)) } typ, ok := context.MatTypeCache[mat.TypeId] if !ok { return errors.New("找不到材料类型: " + db.ToString(mat.TypeId)) } if material.Purchase { price := mat.PurchasePrices() total := math.Round(utils.FloatMul(price, material.Number, 3)) context.Pkg.BuildBudget.MaterialPurchaseItems = append(context.Pkg.BuildBudget.MaterialPurchaseItems, PersonalItem{ Material: material.Material, Name: mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color, Unit: typ.Unit, Number: material.Number, Price: price, Total: total, Index: i, Purchase: material.Purchase, }) } else { price := mat.SalesPrices() total := math.Round(utils.FloatMul(price, material.Number, 3)) context.Pkg.BuildBudget.MaterialAdditionalItems = append(context.Pkg.BuildBudget.MaterialAdditionalItems, PersonalItem{ Material: material.Material, Name: mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color, Unit: typ.Unit, Number: material.Number, Price: price, Total: total, Index: i, Purchase: material.Purchase, }) } total := utils.FloatMul(mat.Price, material.Number, 3) context.Pkg.BuildBudget.Materials[-1][0] = append(context.Pkg.BuildBudget.Materials[-1][0], MaterialItem{ Material: material.Material, Name: mat.Brand + " " + mat.Series + " " + mat.Model + " " + mat.Specs + " " + mat.Color, Type: "个性化", Unit: typ.Unit, Number: material.Number, Price: mat.Price, Total: total, Index: -1, }) } for i, special := range context.Pkg.AdditionalData.Specials { total := math.Round(utils.FloatMul(special.Price, special.Number, 3)) context.Pkg.BuildBudget.BuildSpecialItems = append(context.Pkg.BuildBudget.BuildSpecialItems, PersonalItem{ Type: special.Type, Name: special.Name, Unit: special.Unit, Number: special.Number, Price: special.Price, Total: total, Remark: special.Remark, Index: i, }) context.Pkg.BuildBudget.SpecialProjectItems = append(context.Pkg.BuildBudget.SpecialProjectItems, BuildBudgetItem{ Type: special.Type, Name: special.Name, Unit: special.Unit, Number: special.Number, Price: special.Price, Total: total, Remark: special.Remark, }) context.Pkg.BuildBudget.SpecialProjectTotal = utils.FloatAdd(context.Pkg.BuildBudget.SpecialProjectTotal, total, 3) } for _, AdditionalMaterialFunc := range AdditionalMaterials { if AdditionalMaterialFunc != nil { items, err := AdditionalMaterialFunc(context) if err != nil { return err } if items != nil { context.Pkg.BuildBudget.Materials[-1][0] = append(context.Pkg.BuildBudget.Materials[-1][0], items...) } } } for _, MaterialAdditionalItemFunc := range MaterialAdditionalItems { if MaterialAdditionalItemFunc != nil { items, err := MaterialAdditionalItemFunc(context) if err != nil { return err } context.Pkg.BuildBudget.MaterialAdditionalItems = append(context.Pkg.BuildBudget.MaterialAdditionalItems, items...) } } context.Pkg.BuildBudget.PersonalBuildCost.TransportProportion = 0.025 context.Pkg.BuildBudget.PersonalBuildCost.SanitationProportion = 0.025 context.Pkg.BuildBudget.PersonalBuildCost.ManageProportion = 0.1 context.Pkg.BuildBudget.PersonalBuildCost.AdjustmentNumber = context.Pkg.RoomData.Pkg.Area context.Pkg.BuildBudget.PersonalBuildCost.AdjustmentPrice = 0 context.Pkg.BuildBudget.PersonalBuildCost.DesignNumber = context.Pkg.RoomData.Pkg.Area context.Pkg.BuildBudget.PersonalBuildCost.DesignPrice = 0 context.Pkg.BuildBudget.PersonalBuildCost.Transport = utils.FloatMul(context.Pkg.BuildBudget.PersonalBuildCost.Direct, context.Pkg.BuildBudget.PersonalBuildCost.TransportProportion, 3) context.Pkg.BuildBudget.PersonalBuildCost.Sanitation = utils.FloatMul(context.Pkg.BuildBudget.PersonalBuildCost.Direct, context.Pkg.BuildBudget.PersonalBuildCost.SanitationProportion, 3) context.Pkg.BuildBudget.PersonalBuildCost.Manage = utils.FloatMul(utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.PersonalBuildCost.Direct, context.Pkg.BuildBudget.PersonalBuildCost.Transport, context.Pkg.BuildBudget.PersonalBuildCost.Sanitation}, 3), context.Pkg.BuildBudget.PersonalBuildCost.ManageProportion, 3) context.Pkg.BuildBudget.PersonalBuildCost.Total = utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.PersonalBuildCost.Direct, context.Pkg.BuildBudget.PersonalBuildCost.Transport, context.Pkg.BuildBudget.PersonalBuildCost.Sanitation, context.Pkg.BuildBudget.PersonalBuildCost.Manage, context.Pkg.BuildBudget.PersonalBuildCost.Adjustment, context.Pkg.BuildBudget.PersonalBuildCost.Design}, 3) pkgs := []int{51, 52, 53, 50} forms := form.MaterialBidDetailCalc{ Area: context.Pkg.RoomData.Pkg.Area, FloorNum: 1, IsElevator: 1, HouseStyle: make([]structs.HouseStyle, 0), Param: make([]structs.MaterialBidOrderParam, 0), PkgID: pkgs[context.Pkg.RoomData.Pkg.Type], } for n, layout := range context.Pkg.RoomData.Pkg.Layout { num := layout if n == 3 { num = 1 } forms.HouseStyle = append(forms.HouseStyle, structs.HouseStyle{ Type: n + 1, Num: num, }) } spaceNames := map[int]string{ 0: "卧室", 1: "客餐厅", 2: "厨房", 3: "卫生间", 4: "阳台", } for typ, spaces := range context.Pkg.RoomData.Space { //if typ == 3 { // spaces = []Space{spaces[0]} //} for n, space := range spaces { forms.Param = append(forms.Param, structs.MaterialBidOrderParam{ Area: space.Area, Round: space.Perimeter, RoomName: spaceNames[typ] + db.ToString(n+1), RoomType: typ + 1, }) } } res, err := bid.Calc(forms) if err != nil { return err } context.Pkg.BuildBudget.Contract.PkgPrice = math.Round(res.TotalPrice) context.Pkg.BuildBudget.Contract.PkgTotal = math.Round(res.TotalPrice) context.Pkg.BuildBudget.Contract.ToiletPrice = make([]float64, 0) /*for n, space := range context.Pkg.RoomData.Space[3] { if n == 0 { continue } form1 := form.MaterialBidDetailCalc1{ PkgID: pkgs[context.Pkg.RoomData.Pkg.Type], Area: space.Area, Round: space.Perimeter, } res, err := bid.CalcToilet(form1) if err != nil { return err } context.Pkg.BuildBudget.Contract.ToiletPrice = append(context.Pkg.BuildBudget.Contract.ToiletPrice, res.TotalPrice) context.Pkg.BuildBudget.Contract.PkgTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.PkgTotal, res.TotalPrice, -1) }*/ for _, material := range context.Pkg.BuildBudget.MaterialAdditionalItems { context.Pkg.BuildBudget.Contract.MaterialTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.MaterialTotal, material.Total, -1) } for _, item := range context.Pkg.BuildBudget.BuildAdditionalItems { context.Pkg.BuildBudget.Contract.PersonalBuildTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.PersonalBuildTotal, item.Total, -1) } //context.Pkg.BuildBudget.Contract.PersonalBuildTotal = context.Pkg.BuildBudget.PersonalBuildCost.Direct context.Pkg.BuildBudget.Contract.PersonalAmount = utils.FloatAdd(context.Pkg.BuildBudget.Contract.MaterialTotal, context.Pkg.BuildBudget.Contract.PersonalBuildTotal, -1) context.Pkg.BuildBudget.Contract.PersonalTransportProportion = 0.025 context.Pkg.BuildBudget.Contract.PersonalSanitationProportion = 0.025 context.Pkg.BuildBudget.Contract.PersonalManageProportion = 0.1 context.Pkg.BuildBudget.Contract.PersonalTransport = math.Round(utils.FloatMul(context.Pkg.BuildBudget.Contract.PersonalAmount, context.Pkg.BuildBudget.Contract.PersonalTransportProportion, 3)) context.Pkg.BuildBudget.Contract.PersonalSanitation = math.Round(utils.FloatMul(context.Pkg.BuildBudget.Contract.PersonalAmount, context.Pkg.BuildBudget.Contract.PersonalSanitationProportion, 3)) context.Pkg.BuildBudget.Contract.PersonalManage = math.Round(utils.FloatMul(utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.Contract.PersonalAmount, context.Pkg.BuildBudget.Contract.PersonalTransport, context.Pkg.BuildBudget.Contract.PersonalSanitation}, 3), context.Pkg.BuildBudget.Contract.PersonalManageProportion, 3)) context.Pkg.BuildBudget.Contract.PersonalTotal = math.Round(utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.Contract.PersonalAmount, context.Pkg.BuildBudget.Contract.PersonalTransport, context.Pkg.BuildBudget.Contract.PersonalSanitation, context.Pkg.BuildBudget.Contract.PersonalManage}, 3)) context.Pkg.BuildBudget.Contract.DesignPrice = math.Round(utils.FloatMul(context.Pkg.ContractData.Design, context.Pkg.RoomData.Pkg.Area, -1)) context.Pkg.BuildBudget.Contract.ChartPrice = math.Round(utils.FloatMul(context.Pkg.ContractData.Chart, context.Pkg.RoomData.Pkg.Area, -1)) //context.Pkg.BuildBudget.Contract.DesignTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.DesignPrice, context.Pkg.BuildBudget.Contract.ChartPrice, -1) context.Pkg.BuildBudget.Contract.DirectTotal = math.Round(utils.FloatAddSlice([]float64{context.Pkg.BuildBudget.Contract.PkgTotal, context.Pkg.BuildBudget.Contract.PersonalTotal, context.Pkg.BuildBudget.Contract.ChartPrice, context.Pkg.BuildBudget.Contract.DesignPrice}, -1)) context.Pkg.BuildBudget.Contract.DirectCost = math.Round(utils.FloatMul(context.Pkg.BuildBudget.Contract.DirectTotal, context.Pkg.ContractData.Discount, -1)) for _, material := range context.Pkg.BuildBudget.MaterialPurchaseItems { context.Pkg.BuildBudget.Contract.MaterialPurchaseTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.MaterialPurchaseTotal, material.Total, -1) } for _, item := range context.Pkg.BuildBudget.BuildSpecialItems { context.Pkg.BuildBudget.Contract.SpecialProjectTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.SpecialProjectTotal, item.Total, -1) } context.Pkg.BuildBudget.Contract.PurchaseTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.MaterialPurchaseTotal, context.Pkg.BuildBudget.Contract.SpecialProjectTotal, -1) for _, material := range context.Pkg.BuildBudget.MaterialDeductionItems { context.Pkg.BuildBudget.Contract.MaterialDeductionTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.MaterialDeductionTotal, material.Total, -1) } for _, material := range context.Pkg.BuildBudget.BuildDeductionItems { context.Pkg.BuildBudget.Contract.BuildDeductionTotal = utils.FloatAdd(context.Pkg.BuildBudget.Contract.BuildDeductionTotal, material.Total, -1) } context.Pkg.BuildBudget.PackageAmount = utils.FloatMulSlice([]float64{utils.FloatAdd(context.Pkg.BuildBudget.Cost.Total, context.Pkg.BuildBudget.PersonalBuildCost.Total, -1), 0.9, 0.63}, -1) context.Pkg.BuildBudget.ControlAmount[沙石材料] = utils.FloatAdd(context.Pkg.BuildBudget.ControlAmount[沙石材料], utils.FloatMul(context.Pkg.BuildBudget.PackageAmount, 0.12, -1), 3) tzArea := float64(0) for _, itemss := range context.Pkg.BuildBudget.Items { for _, items := range itemss { for _, item := range items { if strings.Contains(item.Name, "贴砖") { tzArea = utils.FloatAdd(tzArea, item.Number, -1) } } } } context.Pkg.BuildBudget.ControlAmount[开工形象] = 630 tzArea = utils.FloatSub(tzArea, 50, -1) for tzArea > 0 { context.Pkg.BuildBudget.ControlAmount[开工形象] = utils.FloatAdd(context.Pkg.BuildBudget.ControlAmount[开工形象], 160, -1) tzArea = utils.FloatSub(tzArea, 50, -1) } for _, item := range context.Pkg.BuildBudget.BuildSpecialItems { context.Pkg.BuildBudget.ControlAmount[item.Type] = utils.FloatAdd(context.Pkg.BuildBudget.ControlAmount[item.Type], item.Total, -1) } context.Pkg.BuildBudget.Contract.Cost = math.Round(utils.FloatAdd(context.Pkg.BuildBudget.Contract.DirectCost, context.Pkg.BuildBudget.Contract.PurchaseTotal, -1)) if context.Pkg.ContractData.Taxes { context.Pkg.BuildBudget.Contract.Taxes = math.Round(utils.FloatMul(context.Pkg.BuildBudget.Contract.Cost, 0.036, -1)) } context.Pkg.BuildBudget.Contract.CostTotal = math.Round(utils.FloatAdd(context.Pkg.BuildBudget.Contract.Cost, context.Pkg.BuildBudget.Contract.Taxes, -1)) for _, materialss := range context.Pkg.BuildBudget.Materials { for _, materials := range materialss { for _, material := range materials { context.Pkg.BuildBudget.MaterialCost = utils.FloatAdd(context.Pkg.BuildBudget.MaterialCost, material.CostTotal, -1) } } } context.Pkg.BuildBudget.MaterialCost = utils.FloatAdd(context.Pkg.BuildBudget.MaterialCost, context.Pkg.BuildBudget.ControlAmount[开关面板], -1) context.Pkg.BuildBudget.Profit = utils.FloatSubSlice([]float64{context.Pkg.BuildBudget.Contract.Cost, context.Pkg.BuildBudget.Contract.MaterialDeductionTotal, context.Pkg.BuildBudget.Contract.BuildDeductionTotal, context.Pkg.BuildBudget.PackageAmount, context.Pkg.BuildBudget.SubsidyCollect, context.Pkg.BuildBudget.MaterialCost, 1500}, -1) context.Pkg.BuildBudget.ProfitMargin = utils.FloatDiv(context.Pkg.BuildBudget.Profit, context.Pkg.BuildBudget.Contract.CostTotal, -1) return nil }