179 lines
4.6 KiB
Go
179 lines
4.6 KiB
Go
package outbound
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
func validateRows(ctx context.Context, rows []*Row, opts PreviewOptions, repo *Repository) error {
|
|
identityFirstRow := make(map[string]*Row, len(rows))
|
|
iccids := make([]string, 0, len(rows))
|
|
msisdns := make([]string, 0, len(rows))
|
|
imsis := make([]string, 0, len(rows))
|
|
for _, row := range rows {
|
|
row.Iccid = strings.TrimSpace(row.Iccid)
|
|
row.Msisdn = strings.TrimSpace(row.Msisdn)
|
|
row.Imsi = strings.TrimSpace(row.Imsi)
|
|
row.RangeCodeType = rowIdentityCodeType(row)
|
|
key := rowIdentityKey(row)
|
|
if key == "" {
|
|
row.AddReason(rowIdentityLabel(row.RangeCodeType) + "不能为空")
|
|
continue
|
|
}
|
|
identityKey := row.RangeCodeType + ":" + key
|
|
if firstRow, ok := identityFirstRow[identityKey]; ok {
|
|
label := rowIdentityLabel(row.RangeCodeType)
|
|
row.AddReason(fmt.Sprintf("%s与第%d行重复", label, firstRow.RowNo))
|
|
firstRow.AddReason(fmt.Sprintf("%s与第%d行重复", label, row.RowNo))
|
|
continue
|
|
}
|
|
identityFirstRow[identityKey] = row
|
|
switch row.RangeCodeType {
|
|
case "msisdn":
|
|
msisdns = append(msisdns, key)
|
|
case "imsi":
|
|
imsis = append(imsis, key)
|
|
default:
|
|
iccids = append(iccids, key)
|
|
}
|
|
}
|
|
|
|
stockByIccid, err := repo.GetStockCardsByIccids(ctx, iccids)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
stockByMsisdn, err := repo.GetStockCardsByMsisdns(ctx, msisdns)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
stockByImsi, err := repo.GetStockCardsByImsis(ctx, imsis)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
rowStock := make(map[*Row]*StockCard, len(rows))
|
|
resolvedIccidFirstRow := make(map[string]*Row, len(rows))
|
|
resolvedIccids := make([]string, 0, len(rows))
|
|
|
|
for _, row := range rows {
|
|
if !row.Valid() {
|
|
continue
|
|
}
|
|
stock := stockForRow(row, stockByIccid, stockByMsisdn, stockByImsi)
|
|
if stock == nil {
|
|
row.AddReason(rowIdentityLabel(row.RangeCodeType) + "不存在库存记录")
|
|
continue
|
|
}
|
|
providedIccid := row.Iccid
|
|
providedMsisdn := row.Msisdn
|
|
providedImsi := row.Imsi
|
|
row.Iccid = strings.TrimSpace(stock.Iccid)
|
|
row.Msisdn = chooseString(row.Msisdn, stock.Msisdn)
|
|
row.Imsi = chooseString(row.Imsi, stock.Imsi)
|
|
if row.Iccid == "" {
|
|
row.AddReason("库存卡ICCID为空")
|
|
continue
|
|
}
|
|
if firstRow, ok := resolvedIccidFirstRow[row.Iccid]; ok {
|
|
row.AddReason(fmt.Sprintf("ICCID与第%d行指向同一库存卡", firstRow.RowNo))
|
|
firstRow.AddReason(fmt.Sprintf("ICCID与第%d行指向同一库存卡", row.RowNo))
|
|
continue
|
|
}
|
|
resolvedIccidFirstRow[row.Iccid] = row
|
|
if stock.CreatedDept != opts.DeptId {
|
|
row.AddReason("ICCID不属于当前机构库存")
|
|
continue
|
|
}
|
|
if opts.StrictStockIdentity {
|
|
if providedIccid != "" && providedIccid != strings.TrimSpace(stock.Iccid) {
|
|
row.AddReason("ICCID与库存记录不一致")
|
|
continue
|
|
}
|
|
if providedMsisdn != "" && providedMsisdn != strings.TrimSpace(stock.Msisdn) {
|
|
row.AddReason("MSISDN与库存记录不一致")
|
|
continue
|
|
}
|
|
if providedImsi != "" && providedImsi != strings.TrimSpace(stock.Imsi) {
|
|
row.AddReason("IMSI与库存记录不一致")
|
|
continue
|
|
}
|
|
}
|
|
row.SourceBatchNo = strings.TrimSpace(stock.BatchNo)
|
|
rowStock[row] = stock
|
|
resolvedIccids = append(resolvedIccids, row.Iccid)
|
|
}
|
|
|
|
formalByIccid, err := repo.GetExistingFormalIccids(ctx, resolvedIccids)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, row := range rows {
|
|
if !row.Valid() || rowStock[row] == nil {
|
|
continue
|
|
}
|
|
if formalByIccid[row.Iccid] {
|
|
row.AddReason("ICCID已存在正式卡记录")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func rowIdentityCodeType(row *Row) string {
|
|
if row == nil {
|
|
return "iccid"
|
|
}
|
|
if codeType := normalizeRangeCodeType(row.RangeCodeType); codeType != "" {
|
|
return codeType
|
|
}
|
|
switch {
|
|
case strings.TrimSpace(row.Iccid) != "":
|
|
return "iccid"
|
|
case strings.TrimSpace(row.Msisdn) != "":
|
|
return "msisdn"
|
|
case strings.TrimSpace(row.Imsi) != "":
|
|
return "imsi"
|
|
default:
|
|
return "iccid"
|
|
}
|
|
}
|
|
|
|
func rowIdentityKey(row *Row) string {
|
|
if row == nil {
|
|
return ""
|
|
}
|
|
switch row.RangeCodeType {
|
|
case "msisdn":
|
|
return strings.TrimSpace(row.Msisdn)
|
|
case "imsi":
|
|
return strings.TrimSpace(row.Imsi)
|
|
default:
|
|
return strings.TrimSpace(row.Iccid)
|
|
}
|
|
}
|
|
|
|
func rowIdentityLabel(codeType string) string {
|
|
switch codeType {
|
|
case "msisdn":
|
|
return "MSISDN"
|
|
case "imsi":
|
|
return "IMSI"
|
|
default:
|
|
return "ICCID"
|
|
}
|
|
}
|
|
|
|
func stockForRow(row *Row, stockByIccid, stockByMsisdn, stockByImsi map[string]*StockCard) *StockCard {
|
|
if row == nil {
|
|
return nil
|
|
}
|
|
switch row.RangeCodeType {
|
|
case "msisdn":
|
|
return stockByMsisdn[strings.TrimSpace(row.Msisdn)]
|
|
case "imsi":
|
|
return stockByImsi[strings.TrimSpace(row.Imsi)]
|
|
default:
|
|
return stockByIccid[strings.TrimSpace(row.Iccid)]
|
|
}
|
|
}
|