fix: scope pallet diff parsing to card region
Some checks failed
Desktop Release / Bootstrap updater signing key (push) Has been cancelled
Desktop Release / Windows x64 NSIS (push) Has been cancelled
Desktop Release / Linux x64 DEB + AppImage (push) Has been cancelled
Desktop Release / Publish public desktop release (push) Has been cancelled

This commit is contained in:
Admin 2026-09-25 21:08:24 +00:00
parent ba534cfdb7
commit 554fde4447
5 changed files with 83 additions and 7 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@fieldlens/print",
"version": "0.1.20",
"version": "0.1.21",
"private": true,
"type": "module",
"scripts": {

View File

@ -1,6 +1,6 @@
[package]
name = "fieldlens-print"
version = "0.1.20"
version = "0.1.21"
description = "FieldLens print-stream barcode capture companion"
authors = ["Arrowstack"]
edition = "2021"

View File

@ -41,6 +41,39 @@ fn column_slice(line: &str, start: usize, end: Option<usize>) -> &str {
}
}
fn scope_card_region(raw_text: &str) -> String {
let lines: Vec<&str> = raw_text.lines().collect();
let header_index = lines.iter().position(|line| {
find_ci(line, "ORIGIN").is_some()
&& find_ci(line, "VAR").is_some()
&& find_ci(line, "BRAND").is_some()
&& find_ci(line, "CLASS").is_some()
});
let title_index = lines.iter().position(|line| {
find_ci(line, "Avocados").is_some() && line.contains('-')
});
let start = match (title_index, header_index) {
(Some(title), Some(header)) if title <= header && header.saturating_sub(title) <= 4 => title,
(_, Some(header)) => header,
(Some(title), None) => title,
(None, None) => return raw_text.to_string(),
};
let end = lines
.iter()
.enumerate()
.skip(start)
.find(|(_, line)| find_ci(line, "Total").is_some())
.map(|(index, _)| index)
.unwrap_or_else(|| (start + 40).min(lines.len().saturating_sub(1)));
lines[start..=end].join("\n")
}
fn parse_layout_tables(raw_text: &str, snapshot: &mut PalletSnapshot) {
let lines: Vec<&str> = raw_text.lines().collect();
let right_col = lines
@ -121,7 +154,8 @@ fn parse_layout_tables(raw_text: &str, snapshot: &mut PalletSnapshot) {
}
pub fn parse_pallet_snapshot(raw_text: &str, pallet_id: &str) -> PalletSnapshot {
let flat = raw_text.split_whitespace().collect::<Vec<_>>().join(" ");
let card_text = scope_card_region(raw_text);
let flat = card_text.split_whitespace().collect::<Vec<_>>().join(" ");
let mut snapshot = PalletSnapshot {
pallet_id: pallet_id.trim().to_string(),
..PalletSnapshot::default()
@ -144,7 +178,7 @@ pub fn parse_pallet_snapshot(raw_text: &str, pallet_id: &str) -> PalletSnapshot
);
snapshot.total = capture(&flat, r"(?i)\bTotal\s+([0-9]{1,5})\b", 1);
parse_layout_tables(raw_text, &mut snapshot);
parse_layout_tables(&card_text, &mut snapshot);
if snapshot.grower.is_none() {
if let Ok(regex) = Regex::new(
@ -174,7 +208,7 @@ pub fn parse_pallet_snapshot(raw_text: &str, pallet_id: &str) -> PalletSnapshot
if snapshot.variety.is_none() {
if let Ok(regex) = Regex::new(r"(?i)^\s*Avocados?\s*-\s*([A-Z][A-Z -]{1,20})\s*$") {
snapshot.variety = raw_text.lines().find_map(|line| {
snapshot.variety = card_text.lines().find_map(|line| {
regex
.captures(line)
.and_then(|captures| captures.get(1))
@ -277,6 +311,48 @@ mod tests {
Total 30
"#;
const WHOLE_SHEET: &str = r#"
20 JA 40595983
JA 40595983 JA 40595983 JA 40595983
20
Avocados - Hass
ORIGIN VAR BRAND CLASS Pallet: 40595983
NZ Hass NZAG CLASS 3. Grower Packrun Size Qty
BASE PACK 89930 89930/16/17/26 20 30
CHEP B37
Pick Date: 16/09/2026
Pack Date: 17/09/2026
Time: 14:46:10
This product meets export quality specifications
Signature:
Total 30
JA 40595983 JA 40595983 JA 40595983
20 20 20 20
"#;
#[test]
fn scopes_the_two_column_card_inside_the_full_print_sheet() {
let scoped = scope_card_region(WHOLE_SHEET);
assert!(scoped.contains("ORIGIN"));
assert!(scoped.contains("Grower"));
assert!(scoped.contains("Total"));
assert!(!scoped.contains("20 JA 40595983"));
assert!(!scoped.contains("20 20 20 20"));
let snapshot = parse_pallet_snapshot(WHOLE_SHEET, "40595983");
assert_eq!(snapshot.origin.as_deref(), Some("NZ"));
assert_eq!(snapshot.variety.as_deref(), Some("Hass"));
assert_eq!(snapshot.brand.as_deref(), Some("NZAG"));
assert_eq!(snapshot.class.as_deref(), Some("CLASS 3"));
assert_eq!(snapshot.base.as_deref(), Some("CHEP"));
assert_eq!(snapshot.pack.as_deref(), Some("B37"));
assert_eq!(snapshot.grower.as_deref(), Some("89930"));
assert_eq!(snapshot.packrun.as_deref(), Some("89930/16/17/26"));
assert_eq!(snapshot.size.as_deref(), Some("20"));
assert_eq!(snapshot.qty.as_deref(), Some("30"));
assert_eq!(snapshot.total.as_deref(), Some("30"));
}
#[test]
fn parses_export_card_fields() {
let snapshot = parse_pallet_snapshot(CARD, "40595983");

View File

@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "FieldLens Print",
"version": "0.1.20",
"version": "0.1.21",
"identifier": "dev.arrowstack.fieldlens.print",
"build": {
"beforeDevCommand": "npm run dev",

View File

@ -141,7 +141,7 @@ let config: AppConfig
let jobs: Job[] = []
let status: Status = { running: false, mode: 'raw-proxy', pending: 0, jobs: 0 }
let loginTimer: number | undefined
let currentVersion = '0.1.20'
let currentVersion = '0.1.21'
let bundleType: BundleType | null = null
let availableUpdate: Update | null = null
let availableManualUpdate: ManualUpdate | null = null