order_good.go
12.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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
83
84
85
86
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
package domain
import (
"errors"
"fmt"
"github.com/shopspring/decimal"
)
//分红状态
type OrderGoodBonusStatus interface {
//状态变更为待支付
WartPayPartnerBonus(orderGood *OrderGood) error
//状态变更为已支付
PayPartnerBonus(orderGood *OrderGood) error
//变更货品数量
ModifyOrderGoodNumber(good *OrderGood, number int, orderType int) error
//变更合伙人分红比例
ModifyPertnerBonusPercent(good *OrderGood, percent float64, orderType int) error
}
//货单的支付状态
const (
//待支付
OrderGoodWaitPay int = 1
//已支付
OrderGoodHasPay int = 2
)
//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"`
}
type OrderGoodRemarkReason struct {
ModifyGoodNumber string `json:"modifyGoodNumber"` //货品数量变更的理由
ModifyPartnerBonusPercent string `json:"modifyPartnerBonusPercent"` //合伙人分红比例变更的理由
}
//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"`
//合伙人分红比例 比如12.7等同于12.7%,使用负值表示分红比例未进行设置
PartnerBonusPercent float64 `json:"partnerBonusPercent"`
//分红支付状态
BonusStatus int `json:"bonusStatus"`
//备注信息
Remark string `json:"remark"`
//当前分红支付状态
CurrentBonusStatus OrderGoodBonusStatus `json:"-"`
///核算订单相关数据
GoodCompute GoodCompute `json:"goodCompute"`
//公司
CompanyId int64 `json:"companyId"`
//原因备注
RemarkReason OrderGoodRemarkReason `json:"remarkReason"`
DataFrom OrderDataFrom `json:"data_from"`
}
//NewOrderGood 初始值设定
func NewOrderGood() OrderGood {
return OrderGood{
UseGoodNumber: -1,
BonusStatus: OrderGoodWaitPay,
PartnerBonusPercent: -1,
GoodCompute: GoodCompute{
UsePartnerBonus: -1,
UseAmount: -1,
},
CurrentBonusStatus: OrderGoodBonusWaitPay{},
}
}
//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
}
//ModifyOrderGoodNumber 修改货品数量
func (good *OrderGood) ModifyOrderGoodNumber(number int, orderType int) error {
if good.PlanGoodNumber < number {
return fmt.Errorf("修改数量不能大于初始值:%d", good.PlanGoodNumber)
}
err := good.CurrentBonusStatus.ModifyOrderGoodNumber(good, number, orderType)
return err
}
//ModifyPertnerBonusPercent 修改货品的分红比例
func (good *OrderGood) ModifyPertnerBonusPercent(percent float64, orderType int) error {
err := good.CurrentBonusStatus.ModifyPertnerBonusPercent(good, percent, orderType)
return err
}
//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)
}
if v, ok := m["RemarkReason"]; ok {
good.RemarkReason = v.(OrderGoodRemarkReason)
}
err := good.Compute()
return err
}
//OrderGoodBonusWaitPay 货品分红待支付
type OrderGoodBonusWaitPay struct{}
var _ OrderGoodBonusStatus = (*OrderGoodBonusWaitPay)(nil)
//OrderGoodBonusHasPay 货品分红已支付
type OrderGoodBonusHasPay struct{}
var _ OrderGoodBonusStatus = (*OrderGoodBonusHasPay)(nil)
//WartPayPartnerBonus 货品的支付状态从“待支付”状态变更为“待支付”
func (waitPay OrderGoodBonusWaitPay) WartPayPartnerBonus(good *OrderGood) error {
good.GoodCompute.PartnerBonusExpense = 0
good.GoodCompute.PartnerBonusHas = 0
//初始状态为待支付时 ,合伙人未收分红等于合伙人应收分红(或者调整的)
if good.UseGoodNumber < 0 {
//数量没有调整,未收等于预计应收分红
good.GoodCompute.PartnerBonusNot = good.GoodCompute.PlanPartnerBonus
} else {
//数量有调整,未收等于调整后的应收分红
good.GoodCompute.PartnerBonusNot = good.GoodCompute.UsePartnerBonus
}
good.CurrentBonusStatus = OrderGoodBonusWaitPay{}
good.BonusStatus = OrderGoodWaitPay
return nil
}
//PayPartnerBonus 货品的支付状态从“待支付”状态变更为“已支付”
func (waitPay OrderGoodBonusWaitPay) PayPartnerBonus(good *OrderGood) error {
//待支付状态转支付时
//合伙人已收收分红等于合伙人应收分红(或者调整的)
//计算已支付
if good.UseGoodNumber < 0 {
//数量没有调整,已收等于预计应收分红
good.GoodCompute.PartnerBonusHas = good.GoodCompute.PlanPartnerBonus
} else {
//数量有调整,已收等于调整后的应收分红
good.GoodCompute.PartnerBonusHas = good.GoodCompute.UsePartnerBonus
}
good.GoodCompute.PartnerBonusExpense = 0
good.GoodCompute.PartnerBonusNot = 0
good.CurrentBonusStatus = OrderGoodBonusHasPay{}
good.BonusStatus = OrderGoodHasPay
return nil
}
//PayPartnerBonus 货品的支付状态从“已支付”状态变更为“已支付”
func (hasPay OrderGoodBonusHasPay) PayPartnerBonus(good *OrderGood) error {
//已支付的值保持不变
//未支付的值保持不变
//计算分红支出
//分红支出=应收分红(有出现调整,则取调整后的应收分红)和已收分红的差额
if good.UseGoodNumber >= 0 {
//有数量调整,分红支出等于 已支付分红-调整后的已收分红
good.GoodCompute.PartnerBonusExpense = good.GoodCompute.PartnerBonusHas - good.GoodCompute.UsePartnerBonus
}
good.CurrentBonusStatus = OrderGoodBonusHasPay{}
good.BonusStatus = OrderGoodHasPay
return nil
}
//WartPayPartnerBonus 货品的支付状态从“已支付”状态变更为“待支付”
func (hasPay OrderGoodBonusHasPay) WartPayPartnerBonus(good *OrderGood) error {
return errors.New("已支付的货单不能将状态回退为待支付")
}
//ModifyOrderGoodNumber 货品的支付状态为“已支付”状态变时,修改货品数量
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
}
//ModifyOrderGoodNumber 货品的支付状态为“待支付”状态变时,修改货品数量
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
}
//ModifyPertnerBonusPercent 货品的支付状态为“待支付”状态变时,修改货品合伙人分红比例
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("已支付分红的货品订单,不能修改合伙人分红比例")
}
//Compute 数据汇总核算
func (good *OrderGood) Compute() error {
//计算预计货品总值
//计算预计合伙人分红
price := decimal.NewFromFloat(good.Price)
planGoodNumber := good.PlanGoodNumber
if good.PlanGoodNumber < 0 {
planGoodNumber = 0
}
//计算预计货品总值(planamount), 货品单价*预计货品数量(price*planGoodNumber)
planamount := price.Mul(decimal.NewFromInt(int64(planGoodNumber)))
var partnerBonusPercent float64
if good.PartnerBonusPercent < 0 {
//判断合伙人分成比例是否设置,若未设置则按照 0 来计算分成
partnerBonusPercent = 0
} else {
partnerBonusPercent = good.PartnerBonusPercent
}
//计算预计合伙人分红(planPartnerBonus), 预计货品总值*合伙人分成比例/100(planamount*partnerBonusPercent/100)
planPartnerBonus := planamount.Mul(decimal.NewFromFloat(partnerBonusPercent)).Div(decimal.NewFromInt(100)) //price*planGoodNumber*PartnerBonusPercent
//货品预计总值
good.GoodCompute.PlanAmount, _ = planamount.Round(2).BigFloat().Float64()
good.GoodCompute.PlanPartnerBonus, _ = planPartnerBonus.Round(2).BigFloat().Float64()
if good.UseGoodNumber < 0 {
//没有出现数量调整,使用负值进行标记
good.GoodCompute.UsePartnerBonus = -1
good.GoodCompute.UseAmount = -1
} else {
//计算调整后的货品总值
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
good.GoodCompute.UsePartnerBonus, _ = usePartnerBonus.Round(2).BigFloat().Float64()
good.GoodCompute.UseAmount, _ = useamount.Round(2).BigFloat().Float64()
}
return nil
}
type OrderGoodFindQuery struct {
OrderId int64
Offset int
Limit int
CompanyId int64
}
type OrderGoodFindOneQuery struct {
GoodId int64
}
type OrderGoodRepository interface {
Save(order []OrderGood) error
Find(queryOptions OrderGoodFindQuery) ([]OrderGood, int, error)
FindOne(queryOptions OrderGoodFindOneQuery) (OrderGood, error)
Remove(orderid int64, companyId int64, ids ...int64) error
}