deleted: public/templates/categories_template.csv deleted: public/templates/pickitems_template.csv deleted: public/templates/picklists_template.csv modified: src/db/migrations.ts modified: src/screens/ManageCategoriesScreen.tsx modified: src/screens/ManageProductsScreen.tsx
81 lines
2.8 KiB
TypeScript
81 lines
2.8 KiB
TypeScript
// src/db/migrations.ts
|
|
import { StockFillDB } from './index';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
export const applyMigrations = async (db: StockFillDB) => {
|
|
// Ensure DB is open and ready
|
|
await db.open();
|
|
|
|
// Run a single transaction that normalizes products and pickLists
|
|
await db.transaction('rw', db.categories, db.products, db.pickLists, async () => {
|
|
const now = Date.now();
|
|
|
|
// Load categories (existing)
|
|
const categories = await db.categories.toArray();
|
|
const categoriesByName = new Map(categories.map((c) => [c.name, c.id]));
|
|
const categoriesById = new Map(categories.map((c) => [c.id, c.name]));
|
|
|
|
// 1) Normalize products: category -> categoryId
|
|
const products = await db.products.toArray();
|
|
await Promise.all(
|
|
products.map(async (product) => {
|
|
const cat = product.category ?? '';
|
|
|
|
// Skip empty
|
|
if (!cat) return;
|
|
|
|
// If already an id that matches a known category, skip
|
|
if (categoriesById.has(cat)) return;
|
|
|
|
// If it's a name that matches an existing category, update
|
|
const matchingId = categoriesByName.get(cat);
|
|
if (matchingId) {
|
|
await db.products.update(product.id, { category: matchingId });
|
|
return;
|
|
}
|
|
|
|
// Otherwise: create a new category with this name and use its id
|
|
const newCatId = uuidv4();
|
|
await db.categories.add({
|
|
id: newCatId,
|
|
name: cat,
|
|
created_at: now,
|
|
updated_at: now,
|
|
});
|
|
categoriesByName.set(cat, newCatId);
|
|
categoriesById.set(newCatId, cat);
|
|
|
|
await db.products.update(product.id, { category: newCatId });
|
|
}),
|
|
);
|
|
|
|
// Refresh categories maps (in case we added new ones)
|
|
const updatedCategories = await db.categories.toArray();
|
|
const updatedByName = new Map(updatedCategories.map((c) => [c.name, c.id]));
|
|
const updatedById = new Map(updatedCategories.map((c) => [c.id, c.name]));
|
|
|
|
// 2) Normalize pickLists.categories (array) to hold ids (not names)
|
|
const pickLists = await db.pickLists.toArray();
|
|
await Promise.all(
|
|
pickLists.map(async (pl) => {
|
|
if (!Array.isArray((pl as any).categories)) return;
|
|
|
|
const newCats = (pl as any).categories.map((entry: string) => {
|
|
// If the entry is already an id we know, keep it
|
|
if (updatedById.has(entry)) return entry;
|
|
// If entry is a name, return its id (if exists)
|
|
const id = updatedByName.get(entry);
|
|
if (id) return id;
|
|
// If it's neither, keep as-is (or optionally create category)
|
|
return entry;
|
|
});
|
|
|
|
// Update only if changed
|
|
if (JSON.stringify(newCats) !== JSON.stringify((pl as any).categories)) {
|
|
await db.pickLists.update(pl.id, { categories: newCats });
|
|
}
|
|
}),
|
|
);
|
|
});
|
|
};
|