joycecast commited on
Commit
350560b
·
verified ·
1 Parent(s): 5691587

Upload hts_validator.py

Browse files
Files changed (1) hide show
  1. hts_validator.py +74 -8
hts_validator.py CHANGED
@@ -25,11 +25,13 @@ SCENARIO_SUMMARIES = {
25
  "S7": "Dual Steel+Aluminum HTS - matches keyword, apply corresponding 232, no 99030125",
26
  "S7a": "Dual Steel+Aluminum HTS + BOTH keywords - flag for manual review",
27
  "S8": "Dual Steel+Aluminum HTS + NO keywords - flag for manual review",
28
- "S9": "Copper keyword but NOT copper HTS - potential misclassification",
29
  "S11": "Dual Aluminum+Copper HTS + copper keyword - apply 99030133 + copper tariffs, no 99030125",
30
  "S12": "Dual Aluminum+Copper HTS + aluminum keyword - apply 99030133 + aluminum 232, no 99030125",
31
  "S13": "Zinc keyword - should ONLY apply 99030125, no 232 tariffs allowed",
32
  "S14": "Plastics keyword + metal HTS - override, should ONLY apply 99030125",
 
 
33
  "COPPER_OK": "Copper HTS + copper keyword - verify copper tariffs applied",
34
  "NONE": "No applicable scenario - entry does not match any validation rules",
35
  }
@@ -411,8 +413,35 @@ class HTSValidator:
411
 
412
  # Priority 3: Single list scenarios
413
 
414
- # Steel scenarios (S1)
415
  if in_steel and not in_aluminum and not in_copper:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
  if has_metal_kw:
417
  # S1: Steel HTS + metal keyword + 232 tariff
418
  if has_steel_232:
@@ -483,8 +512,35 @@ class HTSValidator:
483
  issue="; ".join(issues) if issues else "Correct - metal keyword with non-steel HTS"
484
  )
485
 
486
- # Aluminum scenarios (S4)
487
  if in_aluminum and not in_steel and not in_copper:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  if has_aluminum_kw:
489
  # S4: Aluminum HTS + aluminum keyword + 232 tariff
490
  if has_aluminum_232:
@@ -582,7 +638,17 @@ class HTSValidator:
582
 
583
  # S9: Copper keyword but NOT in copper list
584
  if has_copper_kw and not in_copper:
585
- status = "FLAG"
 
 
 
 
 
 
 
 
 
 
586
  return ValidationResult(
587
  entry_number=entry_number,
588
  description=description,
@@ -591,10 +657,10 @@ class HTSValidator:
591
  scenario_id="S9",
592
  scenario_summary=SCENARIO_SUMMARIES["S9"],
593
  status=status,
594
- expected_hts=[],
595
- missing_hts=[],
596
- unexpected_hts=[],
597
- issue="Description mentions copper but HTS not in copper list - potential misclassification"
598
  )
599
 
600
  # No applicable scenario
 
25
  "S7": "Dual Steel+Aluminum HTS - matches keyword, apply corresponding 232, no 99030125",
26
  "S7a": "Dual Steel+Aluminum HTS + BOTH keywords - flag for manual review",
27
  "S8": "Dual Steel+Aluminum HTS + NO keywords - flag for manual review",
28
+ "S9": "Copper keyword but NOT copper HTS - should apply 99030125, no 232 tariffs",
29
  "S11": "Dual Aluminum+Copper HTS + copper keyword - apply 99030133 + copper tariffs, no 99030125",
30
  "S12": "Dual Aluminum+Copper HTS + aluminum keyword - apply 99030133 + aluminum 232, no 99030125",
31
  "S13": "Zinc keyword - should ONLY apply 99030125, no 232 tariffs allowed",
32
  "S14": "Plastics keyword + metal HTS - override, should ONLY apply 99030125",
33
+ "S15": "Steel HTS + aluminum keyword - should apply 99030125, no 99030133 or 232 tariffs",
34
+ "S16": "Aluminum HTS + steel keyword - should apply 99030125, no 99030133 or 232 tariffs",
35
  "COPPER_OK": "Copper HTS + copper keyword - verify copper tariffs applied",
36
  "NONE": "No applicable scenario - entry does not match any validation rules",
37
  }
 
413
 
414
  # Priority 3: Single list scenarios
415
 
416
+ # Steel scenarios (S1, S15)
417
  if in_steel and not in_aluminum and not in_copper:
418
+ # S15: Steel HTS + aluminum keyword - mismatch, should apply 99030125
419
+ if has_aluminum_kw and not has_metal_kw:
420
+ expected = [MISMATCH_CODE]
421
+ issues = []
422
+
423
+ if not has_mismatch:
424
+ issues.append("Missing 99030125")
425
+ if has_steel_232 or has_aluminum_232:
426
+ issues.append("Should NOT have 232 tariffs - description says aluminum but HTS is steel")
427
+ if has_301:
428
+ issues.append("Should NOT have 99030133 - description says aluminum but HTS is steel")
429
+
430
+ status = "PASS" if not issues else "FAIL"
431
+ return ValidationResult(
432
+ entry_number=entry_number,
433
+ description=description,
434
+ primary_hts=primary_hts,
435
+ additional_hts=additional_hts,
436
+ scenario_id="S15",
437
+ scenario_summary=SCENARIO_SUMMARIES["S15"],
438
+ status=status,
439
+ expected_hts=expected,
440
+ missing_hts=[MISMATCH_CODE] if not has_mismatch else [],
441
+ unexpected_hts=self._get_unexpected_232(additional_set) + ([GENERAL_301_CODE] if has_301 else []),
442
+ issue="; ".join(issues) if issues else "Correct - steel HTS with aluminum keyword, has 99030125"
443
+ )
444
+
445
  if has_metal_kw:
446
  # S1: Steel HTS + metal keyword + 232 tariff
447
  if has_steel_232:
 
512
  issue="; ".join(issues) if issues else "Correct - metal keyword with non-steel HTS"
513
  )
514
 
515
+ # Aluminum scenarios (S4, S16)
516
  if in_aluminum and not in_steel and not in_copper:
517
+ # S16: Aluminum HTS + steel keyword - mismatch, should apply 99030125
518
+ if has_metal_kw and not has_aluminum_kw:
519
+ expected = [MISMATCH_CODE]
520
+ issues = []
521
+
522
+ if not has_mismatch:
523
+ issues.append("Missing 99030125")
524
+ if has_steel_232 or has_aluminum_232:
525
+ issues.append("Should NOT have 232 tariffs - description says steel but HTS is aluminum")
526
+ if has_301:
527
+ issues.append("Should NOT have 99030133 - description says steel but HTS is aluminum")
528
+
529
+ status = "PASS" if not issues else "FAIL"
530
+ return ValidationResult(
531
+ entry_number=entry_number,
532
+ description=description,
533
+ primary_hts=primary_hts,
534
+ additional_hts=additional_hts,
535
+ scenario_id="S16",
536
+ scenario_summary=SCENARIO_SUMMARIES["S16"],
537
+ status=status,
538
+ expected_hts=expected,
539
+ missing_hts=[MISMATCH_CODE] if not has_mismatch else [],
540
+ unexpected_hts=self._get_unexpected_232(additional_set) + ([GENERAL_301_CODE] if has_301 else []),
541
+ issue="; ".join(issues) if issues else "Correct - aluminum HTS with steel keyword, has 99030125"
542
+ )
543
+
544
  if has_aluminum_kw:
545
  # S4: Aluminum HTS + aluminum keyword + 232 tariff
546
  if has_aluminum_232:
 
638
 
639
  # S9: Copper keyword but NOT in copper list
640
  if has_copper_kw and not in_copper:
641
+ expected = [MISMATCH_CODE]
642
+ issues = []
643
+
644
+ if not has_mismatch:
645
+ issues.append("Missing 99030125")
646
+ if has_steel_232 or has_aluminum_232 or has_copper_tariff:
647
+ issues.append("Should NOT have 232/copper tariffs - HTS not in copper list")
648
+ if has_301:
649
+ issues.append("Should NOT have 99030133 - HTS not in copper list")
650
+
651
+ status = "PASS" if not issues else "FAIL"
652
  return ValidationResult(
653
  entry_number=entry_number,
654
  description=description,
 
657
  scenario_id="S9",
658
  scenario_summary=SCENARIO_SUMMARIES["S9"],
659
  status=status,
660
+ expected_hts=expected,
661
+ missing_hts=[MISMATCH_CODE] if not has_mismatch else [],
662
+ unexpected_hts=self._get_unexpected_232(additional_set) + ([GENERAL_301_CODE] if has_301 else []),
663
+ issue="; ".join(issues) if issues else "Correct - copper keyword with non-copper HTS"
664
  )
665
 
666
  # No applicable scenario