From 6666ecd59907522e776848687916f2397c217a70 Mon Sep 17 00:00:00 2001 From: Rafhan Mazaya Fathurrahman Date: Thu, 2 Jul 2026 16:46:13 +0700 Subject: [PATCH] feat: auto-fill empty item names in manual labels from sku master database table --- backend/fill_item_names.py | 64 ++++++++++++++++++ .../pfm-web-app/public/comparison_report.xlsx | Bin 21444 -> 21459 bytes backend/sources/manual_labels.json | 16 ++--- 3 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 backend/fill_item_names.py diff --git a/backend/fill_item_names.py b/backend/fill_item_names.py new file mode 100644 index 0000000..05f5f72 --- /dev/null +++ b/backend/fill_item_names.py @@ -0,0 +1,64 @@ +import json +import os +import glob +import csv + +def main(): + uploads_dir = "backend/uploads" + if not os.path.exists(uploads_dir): + uploads_dir = "uploads" + + csv_path = os.path.join(uploads_dir, "sku_master.csv") + if not os.path.exists(csv_path): + print(f"Error: sku_master.csv not found at {csv_path}") + return + + # Load SKU map + sku_map = {} + with open(csv_path, "r", encoding="utf-8") as f: + reader = csv.reader(f) + header = next(reader, None) # skip header + for row in reader: + if len(row) >= 2: + sku_map[row[0].strip()] = row[1].strip() + + print(f"Loaded {len(sku_map)} SKU mappings from master list.") + + manual_pattern = os.path.join(uploads_dir, "manual_label_*.json") + manual_files = glob.glob(manual_pattern) + modified_files = 0 + filled_items = 0 + + for mf in manual_files: + try: + with open(mf, "r", encoding="utf-8") as f: + data = json.load(f) + + is_modified = False + items = data.get("items", []) + for item in items: + sku = item.get("kodeBarang", "").strip() + name = item.get("namaBarang", "").strip() + + # If name is empty, try to fill it + if not name and sku: + master_name = sku_map.get(sku) + if master_name: + item["namaBarang"] = master_name + is_modified = True + filled_items += 1 + + if is_modified: + with open(mf, "w", encoding="utf-8") as f: + json.dump(data, f, indent=2, ensure_ascii=False) + modified_files += 1 + + except Exception as e: + print(f"Error processing manual label {mf}: {e}") + + print(f"Finished item name fill process.") + print(f"Files updated: {modified_files}") + print(f"Item names filled: {filled_items}") + +if __name__ == "__main__": + main() diff --git a/backend/pfm-web-app/public/comparison_report.xlsx b/backend/pfm-web-app/public/comparison_report.xlsx index 34c2fa117e82e6939d6108a9e3e62c216e07d8f4..c41bf48ece37ecae1190b18dd22f5dd098f88a3a 100644 GIT binary patch delta 9223 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 delta 9164 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