import json from pathlib import Path from article_data_manager.tools.erp_explorer import ( infer_value_type, profile_erp_csv, render_erp_profile_report, write_erp_profile_report, ) def write_text(path: Path, content: str) -> Path: path.write_text(content, encoding="utf-8") return path def write_rollcalc_json(path: Path, article_numbers: list[str]) -> Path: payload = [ { "nr": nr, "name": f"Article {nr}", "thickness": 1.0, "area_weight": 0.0, "core_type": 0.0, } for nr in article_numbers ] path.write_text(json.dumps(payload), encoding="utf-8") return path def test_profiles_columns(tmp_path: Path) -> None: csv_path = write_text( tmp_path / "erp.csv", "\n".join( [ "SL_ITEM_NO,ROP_PRODUCT_WIDTH,COMMENT,EMPTY_COLUMN", "214700,\"6,00\",Alpha,", "000123,1.20,Beta,", "777777,,Alpha,", ] ), ) profile = profile_erp_csv(csv_path) assert profile.file_name == "erp.csv" assert profile.row_count == 3 assert profile.column_count == 4 columns = {column.name: column for column in profile.columns} assert columns["ROP_PRODUCT_WIDTH"].filled_count == 2 assert columns["ROP_PRODUCT_WIDTH"].empty_count == 1 assert columns["ROP_PRODUCT_WIDTH"].distinct_count == 2 assert columns["ROP_PRODUCT_WIDTH"].inferred_type == "decimal" assert columns["COMMENT"].distinct_count == 2 assert columns["COMMENT"].inferred_type == "text" assert columns["EMPTY_COLUMN"].inferred_type == "empty" def test_infers_value_types() -> None: assert infer_value_type([]) == "empty" assert infer_value_type(["1", "002", "-3"]) == "integer" assert infer_value_type(["1", "2.5", "3,75"]) == "decimal" assert infer_value_type(["Alpha", "Beta"]) == "text" assert infer_value_type(["1", "Alpha"]) == "mixed" def test_detects_duplicate_article_numbers(tmp_path: Path) -> None: csv_path = write_text( tmp_path / "erp.csv", "\n".join( [ "SL_ITEM_NO,NAME", "00001,A", "1,B", "00001,C", "214700,D", "214700,E", ] ), ) article_numbers = profile_erp_csv(csv_path).article_numbers assert article_numbers.distinct_count == 3 assert article_numbers.duplicate_count == 2 assert [(duplicate.nr, duplicate.count) for duplicate in article_numbers.duplicates] == [ ("00001", 2), ("214700", 2), ] def test_compares_rollcalc_articles_when_path_is_provided(tmp_path: Path) -> None: csv_path = write_text( tmp_path / "erp.csv", "\n".join( [ "SL_ITEM_NO,NAME", "214700,A", "000123,B", ] ), ) rollcalc_path = write_rollcalc_json(tmp_path / "article-data.json", ["214700", "999999"]) comparison = profile_erp_csv(csv_path, rollcalc_path=rollcalc_path).rollcalc_comparison assert comparison is not None assert comparison.rollcalc_article_count == 2 assert comparison.found_count == 1 assert comparison.missing_count == 1 assert comparison.missing_article_numbers == ("999999",) def test_rollcalc_comparison_is_optional(tmp_path: Path) -> None: csv_path = write_text( tmp_path / "erp.csv", "\n".join( [ "SL_ITEM_NO,NAME", "214700,A", ] ), ) assert profile_erp_csv(csv_path).rollcalc_comparison is None def test_renders_and_writes_report(tmp_path: Path) -> None: csv_path = write_text( tmp_path / "erp.csv", "\n".join( [ "SL_ITEM_NO,ROP_PRODUCT_WIDTH", "214700,\"6,00\"", "214700,\"6,00\"", ] ), ) report_path = tmp_path / "reports" / "erp_profile_report.txt" profile = write_erp_profile_report(csv_path, report_path=report_path) report = report_path.read_text(encoding="utf-8") assert report == render_erp_profile_report(profile) assert "ERP Profile Report" in report assert "File: erp.csv" in report assert "Rows: 2" in report assert "Columns: 2" in report assert "Column: ROP_PRODUCT_WIDTH" in report assert "Duplicate article numbers" in report assert "214700\t2" in report