审查视图

pkg/domain/order_good.go 11.4 KB
tangxvhui authored
1 2 3 4
package domain

import (
	"errors"
唐旭辉 authored
5
	"fmt"
tangxvhui authored
6 7 8 9 10 11 12 13 14 15

	"github.com/shopspring/decimal"
)

//分红状态
type OrderGoodBonusStatus interface {
	//状态变更为待支付
	WartPayPartnerBonus(orderGood *OrderGood) error
	//状态变更为已支付
	PayPartnerBonus(orderGood *OrderGood) error
唐旭辉 authored
16
	//变更货品数量
唐旭辉 authored
17
	ModifyOrderGoodNumber(good *OrderGood, number int, orderType int) error
唐旭辉 authored
18
	//变更合伙人分红比例
唐旭辉 authored
19
	ModifyPertnerBonusPercent(good *OrderGood, percent float64, orderType int) error
tangxvhui authored
20 21 22 23 24 25 26 27 28 29
}

//货单的支付状态
const (
	//待支付
	OrderGoodWaitPay int = 1
	//已支付
	OrderGoodHasPay int = 2
)
唐旭辉 authored
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
//GoodCompute 货品中计算值
type GoodCompute struct {
	//预计的货品总额
	PlanAmount float64 `json:"planAmount"`
	//调整后的货品总额 (初始值=-1)
	//业务判定时0是有效值,
	//所以用空串表示无值,转换到数据库中为负值
	UseAmount float64 `json:"useAmount"`
	//预计的合伙人分红
	PlanPartnerBonus float64 `json:"planPartnerBonus"`
	//合伙人应收分红调整 (初始值=-1),
	//业务判定时0是有效值,
	//所以用空串表示无值,转换到数据库中为负值
	UsePartnerBonus float64 `json:"usePartnerBonus"`
	//合伙人已收分红
	PartnerBonusHas float64 `json:"partnerBonusHas"`
	//合伙人未收分红
	PartnerBonusNot float64 `json:"partnerBonusNot"`
	//合伙人分红支出
	PartnerBonusExpense float64 `json:"partnerBonusExpense"`
}
唐旭辉 authored
51
唐旭辉 authored
52 53 54 55
type OrderGoodRemarkReason struct {
	ModifyGoodNumber          string `json:"modifyGoodNumber"`          //货品数量变更的理由
	ModifyPartnerBonusPercent string `json:"modifyPartnerBonusPercent"` //合伙人分红比例变更的理由
}
唐旭辉 authored
56
tangxvhui authored
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
//OrderGood 订单中的货品
type OrderGood struct {
	//货品id
	Id int64 `json:"id"`
	//所属订单id
	OrderId int64 `json:"orderId"`
	//货品名称 长度可能较长
	GoodName string `json:"goodName"`
	//预计的货品数量
	PlanGoodNumber int `json:"planGoodNumber"`
	//调整后的货品数量
	//业务判定时0是有效值,
	//所以用空串表示无值,转换到数据库中为负值
	UseGoodNumber int `json:"useGoodNumber"`
	//货品单价
	Price float64 `json:"price"`
	//合伙人分红比例
	PartnerBonusPercent float64 `json:"partnerBonusPercent"`
	//分红支付状态
	BonusStatus int `json:"bonusStatus"`
	//备注信息
	Remark string `json:"remark"`
	//当前分红支付状态
	CurrentBonusStatus OrderGoodBonusStatus `json:"-"`
	///核算订单相关数据
	GoodCompute GoodCompute `json:"goodCompute"`
83
	//公司
唐旭辉 authored
84 85 86
	CompanyId int64 `json:"companyId"`
	//原因备注
	RemarkReason OrderGoodRemarkReason `json:"remarkReason"`
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
	DataFrom     OrderDataFrom         `json:"data_from"`
}

//GetCurrentGoodNumber 获取当前的商品数量
func (good OrderGood) GetCurrentGoodNumber() int {
	if good.UseGoodNumber >= 0 {
		return good.UseGoodNumber
	}
	return good.PlanGoodNumber
}

//GetCurrentAmount 获取当前的商品总额
func (good OrderGood) GetCurrentAmount() float64 {
	if good.GoodCompute.UseAmount >= 0 {
		return good.GoodCompute.UseAmount
	}
	return good.GoodCompute.PlanAmount
}

//GetCurrentAmount 获取当前的商品合伙人分红
func (good OrderGood) GetCurrentPartnerBonus() float64 {
	if good.GoodCompute.UsePartnerBonus >= 0 {
		return good.GoodCompute.UsePartnerBonus
	}
	return good.GoodCompute.PlanPartnerBonus
tangxvhui authored
112 113
}
唐旭辉 authored
114 115
//GetCurrentAmount 获取当前的商品合伙人分红
func (good *OrderGood) ModifyOrderGoodNumber(number int, orderType int) error {
唐旭辉 authored
116 117 118
	if good.PlanGoodNumber < number {
		return fmt.Errorf("修改数量不能大于初始值:%d", good.PlanGoodNumber)
	}
唐旭辉 authored
119 120 121 122 123 124 125 126 127
	err := good.CurrentBonusStatus.ModifyOrderGoodNumber(good, number, orderType)
	return err
}

func (good *OrderGood) ModifyPertnerBonusPercent(percent float64, orderType int) error {
	err := good.CurrentBonusStatus.ModifyPertnerBonusPercent(good, percent, orderType)
	return err
}
唐旭辉 authored
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
//Update 更新商品相关的数据
func (good *OrderGood) Update(m map[string]interface{}) error {
	if v, ok := m["GoodName"]; ok {
		good.GoodName = v.(string)
	}
	if v, ok := m["PlanGoodNumber"]; ok {
		good.PlanGoodNumber = v.(int)
	}
	if v, ok := m["UseGoodNumber"]; ok {
		good.UseGoodNumber = v.(int)
	}
	if v, ok := m["Price"]; ok {
		good.Price = v.(float64)
	}
	if v, ok := m["PartnerBonusPercent"]; ok {
		good.PartnerBonusPercent = v.(float64)
	}
	if v, ok := m["Remark"]; ok {
		good.Remark = v.(string)
	}
唐旭辉 authored
148 149 150
	if v, ok := m["RemarkReason"]; ok {
		good.RemarkReason = v.(OrderGoodRemarkReason)
	}
唐旭辉 authored
151 152
	err := good.Compute()
	return err
tangxvhui authored
153 154 155 156 157 158 159 160 161 162 163 164
}

//OrderGoodBonusWaitPay 货品分红待支付
type OrderGoodBonusWaitPay struct{}

var _ OrderGoodBonusStatus = (*OrderGoodBonusWaitPay)(nil)

//OrderGoodBonusHasPay 货品分红已支付
type OrderGoodBonusHasPay struct{}

var _ OrderGoodBonusStatus = (*OrderGoodBonusHasPay)(nil)
tangxvhui authored
165
func (waitPay OrderGoodBonusWaitPay) WartPayPartnerBonus(good *OrderGood) error {
tangxvhui authored
166 167 168 169
	good.GoodCompute.PartnerBonusExpense = 0
	good.GoodCompute.PartnerBonusHas = 0
	//初始状态为待支付时 ,合伙人未收分红等于合伙人应收分红(或者调整的)
	if good.UseGoodNumber < 0 {
tangxvhui authored
170
		//数量没有调整,未收等于预计应收分红
tangxvhui authored
171 172
		good.GoodCompute.PartnerBonusNot = good.GoodCompute.PlanPartnerBonus
	} else {
tangxvhui authored
173
		//数量有调整,未收等于调整后的应收分红
tangxvhui authored
174 175
		good.GoodCompute.PartnerBonusNot = good.GoodCompute.UsePartnerBonus
	}
176
	good.CurrentBonusStatus = OrderGoodBonusWaitPay{}
唐旭辉 authored
177
	good.BonusStatus = OrderGoodWaitPay
tangxvhui authored
178 179 180
	return nil
}
tangxvhui authored
181
func (waitPay OrderGoodBonusWaitPay) PayPartnerBonus(good *OrderGood) error {
tangxvhui authored
182 183 184 185 186
	//待支付状态转支付时
	//合伙人已收收分红等于合伙人应收分红(或者调整的)
	//计算已支付
	if good.UseGoodNumber < 0 {
		//数量没有调整,已收等于预计应收分红
tangxvhui authored
187 188
		good.GoodCompute.PartnerBonusHas = good.GoodCompute.PlanPartnerBonus
	} else {
tangxvhui authored
189
		//数量有调整,已收等于调整后的应收分红
tangxvhui authored
190 191 192
		good.GoodCompute.PartnerBonusHas = good.GoodCompute.UsePartnerBonus
	}
	good.GoodCompute.PartnerBonusExpense = 0
tangxvhui authored
193
	good.GoodCompute.PartnerBonusNot = 0
194
	good.CurrentBonusStatus = OrderGoodBonusHasPay{}
唐旭辉 authored
195
	good.BonusStatus = OrderGoodHasPay
tangxvhui authored
196 197 198 199 200 201 202 203 204
	return nil
}

func (hasPay OrderGoodBonusHasPay) PayPartnerBonus(good *OrderGood) error {
	//已支付的值保持不变
	//未支付的值保持不变
	//计算分红支出
	//分红支出=应收分红(有出现调整,则取调整后的应收分红)和已收分红的差额
	if good.UseGoodNumber >= 0 {
tangxvhui authored
205
		//有数量调整,分红支出等于 已支付分红-调整后的已收分红
tangxvhui authored
206 207
		good.GoodCompute.PartnerBonusExpense = good.GoodCompute.PartnerBonusHas - good.GoodCompute.UsePartnerBonus
	}
208
	good.CurrentBonusStatus = OrderGoodBonusHasPay{}
唐旭辉 authored
209
	good.BonusStatus = OrderGoodHasPay
tangxvhui authored
210 211 212 213 214 215 216
	return nil
}

func (hasPay OrderGoodBonusHasPay) WartPayPartnerBonus(good *OrderGood) error {
	return errors.New("已支付的货单不能将状态回退为待支付")
}
唐旭辉 authored
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
func (hasPay OrderGoodBonusHasPay) ModifyOrderGoodNumber(good *OrderGood, number int, orderType int) error {
	//规则描述:
	//实际自建订单(orderType==1),已支付分红状态下“可以”修改货品数量
	//香米小程序订单(orderType==3),已支付分红状态下“不可以”修改货品数量
	switch orderType {
	case OrderReal:
		good.UseGoodNumber = number
		//待支付状态计算
		err := good.Compute()
		if err != nil {
			return errors.New("核算商品数据失败" + err.Error())
		}
	case OrderTypeBestShop:
		return errors.New("小程序订单里已支付分红的货品订单,不能修改货品数量")
	}
	good.CurrentBonusStatus.PayPartnerBonus(good)
	return nil
}

func (waitPay OrderGoodBonusWaitPay) ModifyOrderGoodNumber(good *OrderGood, number int, orderType int) error {
	//规则描述:
	//实际自建订单(orderType==1),未支付分红状态下“可以”修改货品数量
	//香米小程序订单(orderType==3),未支付分红状态下“可以”修改货品数量
	good.UseGoodNumber = number
	//待支付状态计算
	err := good.Compute()
	if err != nil {
		return errors.New("核算商品数据失败" + err.Error())
	}
	good.CurrentBonusStatus.WartPayPartnerBonus(good)
	return nil
}

func (waitPay OrderGoodBonusWaitPay) ModifyPertnerBonusPercent(good *OrderGood, percent float64, orderType int) error {
	//规则描述:
	//实际自建订单(orderType==1),未支付分红状态下“不可以”修改合伙人分红比例
	//香米小程序订单(orderType==3),未支付分红状态下“可以”修改合伙人分红比例
	switch orderType {
	case OrderReal:
		return errors.New("自建订单不能修改合伙人分红比例")
	case OrderTypeBestShop:
		good.PartnerBonusPercent = percent
		//待支付状态计算
		err := good.Compute()
		if err != nil {
			return errors.New("核算商品数据失败" + err.Error())
		}
		err = good.CurrentBonusStatus.WartPayPartnerBonus(good)
		if err != nil {
			return errors.New("核算商品数据失败" + err.Error())
		}
	}
	return nil
}

func (hasPay OrderGoodBonusHasPay) ModifyPertnerBonusPercent(good *OrderGood, percent float64, orderType int) error {
	//规则描述:
	//实际自建订单(orderType==1),已支付分红状态下“不可以”修改合伙人分红比例
	//香米小程序订单(orderType==3),已支付分红状态下“不可以”修改合伙人分红比例
	return errors.New("已支付分红的货品订单,不能修改合伙人分红比例")
}
tangxvhui authored
279 280 281
//NewOrderGood 初始值设定
func NewOrderGood() OrderGood {
	return OrderGood{
唐旭辉 authored
282 283 284
		UseGoodNumber:       -1,
		BonusStatus:         OrderGoodWaitPay,
		PartnerBonusPercent: -1,
tangxvhui authored
285 286 287 288 289 290 291 292 293 294
		GoodCompute: GoodCompute{
			UsePartnerBonus: -1,
			UseAmount:       -1,
		},
		CurrentBonusStatus: OrderGoodBonusWaitPay{},
	}
}

//Compute 数据汇总核算
func (good *OrderGood) Compute() error {
tangxvhui authored
295 296
	//计算预计货品总值
	//计算预计合伙人分红
tangxvhui authored
297
	price := decimal.NewFromFloat(good.Price)
唐旭辉 authored
298 299 300 301 302
	planGoodNumber := good.PlanGoodNumber
	if good.PlanGoodNumber < 0 {
		planGoodNumber = 0
	}
	planamount := price.Mul(decimal.NewFromInt(int64(planGoodNumber))) //price*planGoodNumber
唐旭辉 authored
303 304 305
	var partnerBonusPercent float64
	if good.PartnerBonusPercent < 0 {
		partnerBonusPercent = 0
唐旭辉 authored
306 307
	} else {
		partnerBonusPercent = good.PartnerBonusPercent
唐旭辉 authored
308
	}
tangxvhui authored
309
	//price*useGoodNumber
唐旭辉 authored
310
	planPartnerBonus := planamount.Mul(decimal.NewFromFloat(partnerBonusPercent)).Div(decimal.NewFromInt(100)) //price*planGoodNumber*PartnerBonusPercent
tangxvhui authored
311 312
	good.GoodCompute.PlanAmount, _ = planamount.Round(2).BigFloat().Float64()
	good.GoodCompute.PlanPartnerBonus, _ = planPartnerBonus.Round(2).BigFloat().Float64()
tangxvhui authored
313 314 315 316 317
	if good.UseGoodNumber < 0 {
		//没有出现数量调整
		good.GoodCompute.UsePartnerBonus = -1
		good.GoodCompute.UseAmount = -1
	} else {
tangxvhui authored
318 319
		//计算调整后的货品总值
		//计算调整后的合伙人分红
唐旭辉 authored
320 321
		useamount := price.Mul(decimal.NewFromInt(int64(good.UseGoodNumber)))                                    //price*useGoodNumber/price*useGoodNumber
		usePartnerBonus := useamount.Mul(decimal.NewFromFloat(partnerBonusPercent)).Div(decimal.NewFromInt(100)) //price*useGoodNumber*PartnerBonusPercent
tangxvhui authored
322 323
		good.GoodCompute.UsePartnerBonus, _ = usePartnerBonus.Round(2).BigFloat().Float64()
		good.GoodCompute.UseAmount, _ = useamount.Round(2).BigFloat().Float64()
tangxvhui authored
324 325 326 327 328 329
	}

	return nil
}

type OrderGoodFindQuery struct {
330 331 332 333
	OrderId   int64
	Offset    int
	Limit     int
	CompanyId int64
tangxvhui authored
334
}
唐旭辉 authored
335 336 337
type OrderGoodFindOneQuery struct {
	GoodId int64
}
tangxvhui authored
338 339 340
type OrderGoodRepository interface {
	Save(order []OrderGood) error
	Find(queryOptions OrderGoodFindQuery) ([]OrderGood, int, error)
唐旭辉 authored
341
	FindOne(queryOptions OrderGoodFindOneQuery) (OrderGood, error)
342
	Remove(orderid int64, companyId int64, ids ...int64) error
tangxvhui authored
343
}