fixed duplicated ISO codes parsing
This commit is contained in:
@@ -19,6 +19,10 @@ market:
|
||||
quote: "EUR"
|
||||
symbol: "EURUSDT"
|
||||
invert: true
|
||||
- base: "USD"
|
||||
quote: "USDT"
|
||||
symbol: "USDTUSD"
|
||||
invert: true
|
||||
- base: "UAH"
|
||||
quote: "USDT"
|
||||
symbol: "USDTUAH"
|
||||
|
||||
@@ -412,26 +412,84 @@ func buildValuteMapping(logger *zap.Logger, items []valuteItem) (*valuteMapping,
|
||||
isoNum := strings.TrimSpace(item.ISONum)
|
||||
name := strings.TrimSpace(item.Name)
|
||||
engName := strings.TrimSpace(item.EngName)
|
||||
|
||||
nominal, err := parseNominal(item.NominalStr)
|
||||
if err != nil {
|
||||
return nil, merrors.InvalidDataType("cbr: parse directory nominal: " + err.Error())
|
||||
}
|
||||
if id != "" && isoChar != "" {
|
||||
info := valuteInfo{
|
||||
ID: id,
|
||||
ISOCharCode: isoChar,
|
||||
ISONumCode: isoNum,
|
||||
Name: name,
|
||||
EngName: engName,
|
||||
Nominal: nominal,
|
||||
|
||||
if id == "" || isoChar == "" {
|
||||
logger.Info("Skipping invalid currency entry",
|
||||
zap.String("id", id),
|
||||
zap.String("iso_char", isoChar),
|
||||
zap.String("name", name),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
info := valuteInfo{
|
||||
ID: id,
|
||||
ISOCharCode: isoChar,
|
||||
ISONumCode: isoNum,
|
||||
Name: name,
|
||||
EngName: engName,
|
||||
Nominal: nominal,
|
||||
}
|
||||
|
||||
// Handle duplicate ISO char codes (e.g. DEM with different IDs / nominals).
|
||||
if existing, ok := byISO[isoChar]; ok {
|
||||
// Same ISO + same ID: duplicate entry, just ignore.
|
||||
if existing.ID == id {
|
||||
logger.Debug("Duplicate directory entry for same ISO and ID, ignoring",
|
||||
zap.String("iso_code", isoChar),
|
||||
zap.String("id", id),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
if existing, ok := byISO[isoChar]; ok && existing.ID != id {
|
||||
return nil, merrors.InvalidDataType("cbr: duplicate ISO code " + isoChar)
|
||||
// Different IDs but same ISO char.
|
||||
// Choose canonical entry:
|
||||
// 1) Prefer nominal == 1
|
||||
// 2) Otherwise prefer smaller nominal
|
||||
keepExisting := true
|
||||
|
||||
if existing.Nominal != 1 && info.Nominal == 1 {
|
||||
keepExisting = false
|
||||
} else if existing.Nominal == 1 && info.Nominal != 1 {
|
||||
keepExisting = true
|
||||
} else if info.Nominal < existing.Nominal {
|
||||
keepExisting = false
|
||||
}
|
||||
if existing, ok := byID[id]; ok && existing.ISOCharCode != isoChar {
|
||||
return nil, merrors.InvalidDataType("cbr: duplicate valute id " + id)
|
||||
|
||||
if keepExisting {
|
||||
logger.Warn("Ignoring duplicate ISO currency entry with less preferred nominal",
|
||||
zap.String("iso_code", isoChar),
|
||||
zap.String("existing_id", existing.ID),
|
||||
zap.Int64("existing_nominal", existing.Nominal),
|
||||
zap.String("new_id", info.ID),
|
||||
zap.Int64("new_nominal", info.Nominal),
|
||||
)
|
||||
// We keep the old one, just skip the new.
|
||||
continue
|
||||
}
|
||||
|
||||
// Replace existing mapping with the new, more canonical one.
|
||||
logger.Warn("Replacing currency mapping due to more canonical nominal",
|
||||
zap.String("iso_code", isoChar),
|
||||
zap.String("old_id", existing.ID),
|
||||
zap.Int64("old_nominal", existing.Nominal),
|
||||
zap.String("new_id", info.ID),
|
||||
zap.Int64("new_nominal", info.Nominal),
|
||||
)
|
||||
|
||||
// Update byID: drop old ID, add new one
|
||||
delete(byID, existing.ID)
|
||||
byID[id] = info
|
||||
|
||||
// Update ISO mapping
|
||||
byISO[isoChar] = info
|
||||
|
||||
// Update numeric-code index if present
|
||||
if isoNum != "" {
|
||||
if existingID, ok := byNum[isoNum]; ok && existingID != id {
|
||||
return nil, merrors.InvalidDataType("cbr: duplicate ISO numeric code " + isoNum)
|
||||
@@ -439,12 +497,26 @@ func buildValuteMapping(logger *zap.Logger, items []valuteItem) (*valuteMapping,
|
||||
byNum[isoNum] = id
|
||||
}
|
||||
|
||||
logger.Info("Installing currency code", zap.String("iso_code", isoChar), zap.String("id", id))
|
||||
byISO[isoChar] = info
|
||||
byID[id] = info
|
||||
} else {
|
||||
logger.Info("Skipping invalid currency entry", zap.String("id", id), zap.String("iso_char", isoChar))
|
||||
continue
|
||||
}
|
||||
|
||||
// No existing ISO entry, do normal uniqueness checks.
|
||||
|
||||
if existing, ok := byID[id]; ok && existing.ISOCharCode != isoChar {
|
||||
return nil, merrors.InvalidDataType("cbr: duplicate valute id " + id)
|
||||
}
|
||||
|
||||
if isoNum != "" {
|
||||
if existingID, ok := byNum[isoNum]; ok && existingID != id {
|
||||
return nil, merrors.InvalidDataType("cbr: duplicate ISO numeric code " + isoNum)
|
||||
}
|
||||
byNum[isoNum] = id
|
||||
}
|
||||
|
||||
logger.Info("Installing currency code", zap.String("iso_code", isoChar), zap.String("id", id), zap.Int64("nominal", nominal))
|
||||
|
||||
byISO[isoChar] = info
|
||||
byID[id] = info
|
||||
}
|
||||
|
||||
if len(byISO) == 0 {
|
||||
|
||||
Reference in New Issue
Block a user