package domain import ( "time" "github.com/shopspring/decimal" ) const ( OrderReal = iota + 1 //实发订单 OrderIntention //意向订单 OrderTypeBestShop //来自小程序海鲜干货的订单 ) func GetOrderBaseTypeName(orderType int) string { var name string switch orderType { case OrderReal: name = "自建订单" case OrderTypeBestShop: name = "小程序订单" case OrderIntention: name = "意向订单" } return name } const ( OrderDisableNot = iota //订单未关闭 OrderDisableYes //订单已关闭 ) //Buyer 买家 type Buyer struct { //买家姓名 BuyerName string `json:"buyerName"` //联系方式 ContactInfo string `json:"contactInfo"` //收获地址 ShippingAddress string `json:"shippingAddress"` //买家备注 Remark string `json:"remark"` } type OrderCompute struct { //合伙人应收分红 PlanPartnerBonus float64 `json:"planPartnerBonus"` //调整后的合伙人应收分红 (初始值=-1); //业务判定时0是有效值, //所以用空串表示无值,转换到数据库中为负值 UsePartnerBonus float64 `json:"usePartnerBonus"` //合伙人已收分红 PartnerBonusHas float64 `json:"partnerBonusHas"` //合伙人未收分红 PartnerBonusNot float64 `json:"partnerBonusNot"` //合伙人分红支出 PartnerBonusExpense float64 `json:"partnerBonusExpense"` //业务员抽成 SalesmanBonus float64 `json:"salesmanBonus"` //预计的订单内货品总数 PlanOrderCount int `json:"planOrderCount"` //预计的订单的总金额 PlanOrderAmount float64 `json:"planOrderAmount"` //按需使用的订单内货品总数 (初始值=-1) //业务判定时0是有效值, //所以用空串表示无值,转换到数据库中为负值 UseOrderCount int `json:"useOrderCount"` //按需使用的订单内货总金额 (初始值=-1) //业务判定时0是有效值, //所以用空串表示无值,转换到数据库中为负值 UseOrderAmount float64 `json:"useOrderAmount"` } type OrderBaseRemark struct { RemarkBonus string `json:"remarkBonus"` } //OrderBase 订单基础 type OrderBase struct { //表id Id int64 `json:"id"` //订单类型 OrderType int `json:"orderType"` //订单编号 OrderCode string `json:"orderCode"` //交货编号 DeliveryCode string `json:"deliveryCode"` //买家 Buyer Buyer `json:"buyer"` //订单区域信息 RegionInfo RegionInfo `json:"regionInfo"` //订单对应的合伙人 PartnerId int64 `json:"partnerId"` PartnerInfo Partner `json:"partnerInfo"` //业务员抽成比例 SalesmanBonusPercent float64 `json:"salesmanBonusPercent"` //订单的创建时间 CreateTime time.Time `json:"createTime"` //发货时间 DeliveryTime time.Time `json:"deliveryTime"` //更新时间 UpdateTime time.Time `json:"updateTime"` //货品 Goods []OrderGood `json:"goods"` //核算订单相关数据 OrderCompute OrderCompute `json:"orderCompute"` //是否关闭订单 IsDisable int `json:"isDisable"` //分红支付状态 BonusStatus int `json:"bonusStatus"` //公司 CompanyId int64 `json:"companyId"` //数据来源 DataFrom OrderDataFrom `json:"dataFrom"` //备注 Remark OrderBaseRemark `json:"remark"` PartnerCategory PartnerCategory `json:"partnerCategory"` } //GetCurrentPartnerBonus 获取当前合伙人应收分红 func (order *OrderBase) GetCurrentPartnerBonus() float64 { if order.OrderCompute.UsePartnerBonus >= 0 { return order.OrderCompute.UsePartnerBonus } return order.OrderCompute.PlanPartnerBonus } //GetCurrentOrderCount 获取当前订单商品总数 func (order *OrderBase) GetCurrentOrderCount() int { if order.OrderCompute.UseOrderCount >= 0 { return order.OrderCompute.UseOrderCount } return order.OrderCompute.PlanOrderCount } // GetCurrentOrderAmount 获取当前订单的总额 func (order *OrderBase) GetCurrentOrderAmount() float64 { if order.OrderCompute.UseOrderAmount >= 0 { return order.OrderCompute.UseOrderAmount } return order.OrderCompute.PlanOrderAmount } //Update 更新订单数据 //orderData 订单数据 //goodsMap 货品的数据,以货品的id做键,map[id]map[string]interface{} func (order *OrderBase) Update(orderData map[string]interface{}, goodsMap map[int64]map[string]interface{}) error { if v, ok := orderData["OrderCode"]; ok { order.OrderCode = v.(string) } if v, ok := orderData["DeliveryCode"]; ok { order.DeliveryCode = v.(string) } if v, ok := orderData["Buyer"]; ok { order.Buyer = v.(Buyer) } if v, ok := orderData["SalesmanBonusPercent"]; ok { order.SalesmanBonusPercent = v.(float64) } if v, ok := orderData["DeliveryTime"]; ok { order.DeliveryTime = v.(time.Time) } if v, ok := orderData["IsDisable"]; ok { order.IsDisable = v.(int) } for i := range order.Goods { goodId := order.Goods[i].Id if _, ok := goodsMap[goodId]; !ok { continue } if err := order.Goods[i].Update(goodsMap[goodId]); err != nil { return err } } err := order.Compute() return err } func (order *OrderBase) AddGoods(goods []OrderGood) { order.Goods = append(order.Goods, goods...) order.Compute() } func (order *OrderBase) ModifyGoodNumber(goodid int64, number int64) { for i := range order.Goods { if order.Goods[i].Id != goodid { continue } // thisGood := order.Goods[i] } order.Compute() } //Compute 数据汇总核算 func (order *OrderBase) Compute() error { planPartnerBonus := decimal.NewFromFloat(0) planOrderAmount := decimal.NewFromFloat(0) var ( planOrderCount int = 0 useOrderCount int = 0 HasUseOrderCount bool = false ) usePartnerBonus := decimal.NewFromFloat(0) var hasUsePartnerBonus bool = false useOrderAmount := decimal.NewFromFloat(0) var hasUseOrderAmount bool = false partnerBonusHas := decimal.NewFromFloat(0) partnerBonusNot := decimal.NewFromFloat(0) partnerBonusExpense := decimal.NewFromFloat(0) //初始订单的支付状态 order.BonusStatus = OrderGoodWaitPay //统计所以货品的值 for i := range order.Goods { if order.Goods[i].BonusStatus == OrderGoodHasPay { //确定订单的支付状态 order.BonusStatus = OrderGoodHasPay } planPartnerBonus = planPartnerBonus.Add(decimal.NewFromFloat(order.Goods[i].GoodCompute.PlanPartnerBonus)) planOrderAmount = planOrderAmount.Add(decimal.NewFromFloat(order.Goods[i].GoodCompute.PlanAmount)) planOrderCount += order.Goods[i].PlanGoodNumber goodUseAmount := decimal.NewFromFloat(order.Goods[i].GoodCompute.UseAmount) if goodUseAmount.GreaterThanOrEqual(decimal.NewFromFloat(0)) { //调整值非负值得情况 hasUseOrderAmount = true useOrderAmount = useOrderAmount.Add(goodUseAmount) } else { useOrderAmount = useOrderAmount.Add(decimal.NewFromFloat(order.Goods[i].GoodCompute.PlanAmount)) } goodUsePartnerBonus := decimal.NewFromFloat(order.Goods[i].GoodCompute.UsePartnerBonus) if goodUsePartnerBonus.GreaterThanOrEqual(decimal.NewFromFloat(0)) { hasUsePartnerBonus = true usePartnerBonus = usePartnerBonus.Add(goodUsePartnerBonus) } else { usePartnerBonus = usePartnerBonus.Add(decimal.NewFromFloat(order.Goods[i].GoodCompute.PlanPartnerBonus)) } if order.Goods[i].UseGoodNumber >= 0 { HasUseOrderCount = true useOrderCount += order.Goods[i].UseGoodNumber } else { useOrderCount += order.Goods[i].PlanGoodNumber } partnerBonusHas = partnerBonusHas.Add(decimal.NewFromFloat(order.Goods[i].GoodCompute.PartnerBonusHas)) partnerBonusNot = partnerBonusNot.Add(decimal.NewFromFloat(order.Goods[i].GoodCompute.PartnerBonusNot)) partnerBonusExpense = partnerBonusExpense.Add(decimal.NewFromFloat(order.Goods[i].GoodCompute.PartnerBonusExpense)) } //汇总赋值 order.OrderCompute.PartnerBonusExpense, _ = partnerBonusExpense.Round(2).BigFloat().Float64() order.OrderCompute.PartnerBonusHas, _ = partnerBonusHas.Round(2).BigFloat().Float64() order.OrderCompute.PartnerBonusNot, _ = partnerBonusNot.Round(2).BigFloat().Float64() order.OrderCompute.PlanPartnerBonus, _ = planPartnerBonus.Round(2).BigFloat().Float64() order.OrderCompute.PlanOrderAmount, _ = planOrderAmount.Round(2).BigFloat().Float64() order.OrderCompute.PlanOrderCount = planOrderCount if hasUsePartnerBonus { order.OrderCompute.UsePartnerBonus, _ = usePartnerBonus.Round(2).BigFloat().Float64() } else { order.OrderCompute.UsePartnerBonus = -1 } if hasUseOrderAmount { order.OrderCompute.UseOrderAmount, _ = useOrderAmount.Round(2).BigFloat().Float64() //计算业务员的抽成 order.OrderCompute.SalesmanBonus, _ = useOrderAmount. Mul(decimal.NewFromFloat(order.SalesmanBonusPercent)). Div(decimal.NewFromInt(100)). Round(2).BigFloat().Float64() } else { order.OrderCompute.UseOrderAmount = -1 order.OrderCompute.SalesmanBonus, _ = planOrderAmount. Mul(decimal.NewFromFloat(order.SalesmanBonusPercent)). Div(decimal.NewFromInt(100)). Round(2).BigFloat().Float64() } if HasUseOrderCount { order.OrderCompute.UseOrderCount = useOrderCount } else { order.OrderCompute.UseOrderCount = -1 } return nil } type OrderBaseFindOneQuery struct { OrderId int64 CompanyId int64 } type OrderBaseFindQuery struct { PartnerId int64 OrderCode string DeliveryCode string Offset int Limit int OrderType int CompanyId int64 } type OrderBaseRepository interface { Save(order *OrderBase) error FindOne(qureyOptions OrderBaseFindOneQuery) (*OrderBase, error) Find(queryOptions OrderBaseFindQuery) ([]OrderBase, int, error) Remove(id int64, companyId int64) error }