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