From 1c4697ecb2ab1e7df9ecb35bb1ba68cbb2f30e0a Mon Sep 17 00:00:00 2001 From: rouggy Date: Sun, 23 Aug 2026 18:30:10 +0200 Subject: [PATCH] feat(awards): match on CNTY as it stands, not only keyed to a US state The award field list offered us_county, which returns STATE,County -- correct for the United States, where Jefferson County exists in several states, and wrong for every award whose district is already unique. An RDA reference (RO-19) never matched, and there was no other field to point an award at. Adds county, the raw CNTY value, alongside it. --- changelog.json | 6 +++-- internal/award/award.go | 9 +++++++- internal/award/fieldvalue_county_test.go | 29 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 internal/award/fieldvalue_county_test.go diff --git a/changelog.json b/changelog.json index 4b44efb..d89b1cc 100644 --- a/changelog.json +++ b/changelog.json @@ -8,7 +8,8 @@ "QSL Manager: HAMLOG.online gains 'Import confirmations (ADIF)…'. Their site exports a log, this reads it back and stamps the confirmations on QSOs already present — it never inserts. Importing that same file through the ordinary ADIF import does insert, because it matches on the UTC minute and their export rarely agrees to the minute.", "Deleting QSOs now says how many rows were actually removed, and writes it to the log. A delete that removes nothing used to look exactly like one that worked.", "Deleting QSOs is fast again when 'delete from the remote services' is on. Club Log is only asked about contacts that were actually uploaded to it — asking about the others earned a 403 each time, one network round trip per QSO — the withdrawals now run in the background instead of holding the window, the rows behind a selection are read in one query rather than one per QSO, and repeated refusals stop the run rather than earning a longer block.", - "The HAMLOG.online confirmation import now fills the Results view with the contacts it confirmed, flagged new entity / band / mode / slot, and can export the unmatched ones as ADIF. Those are the interesting half: each is a contact their site holds and the log does not confirm — a minute of drift, a portable call, or a QSO genuinely missing." + "The HAMLOG.online confirmation import now fills the Results view with the contacts it confirmed, flagged new entity / band / mode / slot, and can export the unmatched ones as ADIF. Those are the interesting half: each is a contact their site holds and the log does not confirm — a minute of drift, a portable call, or a QSO genuinely missing.", + "Awards: 'county' joins the searchable QSO fields — the CNTY field as it stands. The existing 'us_county' keys the county to its state, which is right for the United States and wrong everywhere else: an RDA district or a Japanese city code is already unique." ], "fr": [ "Édition de QSO : HAMLOG.online rejoint l'onglet QSL Info — son propre canal dans la liste, avec envoyé/reçu et les deux dates, et une ligne dans le tableau de statut. Ses quatre colonnes passent aussi du groupe QSL au groupe Uploads, à côté de Club Log et QRZ.com.", @@ -16,7 +17,8 @@ "Gestionnaire QSL : HAMLOG.online reçoit « Importer les confirmations (ADIF)… ». Leur site exporte un log, cette fonction le relit et appose les confirmations sur les QSO déjà présents — elle n'ajoute jamais rien. Le même fichier passé par l'import ADIF ordinaire, lui, ajoute : il compare à la minute UTC près et leur export s'accorde rarement à la minute.", "La suppression de QSO indique maintenant combien de lignes ont réellement été supprimées, et l'écrit dans le journal. Une suppression sans effet ressemblait exactement à une suppression réussie.", "La suppression de QSO redevient rapide quand « supprimer aussi des services externes » est activé. Club Log n'est plus interrogé que pour les contacts qui y ont réellement été envoyés — pour les autres il répondait 403, un aller-retour réseau par QSO — les retraits se font désormais en arrière-plan au lieu de bloquer la fenêtre, les lignes d'une sélection sont lues en une seule requête au lieu d'une par QSO, et une série de refus interrompt le traitement au lieu d'aggraver le blocage.", - "L'import des confirmations HAMLOG.online alimente maintenant la vue Résultats avec les contacts confirmés, marqués nouvelle entité / bande / mode / slot, et peut exporter les non-rapprochés en ADIF. C'est la moitié intéressante : chacun est un contact que leur site détient et que le journal ne confirme pas — minute décalée, indicatif portable, ou QSO réellement absent." + "L'import des confirmations HAMLOG.online alimente maintenant la vue Résultats avec les contacts confirmés, marqués nouvelle entité / bande / mode / slot, et peut exporter les non-rapprochés en ADIF. C'est la moitié intéressante : chacun est un contact que leur site détient et que le journal ne confirme pas — minute décalée, indicatif portable, ou QSO réellement absent.", + "Diplômes : « county » rejoint les champs de QSO interrogeables — le champ CNTY tel quel. Le « us_county » existant associe le comté à son État, ce qui est juste aux États-Unis et faux ailleurs : un district RDA ou un code de ville japonais est déjà unique." ] }, { diff --git a/internal/award/award.go b/internal/award/award.go index 5bb0db0..f84ddfa 100644 --- a/internal/award/award.go +++ b/internal/award/award.go @@ -344,7 +344,7 @@ func Migrate(defs []Def) ([]Def, bool) { func Fields() []string { return []string{ "dxcc", "cqz", "ituz", "prefix", "callsign", - "state", "us_county", "cont", "country", "grid", "grid4", + "state", "county", "us_county", "cont", "country", "grid", "grid4", "iota", "sota_ref", "pota_ref", "wwff", "name", "qth", "address", "comment", "note", } @@ -1373,6 +1373,13 @@ func fieldRaw(field string, q *qso.QSO) string { return q.Callsign case "state": return q.State + case "county": + // CNTY as it stands, with nothing prepended. us_county below answers a + // different question — it keys the county to its state, because two US + // states each have a Jefferson County. Outside the United States that + // prefixing is wrong: an RDA district (RO-19) and a Japanese city code + // are already unique, and a state is not what qualifies them. + return q.County case "us_county": return USCountyKey(q.State, q.County) case "cont": diff --git a/internal/award/fieldvalue_county_test.go b/internal/award/fieldvalue_county_test.go new file mode 100644 index 0000000..6cf1b09 --- /dev/null +++ b/internal/award/fieldvalue_county_test.go @@ -0,0 +1,29 @@ +package award + +import ( + "testing" + + "hamlog/internal/qso" +) + +// A district lives in CNTY as-is; the US award field keys it to the state +// because county names repeat across states. Confusing the two silently breaks +// whichever award is not American. +func TestCountyFieldIsRawWhileUSCountyIsKeyed(t *testing.T) { + q := &qso.QSO{State: "TX", County: "RO-19"} + if got := fieldRaw("county", q); got != "RO-19" { + t.Fatalf("county = %q, want RO-19", got) + } + if got := fieldRaw("us_county", q); got == "RO-19" { + t.Fatalf("us_county should key the county to its state, got %q", got) + } + var found bool + for _, f := range Fields() { + if f == "county" { + found = true + } + } + if !found { + t.Fatal("county missing from the award field list") + } +}