go-common/app/admin/main/coupon/service/allowance.go

271 lines
7.0 KiB
Go
Raw Normal View History

2019-04-22 10:49:16 +00:00
package service
import (
"context"
"encoding/csv"
"fmt"
"mime/multipart"
"strconv"
"strings"
"time"
"go-common/app/admin/main/coupon/model"
"go-common/library/database/sql"
"go-common/library/ecode"
"go-common/library/log"
xtime "go-common/library/time"
"github.com/pkg/errors"
)
// AddAllowanceBatchInfo add allowance batch info.
func (s *Service) AddAllowanceBatchInfo(c context.Context, b *model.CouponBatchInfo) (token string, err error) {
if b.ExpireDay < 0 && (b.StartTime <= 0 && b.ExpireTime <= 0) {
err = ecode.CouponExpireErr
return
}
if b.ExpireDay < 0 && b.StartTime >= b.ExpireTime {
err = ecode.CouPonBatchTimeErr
return
}
if b.Amount >= b.FullAmount {
err = ecode.CouponAmountErr
return
}
b.BatchToken = s.token()
b.Ctime = xtime.Time(time.Now().Unix())
if _, err = s.dao.AddAllowanceBatchInfo(c, b); err != nil {
err = errors.WithStack(err)
}
token = b.BatchToken
return
}
//UpdateAllowanceBatchInfo update allowance batch info.
func (s *Service) UpdateAllowanceBatchInfo(c context.Context, b *model.CouponBatchInfo) (err error) {
if _, err = s.dao.UpdateAllowanceBatchInfo(c, b); err != nil {
err = errors.WithStack(err)
}
return
}
//UpdateCodeBatchInfo update code batch info.
func (s *Service) UpdateCodeBatchInfo(c context.Context, b *model.CouponBatchInfo) (err error) {
var data *model.CouponBatchInfo
if data, err = s.BatchInfoByID(c, b.ID); err != nil {
return
}
if data == nil || batchState(data) != model.CodeBatchUsable {
return ecode.RequestErr
}
if _, err = s.dao.UpdateCodeBatchInfo(c, b); err != nil {
err = errors.WithStack(err)
}
return
}
//UpdateBatchStatus update batch status.
func (s *Service) UpdateBatchStatus(c context.Context, status int8, operator string, id int64) (err error) {
var data *model.CouponBatchInfo
if data, err = s.BatchInfoByID(c, id); err != nil {
return
}
if data == nil ||
(status == model.CodeBatchBlock && batchState(data) != model.CodeBatchUsable) ||
(status == model.CodeBatchUsable && batchState(data) != model.CodeBatchBlock) {
return ecode.RequestErr
}
if _, err = s.dao.UpdateBatchStatus(c, status, operator, id); err != nil {
err = errors.WithStack(err)
}
return
}
//BatchInfo allowance batch info.
func (s *Service) BatchInfo(c context.Context, token string) (res *model.CouponBatchInfo, err error) {
if res, err = s.dao.BatchInfo(c, token); err != nil {
err = errors.WithStack(err)
}
return
}
//BatchInfoByID allowance batch info.
func (s *Service) BatchInfoByID(c context.Context, id int64) (*model.CouponBatchInfo, error) {
return s.dao.BatchInfoByID(c, id)
}
// AllowanceSalary allowance salary.
func (s *Service) AllowanceSalary(c context.Context, f multipart.File, h *multipart.FileHeader, mids []int64, token, msgType string) (count int, err error) {
var bi *model.CouponBatchInfo
if len(mids) == 0 {
if mids, err = s.ReadCsv(f, h); err != nil {
err = errors.WithStack(err)
return
}
}
if len(mids) == 0 {
err = ecode.CouponBatchSalaryCountZeroErr
return
}
if len(mids) > _maxSalaryCount {
err = ecode.CouponBatchSalaryLimitErr
return
}
if bi, err = s.dao.BatchInfo(c, token); err != nil {
err = errors.WithStack(err)
return
}
if bi == nil {
err = ecode.CouPonTokenNotFoundErr
return
}
if bi.State != model.BatchStateNormal {
err = ecode.CouPonHadBlockErr
return
}
if bi.ExpireDay < 0 && bi.ExpireTime < time.Now().Unix() {
err = ecode.CouponBatchExpireTimeErr
return
}
if bi.MaxCount != _notLimitSalary && len(mids) > int(bi.MaxCount-bi.CurrentCount) {
err = ecode.CouponBatchSalaryLimitErr
return
}
s.RunSalaryCoupon(c, mids, token, bi.AppID, model.CouponAllowance, model.AdminSalaryOrigin, msgType)
count = len(mids)
return
}
// ReadCsv read csv file
func (s *Service) ReadCsv(f multipart.File, h *multipart.FileHeader) (mids []int64, err error) {
var (
mid int64
records [][]string
)
mids = []int64{}
defer f.Close()
if h != nil && !strings.HasSuffix(h.Filename, ".csv") {
err = ecode.CouponUpdateFileErr
return
}
r := csv.NewReader(f)
records, err = r.ReadAll()
if err != nil {
err = errors.WithStack(err)
return
}
for _, v := range records {
if len(v) <= 0 {
continue
}
if mid, err = strconv.ParseInt(v[0], 10, 64); err != nil {
err = errors.WithStack(err)
break
}
mids = append(mids, mid)
}
return
}
// //AllowancePage allowance page.
// func (s *Service) AllowancePage(c context.Context, arg *model.ArgAllowanceSearch) (res *model.PageCouponInfo, err error) {
// var page *model.SearchData
// res = &model.PageCouponInfo{}
// if page, err = s.dao.AllowancePage(c, arg); err != nil {
// err = errors.WithStack(err)
// return
// }
// if page != nil && page.Data != nil && page.Data.Page != nil {
// res.Count = page.Data.Page.Total
// res.Item = page.Data.Result
// }
// return
// }
//AllowanceList allowance list.
func (s *Service) AllowanceList(c context.Context, arg *model.ArgAllowanceSearch) (res []*model.CouponAllowanceInfo, err error) {
if res, err = s.dao.AllowanceList(c, arg); err != nil {
err = errors.WithStack(err)
}
for _, v := range res {
if v.State == model.NotUsed && v.ExpireTime < time.Now().Unix() {
v.State = model.Expire
}
}
return
}
//UpdateAllowanceState update allowance state.
func (s *Service) UpdateAllowanceState(c context.Context, mid int64, state int8, token string) (err error) {
var (
cp *model.CouponAllowanceInfo
changeType int8
)
if cp, err = s.dao.AllowanceByToken(c, mid, token); err != nil {
err = errors.WithStack(err)
return
}
if cp == nil {
err = ecode.CouPonTokenNotFoundErr
return
}
if state == model.Block {
changeType = model.AllowanceBlock
} else {
changeType = model.AllowanceUnBlock
}
if err = s.UpdateAllowanceCoupon(c, mid, state, token, cp.Ver, changeType, cp); err != nil {
err = errors.WithStack(err)
}
return
}
// UpdateAllowanceCoupon update coupon info.
func (s *Service) UpdateAllowanceCoupon(c context.Context, mid int64, state int8, token string, ver int64, changeType int8, cp *model.CouponAllowanceInfo) (err error) {
var (
tx *sql.Tx
aff int64
)
if tx, err = s.dao.BeginTran(c); err != nil {
log.Error("%+v", err)
return
}
defer func() {
if err != nil {
if err1 := tx.Rollback(); err1 != nil {
log.Error("tx.Rollback %+v", err1)
}
return
}
if err = tx.Commit(); err != nil {
log.Error("tx.Commit %+v", err)
}
}()
if aff, err = s.dao.UpdateAllowanceStatus(c, tx, state, mid, token, ver); err != nil {
err = errors.WithStack(err)
}
if aff != 1 {
err = fmt.Errorf("coupon update faild")
return
}
l := &model.CouponAllowanceChangeLog{
CouponToken: cp.CouponToken,
Mid: cp.Mid,
State: state,
Ctime: xtime.Time(time.Now().Unix()),
OrderNO: cp.OrderNO,
ChangeType: changeType,
}
if aff, err = s.dao.InsertCouponAllowanceHistory(c, tx, l); err != nil {
err = errors.WithStack(err)
return
}
if aff != 1 {
err = fmt.Errorf("add change log faild")
return
}
s.dao.DelCouponAllowancesKey(c, cp.Mid, model.NotUsed)
s.dao.DelCouponAllowancesKey(c, cp.Mid, model.InUse)
return
}