package quote import ( "zhiyuan/models/quote" "zhiyuan/pkg/db" "zhiyuan/pkg/utils" "zhiyuan/services/form" "zhiyuan/services/structs" ) func CalcBidItemMoney(param form.QuoteOrderParam, bidItem *quote.Item, setting structs.MaterialBidCalcSetting, form form.QuoteCalc, price float64) float64 { windowArea := utils.FloatMul(param.Window, bidItem.CalcParamDecode.WindowHeight, -1) holeArea := utils.FloatMul(param.Hole, bidItem.CalcParamDecode.HoleHeight, -1) wallArea := utils.FloatMul(param.Round, bidItem.CalcParamDecode.WallHeight, -1) switch bidItem.CalcType { case 1: // 地面面积*单价 return utils.FloatMul(param.Area, price, 4) case 2: // 固定数*单价 return utils.FloatMul(bidItem.CalcParamDecode.FixNum, price, 4) case 4: // 墙面面积*单价 return utils.FloatMul(utils.FloatSub(wallArea, holeArea, -1), price, 4) case 6: // 地面面积*损耗系数*单价 return utils.FloatMulSlice([]float64{param.Area, bidItem.CalcParamDecode.LossRate, price}, 4) case 7: // 基础房间*房间单价 money := utils.ToFloat64(bidItem.CalcParamDecode.BaseMoney) if setting.RoomNum > bidItem.CalcParamDecode.RoomNum { money = utils.FloatAdd(money, utils.FloatMul(bidItem.CalcParamDecode.AddRoomMoney, utils.ToFloat64(setting.RoomNum-bidItem.CalcParamDecode.RoomNum), -1), -1) } if setting.ToiletNum > bidItem.CalcParamDecode.ToiletNum { money = utils.FloatAdd(money, utils.FloatMul(bidItem.CalcParamDecode.AddToiletMoney, utils.ToFloat64(setting.ToiletNum-bidItem.CalcParamDecode.ToiletNum), -1), -1) } if setting.KitchenNum > bidItem.CalcParamDecode.KitchenNum { money = utils.FloatAdd(money, utils.FloatMul(bidItem.CalcParamDecode.AddKitchenMoney, utils.ToFloat64(setting.KitchenNum-bidItem.CalcParamDecode.KitchenNum), -1), -1) } if setting.RestaurantNum > bidItem.CalcParamDecode.RestaurantNum { money = utils.FloatAdd(money, utils.FloatMul(bidItem.CalcParamDecode.AddRestaurantMoney, utils.ToFloat64(setting.RestaurantNum-bidItem.CalcParamDecode.RestaurantNum), -1), -1) } return utils.FloatRound(money, 4) case 8: // 全房建筑面积*单价 return utils.FloatMul(param.Area, price, 4) case 9: // (地面面积+墙面面积-窗户面积)*单价 if param.RoomType == 1 { wallArea = utils.FloatAdd(wallArea, utils.FloatMul(1.6, bidItem.CalcParamDecode.WallHeight, -1), -1) } return utils.FloatMul(utils.FloatSubSlice([]float64{utils.FloatAdd(param.Area, wallArea, -1), holeArea, windowArea}, -1), price, 4) case 10: // 门洞*单价 return utils.FloatMul(param.Hole, price, 4) case 11: // 地面周长*单价 return utils.FloatMul(utils.FloatSub(param.Round, param.Hole, -1), price, 4) case 12: // 门洞周长*单价 return utils.FloatMul(utils.FloatAddSlice([]float64{bidItem.CalcParamDecode.HoleHeight, bidItem.CalcParamDecode.HoleHeight, param.Hole}, -1), price, 4) case 13: // 门洞面积*单价 return utils.FloatMulSlice([]float64{bidItem.CalcParamDecode.HoleHeight, param.Hole, price}, 4) case 14: // 墙面面积*损耗系数*单价 return utils.FloatMulSlice([]float64{utils.FloatSub(wallArea, holeArea, -1), bidItem.CalcParamDecode.LossRate, price}, 4) case 15: // 窗台石 return utils.FloatMul(utils.FloatAdd(3, utils.FloatMul(utils.ToFloat64(setting.RoomNum), 1.9, -1), -1), price, 4) case 16: // 窗宽*单价 return utils.FloatMul(param.Window, price, 4) case 17: // (地面面积+客餐厅墙面面积-窗面积)*单价 balconyHoleArea := utils.FloatMul(setting.BalconyHole, bidItem.CalcParamDecode.HoleHeight, -1) KitchenHoleArea := utils.FloatMul(setting.KitchenHole, bidItem.CalcParamDecode.HoleHeight, -1) return utils.FloatMul(utils.FloatSubSlice([]float64{utils.FloatAdd(param.Area, wallArea, -1), holeArea, balconyHoleArea, KitchenHoleArea, windowArea}, -1), price, 4) case 18: // 客餐厅地面周长*单价 return utils.FloatMul(utils.FloatSubSlice([]float64{param.Round, param.Hole, setting.KitchenHole, setting.BalconyHole}, -1), price, 4) case 19: // (客餐厅墙面面积-窗面积)*单价 balconyHoleArea := utils.FloatMul(setting.BalconyHole, bidItem.CalcParamDecode.HoleHeight, -1) KitchenHoleArea := utils.FloatMul(setting.KitchenHole, bidItem.CalcParamDecode.HoleHeight, -1) return utils.FloatMul(utils.FloatSubSlice([]float64{wallArea, holeArea, balconyHoleArea, KitchenHoleArea, windowArea}, -1), price, 4) case 20: // 地面周长*损耗系数*单价 return utils.FloatMulSlice([]float64{utils.FloatSub(param.Round, param.Hole, -1), bidItem.CalcParamDecode.LossRate, price}, 4) case 21: // 客餐厅地面周长*损耗系数*单价 return utils.FloatMulSlice([]float64{utils.FloatSubSlice([]float64{param.Round, param.Hole, setting.KitchenHole, setting.BalconyHole}, -1), bidItem.CalcParamDecode.LossRate, price}, 4) case 24: // (地面周长-固定数)*损耗系数*单价 return utils.FloatMulSlice([]float64{utils.FloatSubSlice([]float64{param.Round, bidItem.CalcParamDecode.FixNum}, -1), bidItem.CalcParamDecode.LossRate, price}, 4) case 25: // (阳台墙面面积-阳台窗户面积)*单价 balconyWallArea := utils.FloatMul(setting.BalconyRound, bidItem.CalcParamDecode.WallHeight, -1) balconyHoleArea := utils.FloatMul(setting.BalconyHole, bidItem.CalcParamDecode.HoleHeight, -1) balconyWindowArea := utils.FloatMul(setting.BalconyWindow, bidItem.CalcParamDecode.WindowHeight, -1) return utils.FloatMul(utils.FloatSubSlice([]float64{balconyWallArea, balconyHoleArea, balconyWindowArea}, -1), price, 4) case 26: // (墙面面积-窗户面积)*单价 if param.RoomType == 1 { wallArea = utils.FloatAdd(wallArea, utils.FloatMul(1.6, bidItem.CalcParamDecode.WallHeight, -1), -1) } return utils.FloatMul(utils.FloatSubSlice([]float64{wallArea, holeArea, windowArea}, -1), price, 4) case 27: // 阳台地面面积*单价 return utils.FloatMul(setting.BalconyArea, price, 4) case 28: // 阳台门洞周长*单价 return utils.FloatMul(utils.FloatAddSlice([]float64{bidItem.CalcParamDecode.HoleHeight, bidItem.CalcParamDecode.HoleHeight, setting.BalconyHole}, -1), price, 4) case 29: // (墙面面积-窗户面积)*损耗系数*单价 if param.RoomType == 1 { wallArea = utils.FloatAdd(wallArea, utils.FloatMul(1.6, bidItem.CalcParamDecode.WallHeight, -1), -1) } return utils.FloatMulSlice([]float64{utils.FloatSubSlice([]float64{wallArea, holeArea, windowArea}, -1), bidItem.CalcParamDecode.LossRate, price}, 4) case 30: // (地面周长+门洞)*单价 return utils.FloatMul(param.Round, price, 4) case 31: // (阳台墙面面积-阳台窗户面积)*损耗系数*单价 balconyWallArea := utils.FloatMul(setting.BalconyRound, bidItem.CalcParamDecode.WallHeight, -1) balconyHoleArea := utils.FloatMul(setting.BalconyHole, bidItem.CalcParamDecode.HoleHeight, -1) balconyWindowArea := utils.FloatMul(setting.BalconyWindow, bidItem.CalcParamDecode.WindowHeight, -1) return utils.FloatMulSlice([]float64{utils.FloatSubSlice([]float64{balconyWallArea, balconyHoleArea, balconyWindowArea}, -1), bidItem.CalcParamDecode.LossRate, price}, 4) default: return 0 } } func Calc(forms form.QuoteCalc) structs.QuoteReturn { var ret structs.QuoteReturn ret.Categorys = make(map[int64]float64) itemList := make([]*quote.Item, 0) db.GetModel(map[string]interface{}{}, &itemList) itemListMap := make(map[int64][]*quote.Item) for _, v := range itemList { if _, ok := itemListMap[v.RoomType]; !ok { itemListMap[v.RoomType] = make([]*quote.Item, 0) } if v.CalcParam != "" { utils.JsonDecode(v.CalcParam).To(&v.CalcParamDecode) } itemListMap[v.RoomType] = append(itemListMap[v.RoomType], v) } calcSetting := structs.MaterialBidCalcSetting{RoomNum: 0, ToiletNum: 0, RestaurantNum: 0, KitchenNum: 0} for _, v := range forms.Param { switch v.RoomType { case 1: calcSetting.RoomNum++ case 2: calcSetting.RestaurantNum++ case 3: calcSetting.KitchenNum++ case 4: calcSetting.ToiletNum++ } if v.RoomType == 3 { calcSetting.KitchenHole = v.Hole } else if v.RoomType == 5 { calcSetting.BalconyArea = v.Area calcSetting.BalconyHole = v.Hole calcSetting.BalconyRound = v.Round calcSetting.BalconyWindow = v.Window } } for _, v := range forms.Param { if v.RoomType == 3 { calcSetting.KitchenHole = v.Hole } else if v.RoomType == 5 { calcSetting.BalconyArea = v.Area calcSetting.BalconyHole = v.Hole calcSetting.BalconyRound = v.Round calcSetting.BalconyWindow = v.Window } } for _, v := range forms.Param { orderReturn := structs.QuoteOrderReturn{RoomType: v.RoomType, RoomName: v.RoomName, Categorys: make(map[int64]float64), Total: 0} itemMap := make(map[int64]form.QuoteOrderItem) for _, i := range v.Items { itemMap[i.ID] = i } items, ok := itemListMap[v.RoomType] if !ok { break } for _, i := range items { price := i.Price if p, ok := itemMap[i.ID]; ok { price = p.Price } total := CalcBidItemMoney(v, i, calcSetting, forms, price) itemReturn := structs.QuoteOrderItemReturn{ID: i.ID, Category: i.Category, Name: i.Name, Price: price, Description: i.Description, Total: total} orderReturn.Items = append(orderReturn.Items, itemReturn) orderReturn.Total += total if _, ok := orderReturn.Categorys[i.Category]; !ok { orderReturn.Categorys[i.Category] = 0 } orderReturn.Categorys[i.Category] += total if _, ok := ret.Categorys[i.Category]; !ok { ret.Categorys[i.Category] = 0 } ret.Categorys[i.Category] += total } ret.Rooms = append(ret.Rooms, orderReturn) ret.Total += orderReturn.Total } return ret }