fix: a tag may not accuse on weak evidence, nor name a distant product
Three findings from the deep review, all about the tag channel claiming more than it can support. 1. The exact signal is a barcode. The reconciliation compared `tag.jan` against the catalog's JAN, but that field held the regular price - a number compared against a product code. It now reads a `barcode` field (populated only by a close-up decode) and the printed number is compared as a price. 2. A price-mismatch violation required "an anchor", which was `tag.jan` - a price. The anchor is now the tag's own arithmetic agreeing, or a name that actually resembles the product, and the name signal carries its score as a field instead of being parsed back out of a human-readable note string. 3. Tag identity could reach anywhere along a row: a facing whose own tag was not detected inherited whichever readable tag was nearest, which can be a different product several columns away. Assignment is now capped at the product's own run (2.5 facing widths, at least 200 px), and a tag may only overrule the packaging channel when it is corroborated or its name matches at 0.6 rather than 0.4. 162 tests pass. Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
3a960b1471
commit
99bce4d7bf
3 changed files with 86 additions and 21 deletions
|
|
@ -50,6 +50,8 @@ def tag(state=TAG_STATE_READABLE, **overrides):
|
|||
"price": None,
|
||||
"regular_price": None,
|
||||
"name": None,
|
||||
"barcode": None,
|
||||
"flags": [],
|
||||
"confidence": 0.8,
|
||||
"observations": 3,
|
||||
"settled": True,
|
||||
|
|
@ -96,12 +98,14 @@ class ReconcileTests(unittest.TestCase):
|
|||
result = reconcile(accepted(), tag(name="Tropicana エッセンシャルズ"), product(price=None, name="Tropicana エッセンシャルズ マルチビタミン"))
|
||||
self.assertEqual(result["state"], RECONCILED_CONFIRMED)
|
||||
|
||||
def test_jan_disagreement_is_a_mismatch(self):
|
||||
result = reconcile(accepted(), tag(price=168, jan="4902105000001"), product(price=168.0, jan="4902105000002"))
|
||||
def test_barcode_disagreement_is_a_mismatch(self):
|
||||
result = reconcile(accepted(), tag(price=168, barcode="4902105000001"),
|
||||
product(price=168.0, jan="4902105000002"))
|
||||
self.assertEqual(result["state"], RECONCILED_MISMATCH)
|
||||
|
||||
def test_jan_agreement_confirms(self):
|
||||
result = reconcile(accepted(), tag(price=None, jan="4902105000001"), product(price=None, jan="4902105000001"))
|
||||
def test_barcode_agreement_confirms(self):
|
||||
result = reconcile(accepted(), tag(price=None, barcode="4902105000001"),
|
||||
product(price=None, jan="4902105000001"))
|
||||
self.assertEqual(result["state"], RECONCILED_CONFIRMED)
|
||||
|
||||
def test_tag_read_but_nothing_comparable(self):
|
||||
|
|
@ -284,7 +288,8 @@ class ComplianceTests(unittest.TestCase):
|
|||
# A reportable mismatch carries an anchor: the tag's JAN was read, so we
|
||||
# know which tag we are comparing.
|
||||
tracks = [track(1, [10, 100, 90, 300])]
|
||||
tags = {1: tag(state=TAG_STATE_READABLE, price=269, jan="357")}
|
||||
# The anchor is the tag's own arithmetic agreeing, not a price field.
|
||||
tags = {1: tag(state=TAG_STATE_READABLE, price=269, flags=["tax_consistent"])}
|
||||
reconciliations = {1: reconcile(accepted(), tags[1], product(price=168.0))}
|
||||
findings = evaluate_compliance(tracks, tags, [tags[1]], BANDS, reconciliations)
|
||||
mismatches = [finding for finding in findings if finding.rule == RULE_PRICE_MISMATCH]
|
||||
|
|
@ -308,8 +313,8 @@ class ComplianceTests(unittest.TestCase):
|
|||
findings = [
|
||||
evaluate_compliance(
|
||||
[track(1, [10, 100, 90, 300])],
|
||||
{1: tag(state=TAG_STATE_READABLE, price=269, jan="357")},
|
||||
[tag(state=TAG_STATE_READABLE, price=269, jan="357")],
|
||||
{1: tag(state=TAG_STATE_READABLE, price=269, flags=["tax_consistent"])},
|
||||
[tag(state=TAG_STATE_READABLE, price=269, flags=["tax_consistent"])],
|
||||
BANDS,
|
||||
{1: reconcile(accepted(), tag(price=269), product(price=168.0))},
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue