516 lines
18 KiB
Go
516 lines
18 KiB
Go
package change
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/logic/iot/cardpackage"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/do"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity"
|
|
|
|
"github.com/gogf/gf/v2/database/gdb"
|
|
"github.com/gogf/gf/v2/encoding/gjson"
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
)
|
|
|
|
func (p *Processor) Complete(ctx context.Context, tx gdb.TX, in *CompleteInput) (*CompleteOutput, error) {
|
|
if in == nil || in.SubmitParam == nil {
|
|
return nil, gerror.New("change params cannot be empty")
|
|
}
|
|
sourceBatchNo := strings.TrimSpace(in.SourceBatchNo)
|
|
if strings.TrimSpace(in.BatchNo) == "" {
|
|
return nil, gerror.New("change batchNo cannot be empty")
|
|
}
|
|
if len(in.Rows) == 0 {
|
|
return nil, gerror.New("change cards cannot be empty")
|
|
}
|
|
if in.PriceSnapshot == nil {
|
|
return nil, gerror.New("change price snapshot cannot be empty")
|
|
}
|
|
if in.PackageBeginTime == nil {
|
|
return nil, gerror.New("change package begin time cannot be empty")
|
|
}
|
|
|
|
iccids := rowsToIccids(in.Rows)
|
|
packageSvc := cardpackage.NewService()
|
|
termination, err := packageSvc.TerminateCurrentPackage(ctx, tx, &cardpackage.TerminateCurrentPackageInput{
|
|
BatchNo: in.BatchNo,
|
|
SourceBatchNo: sourceBatchNo,
|
|
Iccids: iccids,
|
|
Operator: in.Operator,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
voidedByIccid, err := p.voidFuturePendingBinds(ctx, tx, iccids, in.BatchNo, termination.UnsubTime, in.Operator.UserId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
quantity := len(iccids)
|
|
totalAmount := roundAmount(in.PriceSnapshot.ChangeUnitPrice * float64(in.SubmitParam.DurationMonths) * float64(quantity))
|
|
cards := make([]cardpackage.SubscribeCard, 0, quantity)
|
|
for _, iccid := range iccids {
|
|
card := termination.CardsByIccid[iccid]
|
|
if card == nil {
|
|
return nil, gerror.Newf("ICCID card info not found: %s", iccid)
|
|
}
|
|
cards = append(cards, cardpackage.SubscribeCard{
|
|
Iccid: iccid,
|
|
Msisdn: strings.TrimSpace(card.Msisdn),
|
|
Imsi: strings.TrimSpace(card.Imsi),
|
|
})
|
|
}
|
|
|
|
subscribe, err := packageSvc.CreatePackageSubscription(ctx, tx, &cardpackage.CreatePackageSubscriptionInput{
|
|
BatchNo: in.BatchNo,
|
|
Cards: cards,
|
|
CustomerAgentId: in.PriceSnapshot.CustomerAgentId,
|
|
PackageCode: in.PriceSnapshot.NewPackageCode,
|
|
PackageBeginTime: in.PackageBeginTime,
|
|
DurationMonths: in.SubmitParam.DurationMonths,
|
|
GiftDurationMonths: in.SubmitParam.GiftDurationMonths,
|
|
Amount: fmt.Sprintf("%.2f", totalAmount),
|
|
OfflineContractCompleted: in.SubmitParam.OfflineContractCompleted,
|
|
BuyerNote: in.SubmitParam.BuyerNote,
|
|
AdminNote: in.SubmitParam.AdminNote,
|
|
PreviousPackageCode: termination.PackageCode,
|
|
BusinessType: consts.PackageBusinessTypeChange,
|
|
OrderRemark: "sim card change order",
|
|
BindRemark: in.BatchNo,
|
|
Operator: in.Operator,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err = p.updateCardsAfterChange(ctx, tx, iccids, termination.CardsByIccid, subscribe, in.Operator.UserId); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
detailUpdates := make(map[string]any, len(iccids))
|
|
for _, row := range in.Rows {
|
|
card := termination.CardsByIccid[row.Iccid]
|
|
oldBind := termination.BindsByIccid[row.Iccid]
|
|
newBind := subscribe.BindsByIccid[row.Iccid]
|
|
detailUpdates[row.Iccid] = buildDetailSnapshot(row, card, oldBind, newBind, voidedByIccid[row.Iccid], in, termination, subscribe)
|
|
}
|
|
if err = updateBatchDetailSnapshots(ctx, tx, in.BatchNo, detailUpdates, in.Operator.UserId); err != nil {
|
|
return nil, err
|
|
}
|
|
if err = convertBatchDetailsAfterComplete(ctx, tx, in.BatchNo, in.Operator.UserId); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
output := &CompleteOutput{
|
|
BatchNo: in.BatchNo,
|
|
BatchType: consts.BatchTypeChange,
|
|
SourceBatchNo: sourceBatchNo,
|
|
SourceMode: sourceMode(sourceBatchNo),
|
|
Quantity: quantity,
|
|
CustomerAgentId: in.PriceSnapshot.CustomerAgentId,
|
|
CustomerName: "",
|
|
OldPackageCode: termination.PackageCode,
|
|
NewPackageCode: subscribe.Package.PackageCode,
|
|
NewPackageName: subscribe.Package.PackageName,
|
|
OrderSn: subscribe.OrderSn,
|
|
Amount: subscribe.Amount,
|
|
ChangeUnitPrice: in.PriceSnapshot.ChangeUnitPrice,
|
|
DurationMonths: in.SubmitParam.DurationMonths,
|
|
GiftDurationMonths: in.SubmitParam.GiftDurationMonths,
|
|
EffectiveMode: strings.TrimSpace(in.SubmitParam.EffectiveMode),
|
|
OfflineContractCompleted: in.SubmitParam.OfflineContractCompleted,
|
|
PackageBeginTime: subscribe.PackageBeginAt,
|
|
PackageEndTime: subscribe.PackageEndAt,
|
|
ChangeTime: subscribe.SubscribeTime,
|
|
}
|
|
if in.PrepareSnapshot != nil {
|
|
output.CustomerName = in.PrepareSnapshot.CustomerName
|
|
output.OldPackageName = in.PrepareSnapshot.OldPackageName
|
|
}
|
|
if err = updateBatchMainAfterComplete(ctx, tx, in, output); err != nil {
|
|
return nil, err
|
|
}
|
|
return output, nil
|
|
}
|
|
|
|
func (p *Processor) voidFuturePendingBinds(ctx context.Context, tx gdb.TX, iccids []string, batchNo string, voidTime *gtime.Time, userId int64) (map[string][]string, error) {
|
|
result := make(map[string][]string)
|
|
pendingBinds, err := p.repo.LockPendingBindsByIccids(ctx, tx, iccids)
|
|
if err != nil {
|
|
return nil, gerror.Wrap(err, "lock future pending binds failed")
|
|
}
|
|
if len(pendingBinds) == 0 {
|
|
return result, nil
|
|
}
|
|
|
|
orderCodeSet := make(map[string]struct{})
|
|
orderVoidCounts := make(map[string]int)
|
|
subscriptionNos := make([]string, 0, len(pendingBinds))
|
|
logRows := make([]do.TSimBindPackageLogs, 0, len(pendingBinds))
|
|
for _, bind := range pendingBinds {
|
|
if bind == nil {
|
|
continue
|
|
}
|
|
subscriptionNo := strings.TrimSpace(bind.SubscriptionNo)
|
|
if subscriptionNo == "" {
|
|
continue
|
|
}
|
|
subscriptionNos = append(subscriptionNos, subscriptionNo)
|
|
result[strings.TrimSpace(bind.Iccid)] = append(result[strings.TrimSpace(bind.Iccid)], subscriptionNo)
|
|
logRows = append(logRows, bindToVoidedHistory(bind, voidTime, batchNo, userId))
|
|
orderCode := strings.TrimSpace(bind.OrderCode)
|
|
if orderCode != "" {
|
|
orderCodeSet[orderCode] = struct{}{}
|
|
orderVoidCounts[orderCode]++
|
|
}
|
|
}
|
|
if len(logRows) > 0 {
|
|
if _, err = tx.Ctx(ctx).Model(dao.TSimBindPackageLogs.Table()).
|
|
Data(logRows).
|
|
OnConflict(dao.TSimBindPackageLogs.Columns().SubscriptionNo).
|
|
Save(); err != nil {
|
|
return nil, gerror.Wrap(err, "save voided bind history failed")
|
|
}
|
|
}
|
|
affected, err := p.repo.DeleteBindsBySubscriptionNos(ctx, tx, subscriptionNos)
|
|
if err != nil {
|
|
return nil, gerror.Wrap(err, "delete future pending binds failed")
|
|
}
|
|
if int(affected) != len(subscriptionNos) {
|
|
return nil, gerror.New("some future pending binds changed, please retry")
|
|
}
|
|
if err = p.updateOrdersAfterChangeVoid(ctx, tx, mapKeys(orderCodeSet), orderVoidCounts, batchNo, voidTime, userId); err != nil {
|
|
return nil, err
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func bindToVoidedHistory(bind *entity.TSimCardBindPkg, actualExpireAt *gtime.Time, changeBatchNo string, userId int64) do.TSimBindPackageLogs {
|
|
return do.TSimBindPackageLogs{
|
|
SubscriptionNo: bind.SubscriptionNo,
|
|
BatchNo: bind.BatchNo,
|
|
Iccid: bind.Iccid,
|
|
Msisdn: bind.Msisdn,
|
|
DeptId: bind.DeptId,
|
|
PackageType: bind.PackageType,
|
|
PackageCode: bind.PackageCode,
|
|
PreviousPackageCode: bind.PreviousPackageCode,
|
|
BusinessType: bind.BusinessType,
|
|
EffectiveStatus: consts.EffectiveStatusVoided,
|
|
HandleTime: bind.HandleTime,
|
|
EffectiveTime: bind.EffectiveTime,
|
|
ExpectedExpireTime: bind.ExpectedExpireTime,
|
|
ActualExpireTime: actualExpireAt,
|
|
DurationMonths: bind.DurationMonths,
|
|
GiftDurationMonths: bind.GiftDurationMonths,
|
|
OrderCode: bind.OrderCode,
|
|
Remark: appendRemark(bind.Remark, fmt.Sprintf("changeBatchNo=%s", changeBatchNo)),
|
|
TenantId: bind.TenantId,
|
|
CreatedDept: bind.CreatedDept,
|
|
CreatedBy: bind.CreatedBy,
|
|
CreatedAt: bind.CreatedAt,
|
|
UpdatedBy: userId,
|
|
UpdatedAt: actualExpireAt,
|
|
}
|
|
}
|
|
|
|
func (p *Processor) updateOrdersAfterChangeVoid(ctx context.Context, tx gdb.TX, orderCodes []string, voidCounts map[string]int, batchNo string, voidTime *gtime.Time, userId int64) error {
|
|
if len(orderCodes) == 0 {
|
|
return nil
|
|
}
|
|
activeCounts, err := p.repo.ActiveBindCountsByOrderCodes(ctx, tx, orderCodes)
|
|
if err != nil {
|
|
return gerror.Wrap(err, "count active binds by order failed")
|
|
}
|
|
for _, orderCode := range orderCodes {
|
|
returnStatus := consts.OrderReturnStatusSuccess
|
|
if activeCounts[orderCode] > 0 {
|
|
returnStatus = consts.OrderReturnStatusPartial
|
|
}
|
|
if _, err = tx.Ctx(ctx).Model(dao.TOrder.Table()).
|
|
Where(dao.TOrder.Columns().OrderSn, orderCode).
|
|
Data(do.TOrder{
|
|
ReturnStatus: returnStatus,
|
|
UpdatedBy: userId,
|
|
UpdatedAt: voidTime,
|
|
}).
|
|
Update(); err != nil {
|
|
return gerror.Wrap(err, "update order return status failed")
|
|
}
|
|
if err = updateOrderItemChangeExtra(ctx, tx, orderCode, batchNo, voidCounts[orderCode], voidTime, userId); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func updateOrderItemChangeExtra(ctx context.Context, tx gdb.TX, orderCode, batchNo string, voidQuantity int, voidTime *gtime.Time, userId int64) error {
|
|
var item *entity.TOrderItem
|
|
if err := tx.Ctx(ctx).Model(dao.TOrderItem.Table()).
|
|
Where(dao.TOrderItem.Columns().OrderSn, orderCode).
|
|
Limit(1).
|
|
Scan(&item); err != nil {
|
|
return gerror.Wrap(err, "load order item failed")
|
|
}
|
|
if item == nil {
|
|
return nil
|
|
}
|
|
|
|
extra := g.Map{}
|
|
if strings.TrimSpace(item.ExtraSkuData) != "" {
|
|
_ = json.Unmarshal([]byte(item.ExtraSkuData), &extra)
|
|
}
|
|
extra["lastChangeBatchNo"] = batchNo
|
|
extra["lastChangeTime"] = formatTime(voidTime)
|
|
extra["voidedByChangeQuantity"] = voidQuantity
|
|
|
|
data, err := json.Marshal(extra)
|
|
if err != nil {
|
|
return gerror.Wrap(err, "marshal order item extra failed")
|
|
}
|
|
if _, err = tx.Ctx(ctx).Model(dao.TOrderItem.Table()).
|
|
Where(dao.TOrderItem.Columns().ItemId, item.ItemId).
|
|
Data(do.TOrderItem{
|
|
ExtraSkuData: string(data),
|
|
UpdatedBy: userId,
|
|
UpdatedAt: voidTime,
|
|
}).
|
|
Update(); err != nil {
|
|
return gerror.Wrap(err, "update order item extra failed")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *Processor) updateCardsAfterChange(ctx context.Context, tx gdb.TX, iccids []string, cardsByIccid map[string]*entity.TSimCardInfo, subscribe *cardpackage.CreatePackageSubscriptionOutput, userId int64) error {
|
|
if subscribe == nil || subscribe.Package == nil {
|
|
return gerror.New("change subscription output is empty")
|
|
}
|
|
now := gtime.Now()
|
|
columns := dao.TSimCardInfo.Columns()
|
|
for _, iccid := range iccids {
|
|
card := cardsByIccid[iccid]
|
|
if card == nil {
|
|
return gerror.Newf("ICCID card info not found: %s", iccid)
|
|
}
|
|
result, err := tx.Ctx(ctx).Model(dao.TSimCardInfo.Table()).
|
|
Where(columns.Iccid, iccid).
|
|
Data(g.Map{
|
|
columns.CurrentPackageCode: subscribe.Package.PackageCode,
|
|
columns.PackageStatus: subscribe.PackageStatus,
|
|
columns.FlowPkgBeginAt: subscribe.PackageBeginAt,
|
|
columns.FlowPkgPresentAt: nil,
|
|
columns.FlowPkgRealPresentAt: nil,
|
|
columns.FlowPkgEndAt: subscribe.PackageEndAt,
|
|
columns.DataServiceStatus: 1,
|
|
columns.PackageTotalFlowMb: subscribe.Package.FlowMb,
|
|
columns.UsedFlowMb: 0,
|
|
columns.TrafficCutoffStatus: 0,
|
|
columns.TrafficCutoffThreshold: 0,
|
|
columns.SmsServiceStatus: 0,
|
|
columns.PackageTotalSms: 0,
|
|
columns.UsedSms: 0,
|
|
columns.VoiceServiceStatus: 0,
|
|
columns.PackageTotalVoice: 0,
|
|
columns.UsedVoice: 0,
|
|
columns.RoamServiceStatus: 0,
|
|
columns.PackageTotalRoamFlowMb: 0,
|
|
columns.UsedRoamFlowMb: 0,
|
|
columns.UpdatedBy: userId,
|
|
columns.UpdatedAt: now,
|
|
}).
|
|
Update()
|
|
if err != nil {
|
|
return gerror.Wrap(err, "update card after change failed")
|
|
}
|
|
affected, err := result.RowsAffected()
|
|
if err != nil {
|
|
return gerror.Wrap(err, "get updated card count failed")
|
|
}
|
|
if affected != 1 {
|
|
return gerror.Newf("ICCID card changed concurrently, retry: %s", iccid)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func updateBatchDetailSnapshots(ctx context.Context, tx gdb.TX, batchNo string, snapshots map[string]any, userId int64) error {
|
|
for iccid, snapshot := range snapshots {
|
|
_, err := tx.Ctx(ctx).Model(dao.BatchDetail.Table()).
|
|
Where(dao.BatchDetail.Columns().BatchNo, batchNo).
|
|
Where(dao.BatchDetail.Columns().ItemId, iccid).
|
|
Data(do.BatchDetail{
|
|
Snapshot: gjson.New(snapshot),
|
|
UpdatedBy: userId,
|
|
UpdatedAt: gtime.Now(),
|
|
}).
|
|
Update()
|
|
if err != nil {
|
|
return gerror.Wrap(err, "update change batch detail snapshot failed")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func convertBatchDetailsAfterComplete(ctx context.Context, tx gdb.TX, batchNo string, userId int64) error {
|
|
_, err := tx.Ctx(ctx).Model(dao.BatchDetail.Table()).
|
|
Where(dao.BatchDetail.Columns().BatchNo, batchNo).
|
|
Where(dao.BatchDetail.Columns().BatchType, consts.BatchTypePrepare).
|
|
Data(do.BatchDetail{
|
|
BatchType: consts.BatchTypeChange,
|
|
UpdatedBy: userId,
|
|
UpdatedAt: gtime.Now(),
|
|
}).
|
|
Update()
|
|
if err != nil {
|
|
return gerror.Wrap(err, "update change batch detail type failed")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func updateBatchMainAfterComplete(ctx context.Context, tx gdb.TX, in *CompleteInput, output *CompleteOutput) error {
|
|
info := g.Map{
|
|
"sourceMode": output.SourceMode,
|
|
"orderSn": output.OrderSn,
|
|
"customerAgentId": output.CustomerAgentId,
|
|
"customerName": output.CustomerName,
|
|
"oldPackageCode": output.OldPackageCode,
|
|
"oldPackageName": output.OldPackageName,
|
|
"newPackageCode": output.NewPackageCode,
|
|
"newPackageName": output.NewPackageName,
|
|
"durationMonths": output.DurationMonths,
|
|
"giftDurationMonths": output.GiftDurationMonths,
|
|
"effectiveMode": output.EffectiveMode,
|
|
"changeUnitPrice": output.ChangeUnitPrice,
|
|
"amount": output.Amount,
|
|
"quantity": output.Quantity,
|
|
"packageBeginTime": output.PackageBeginTime,
|
|
"packageEndTime": output.PackageEndTime,
|
|
"offlineContractCompleted": output.OfflineContractCompleted,
|
|
"changeTime": output.ChangeTime,
|
|
}
|
|
if output.SourceBatchNo != "" {
|
|
info["sourceBatchNo"] = output.SourceBatchNo
|
|
}
|
|
if in.PriceSnapshot != nil {
|
|
info["priceSource"] = in.PriceSnapshot.PriceSource
|
|
info["agentDefaultPriceId"] = in.PriceSnapshot.AgentDefaultPriceId
|
|
info["targetPriceId"] = in.PriceSnapshot.TargetPriceId
|
|
info["renewableDurationOptions"] = in.PriceSnapshot.RenewableDurationOptions
|
|
}
|
|
if buyerNote := strings.TrimSpace(in.SubmitParam.BuyerNote); buyerNote != "" {
|
|
info["buyerNote"] = buyerNote
|
|
}
|
|
if adminNote := strings.TrimSpace(in.SubmitParam.AdminNote); adminNote != "" {
|
|
info["adminNote"] = adminNote
|
|
}
|
|
if remark := strings.TrimSpace(in.SubmitParam.Remark); remark != "" {
|
|
info["remark"] = remark
|
|
}
|
|
_, err := tx.Ctx(ctx).Model(dao.BatchMain.Table()).
|
|
Where(dao.BatchMain.Columns().BatchNo, in.BatchNo).
|
|
Data(do.BatchMain{
|
|
BatchType: consts.BatchTypeChange,
|
|
OrderSn: output.OrderSn,
|
|
TargetDeptId: output.CustomerAgentId,
|
|
BatchInfo: gjson.New(info),
|
|
UpdatedBy: in.Operator.UserId,
|
|
UpdatedAt: output.ChangeTime,
|
|
}).
|
|
Update()
|
|
if err != nil {
|
|
return gerror.Wrap(err, "update change batch failed")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func buildDetailSnapshot(row *Row, card *entity.TSimCardInfo, oldBind, newBind *entity.TSimCardBindPkg, voidedSubscriptionNos []string, in *CompleteInput, termination *cardpackage.TerminateCurrentPackageOutput, subscribe *cardpackage.CreatePackageSubscriptionOutput) g.Map {
|
|
data := g.Map{
|
|
"ICCID": row.Iccid,
|
|
"MSISDN": row.Msisdn,
|
|
"IMSI": row.Imsi,
|
|
"sourceMode": sourceMode(in.SourceBatchNo),
|
|
"changeBatchNo": in.BatchNo,
|
|
"oldPackageCode": termination.PackageCode,
|
|
"newPackageCode": subscribe.Package.PackageCode,
|
|
"newPackageName": subscribe.Package.PackageName,
|
|
"voidedSubscriptionNos": voidedSubscriptionNos,
|
|
"durationMonths": in.SubmitParam.DurationMonths,
|
|
"giftDurationMonths": in.SubmitParam.GiftDurationMonths,
|
|
"effectiveMode": strings.TrimSpace(in.SubmitParam.EffectiveMode),
|
|
"offlineContractCompleted": in.SubmitParam.OfflineContractCompleted,
|
|
"changeUnitPrice": in.PriceSnapshot.ChangeUnitPrice,
|
|
"amount": roundAmount(in.PriceSnapshot.ChangeUnitPrice * float64(in.SubmitParam.DurationMonths)),
|
|
"newEffectiveTime": formatTime(subscribe.PackageBeginAt),
|
|
"newExpectedExpireTime": formatTime(subscribe.PackageEndAt),
|
|
"oldActualExpireTime": formatTime(termination.UnsubTime),
|
|
"rowNo": row.RowNo,
|
|
"rawFields": row.RawFields,
|
|
}
|
|
if strings.TrimSpace(in.SourceBatchNo) != "" {
|
|
data["sourceBatchNo"] = strings.TrimSpace(in.SourceBatchNo)
|
|
}
|
|
if card != nil {
|
|
data["ICCID"] = card.Iccid
|
|
data["MSISDN"] = card.Msisdn
|
|
data["IMSI"] = card.Imsi
|
|
}
|
|
if in.PrepareSnapshot != nil {
|
|
data["oldPackageName"] = in.PrepareSnapshot.OldPackageName
|
|
}
|
|
if oldBind != nil {
|
|
data["oldSubscriptionNo"] = oldBind.SubscriptionNo
|
|
data["oldOrderSn"] = oldBind.OrderCode
|
|
data["oldEffectiveTime"] = formatTime(oldBind.EffectiveTime)
|
|
data["oldExpectedExpireTime"] = formatTime(oldBind.ExpectedExpireTime)
|
|
}
|
|
if newBind != nil {
|
|
data["newSubscriptionNo"] = newBind.SubscriptionNo
|
|
data["newOrderSn"] = newBind.OrderCode
|
|
}
|
|
return data
|
|
}
|
|
|
|
func appendRemark(old, addition string) string {
|
|
old = strings.TrimSpace(old)
|
|
addition = strings.TrimSpace(addition)
|
|
if old == "" {
|
|
return addition
|
|
}
|
|
if addition == "" {
|
|
return old
|
|
}
|
|
return old + "; " + addition
|
|
}
|
|
|
|
func mapKeys(set map[string]struct{}) []string {
|
|
result := make([]string, 0, len(set))
|
|
for key := range set {
|
|
if strings.TrimSpace(key) != "" {
|
|
result = append(result, key)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func roundAmount(value float64) float64 {
|
|
if value < 0 {
|
|
return 0
|
|
}
|
|
return float64(int(value*100+0.5)) / 100
|
|
}
|
|
|
|
func sourceMode(sourceBatchNo string) int {
|
|
if strings.TrimSpace(sourceBatchNo) != "" {
|
|
return consts.BatchSourceTypeBatchSelect
|
|
}
|
|
return 0
|
|
}
|