@fayz-ai/plugin-inventory 0.1.7 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/data/supabase.d.ts.map +1 -1
- package/dist/data/tables.d.ts +10 -0
- package/dist/data/tables.d.ts.map +1 -0
- package/dist/index.cjs +36 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +36 -26
- package/dist/index.js.map +1 -1
- package/dist/migrations/index.d.ts +9 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/package.json +10 -4
- package/src/README.md +1 -1
- package/src/data/supabase.ts +24 -23
- package/src/data/tables.ts +10 -0
- package/src/migrations/000_plg_rename.sql +27 -0
- package/src/migrations/001_inventory_base.sql +27 -27
- package/src/migrations/002_recipes.sql +13 -13
- package/src/migrations/003_measurement_units.sql +4 -4
- package/src/migrations/index.ts +161 -0
- package/src/registries.ts +5 -5
package/dist/index.js
CHANGED
|
@@ -1725,6 +1725,17 @@ function createMockInventoryProvider() {
|
|
|
1725
1725
|
return provider;
|
|
1726
1726
|
}
|
|
1727
1727
|
|
|
1728
|
+
// src/data/tables.ts
|
|
1729
|
+
var T = {
|
|
1730
|
+
stockLocations: "plg_inventory_stock_locations",
|
|
1731
|
+
stockMovements: "plg_inventory_stock_movements",
|
|
1732
|
+
stockPositions: "plg_inventory_stock_positions",
|
|
1733
|
+
recipes: "plg_inventory_recipes",
|
|
1734
|
+
recipeIngredients: "plg_inventory_recipe_ingredients",
|
|
1735
|
+
measurementUnits: "plg_inventory_measurement_units",
|
|
1736
|
+
productCategories: "plg_inventory_product_categories"
|
|
1737
|
+
};
|
|
1738
|
+
|
|
1728
1739
|
// src/data/supabase.ts
|
|
1729
1740
|
function getTenantId() {
|
|
1730
1741
|
return getActiveTenantId();
|
|
@@ -1773,10 +1784,10 @@ function createSupabaseInventoryProvider() {
|
|
|
1773
1784
|
function getClients() {
|
|
1774
1785
|
const supabase = getSupabaseClientOptional();
|
|
1775
1786
|
if (!supabase) throw new Error("Supabase not initialized");
|
|
1776
|
-
return { core: supabase
|
|
1787
|
+
return { core: supabase, pub: supabase };
|
|
1777
1788
|
}
|
|
1778
1789
|
const provider = {
|
|
1779
|
-
// --- Products (
|
|
1790
|
+
// --- Products (public.products) ---
|
|
1780
1791
|
async getProducts(query) {
|
|
1781
1792
|
const { core} = getClients();
|
|
1782
1793
|
let qb = core.from("products").select("*", { count: "exact" });
|
|
@@ -1867,7 +1878,7 @@ function createSupabaseInventoryProvider() {
|
|
|
1867
1878
|
if (m.destinationLocationId && !m.destinationLocationName) locationIds.add(m.destinationLocationId);
|
|
1868
1879
|
}
|
|
1869
1880
|
if (locationIds.size > 0) {
|
|
1870
|
-
const { data: locs } = await pub.from(
|
|
1881
|
+
const { data: locs } = await pub.from(T.stockLocations).select("id, name").in("id", [...locationIds]);
|
|
1871
1882
|
const locMap = new Map((locs ?? []).map((l) => [l.id, l.name]));
|
|
1872
1883
|
for (const m of movements) {
|
|
1873
1884
|
if (m.stockLocationId && !m.stockLocationName) m.stockLocationName = locMap.get(m.stockLocationId);
|
|
@@ -1888,7 +1899,7 @@ function createSupabaseInventoryProvider() {
|
|
|
1888
1899
|
total_cost: unitCost * input.quantity,
|
|
1889
1900
|
movement_date: input.movementDate ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
|
|
1890
1901
|
};
|
|
1891
|
-
const { data, error } = await pub.from(
|
|
1902
|
+
const { data, error } = await pub.from(T.stockMovements).insert(row).select().single();
|
|
1892
1903
|
if (error) throw new Error(error.message);
|
|
1893
1904
|
const { data: product } = await core.from("products").select("id, name, stock").eq("id", input.productId).single();
|
|
1894
1905
|
if (product) {
|
|
@@ -1900,11 +1911,11 @@ function createSupabaseInventoryProvider() {
|
|
|
1900
1911
|
if (input.stockLocationId) {
|
|
1901
1912
|
try {
|
|
1902
1913
|
const posDelta = input.movementType === "entry" ? input.quantity : -input.quantity;
|
|
1903
|
-
const { data: existing } = await pub.from(
|
|
1914
|
+
const { data: existing } = await pub.from(T.stockPositions).select("id, quantity").eq("product_id", input.productId).eq("stock_location_id", input.stockLocationId).maybeSingle();
|
|
1904
1915
|
if (existing) {
|
|
1905
|
-
await pub.from(
|
|
1916
|
+
await pub.from(T.stockPositions).update({ quantity: (existing.quantity ?? 0) + posDelta, unit_cost: input.unitCost ?? 0 }).eq("id", existing.id);
|
|
1906
1917
|
} else {
|
|
1907
|
-
await pub.from(
|
|
1918
|
+
await pub.from(T.stockPositions).insert({
|
|
1908
1919
|
tenant_id: tenantId,
|
|
1909
1920
|
product_id: input.productId,
|
|
1910
1921
|
stock_location_id: input.stockLocationId,
|
|
@@ -1915,11 +1926,11 @@ function createSupabaseInventoryProvider() {
|
|
|
1915
1926
|
});
|
|
1916
1927
|
}
|
|
1917
1928
|
if (input.movementType === "transfer" && input.destinationLocationId) {
|
|
1918
|
-
const { data: destExisting } = await pub.from(
|
|
1929
|
+
const { data: destExisting } = await pub.from(T.stockPositions).select("id, quantity").eq("product_id", input.productId).eq("stock_location_id", input.destinationLocationId).maybeSingle();
|
|
1919
1930
|
if (destExisting) {
|
|
1920
|
-
await pub.from(
|
|
1931
|
+
await pub.from(T.stockPositions).update({ quantity: (destExisting.quantity ?? 0) + input.quantity, unit_cost: input.unitCost ?? 0 }).eq("id", destExisting.id);
|
|
1921
1932
|
} else {
|
|
1922
|
-
await pub.from(
|
|
1933
|
+
await pub.from(T.stockPositions).insert({
|
|
1923
1934
|
tenant_id: tenantId,
|
|
1924
1935
|
product_id: input.productId,
|
|
1925
1936
|
stock_location_id: input.destinationLocationId,
|
|
@@ -1937,11 +1948,11 @@ function createSupabaseInventoryProvider() {
|
|
|
1937
1948
|
const movement = snakeToCamel(data);
|
|
1938
1949
|
movement.productName = product?.name;
|
|
1939
1950
|
if (input.stockLocationId) {
|
|
1940
|
-
const { data: loc } = await pub.from(
|
|
1951
|
+
const { data: loc } = await pub.from(T.stockLocations).select("name").eq("id", input.stockLocationId).single();
|
|
1941
1952
|
movement.stockLocationName = loc?.name;
|
|
1942
1953
|
}
|
|
1943
1954
|
if (input.destinationLocationId) {
|
|
1944
|
-
const { data: loc } = await pub.from(
|
|
1955
|
+
const { data: loc } = await pub.from(T.stockLocations).select("name").eq("id", input.destinationLocationId).single();
|
|
1945
1956
|
movement.destinationLocationName = loc?.name;
|
|
1946
1957
|
}
|
|
1947
1958
|
return movement;
|
|
@@ -1949,44 +1960,44 @@ function createSupabaseInventoryProvider() {
|
|
|
1949
1960
|
// --- Stock Positions ---
|
|
1950
1961
|
async getPositions(productId) {
|
|
1951
1962
|
const { pub } = getClients();
|
|
1952
|
-
const { data } = await pub.from(
|
|
1963
|
+
const { data } = await pub.from(T.stockPositions).select("*").eq("product_id", productId);
|
|
1953
1964
|
return (data ?? []).map((r) => snakeToCamel(r));
|
|
1954
1965
|
},
|
|
1955
1966
|
// --- Stock Locations ---
|
|
1956
1967
|
async getLocations() {
|
|
1957
1968
|
const { pub } = getClients();
|
|
1958
|
-
const { data } = await pub.from(
|
|
1969
|
+
const { data } = await pub.from(T.stockLocations).select("*").eq("is_active", true).order("name");
|
|
1959
1970
|
return (data ?? []).map((r) => snakeToCamel(r));
|
|
1960
1971
|
},
|
|
1961
1972
|
async createLocation(input) {
|
|
1962
1973
|
const { pub } = getClients();
|
|
1963
1974
|
const tenantId = getTenantId();
|
|
1964
|
-
const { data } = await pub.from(
|
|
1975
|
+
const { data } = await pub.from(T.stockLocations).insert({ ...camelToSnake(input), tenant_id: tenantId }).select().single();
|
|
1965
1976
|
return snakeToCamel(data);
|
|
1966
1977
|
},
|
|
1967
1978
|
// --- Recipes ---
|
|
1968
1979
|
async getRecipes() {
|
|
1969
1980
|
const { pub } = getClients();
|
|
1970
|
-
const { data } = await pub.from(
|
|
1981
|
+
const { data } = await pub.from(T.recipes).select("*").eq("is_active", true).order("name");
|
|
1971
1982
|
return (data ?? []).map((r) => snakeToCamel(r));
|
|
1972
1983
|
},
|
|
1973
1984
|
async getRecipeById(id) {
|
|
1974
1985
|
const { pub } = getClients();
|
|
1975
|
-
const { data } = await pub.from(
|
|
1986
|
+
const { data } = await pub.from(T.recipes).select("*").eq("id", id).single();
|
|
1976
1987
|
return data ? snakeToCamel(data) : null;
|
|
1977
1988
|
},
|
|
1978
1989
|
async getRecipeIngredients(recipeId) {
|
|
1979
1990
|
const { pub } = getClients();
|
|
1980
|
-
const { data } = await pub.from(
|
|
1991
|
+
const { data } = await pub.from(T.recipeIngredients).select("*").eq("recipe_id", recipeId).order("display_order");
|
|
1981
1992
|
return (data ?? []).map((r) => snakeToCamel(r));
|
|
1982
1993
|
},
|
|
1983
1994
|
async createRecipe(input) {
|
|
1984
1995
|
const { pub } = getClients();
|
|
1985
1996
|
const tenantId = getTenantId();
|
|
1986
1997
|
const { ingredients, ...recipeData } = input;
|
|
1987
|
-
const { data: recipe } = await pub.from(
|
|
1998
|
+
const { data: recipe } = await pub.from(T.recipes).insert({ ...camelToSnake(recipeData), tenant_id: tenantId }).select().single();
|
|
1988
1999
|
if (recipe && ingredients.length > 0) {
|
|
1989
|
-
await pub.from(
|
|
2000
|
+
await pub.from(T.recipeIngredients).insert(
|
|
1990
2001
|
ingredients.map((ing) => ({ ...camelToSnake(ing), recipe_id: recipe.id, tenant_id: tenantId }))
|
|
1991
2002
|
);
|
|
1992
2003
|
}
|
|
@@ -2002,7 +2013,7 @@ function createSupabaseInventoryProvider() {
|
|
|
2002
2013
|
const totalValue = items.reduce((sum, p) => sum + (p.stock ?? 0) * (p.price ?? 0), 0);
|
|
2003
2014
|
const weekAgo = /* @__PURE__ */ new Date();
|
|
2004
2015
|
weekAgo.setDate(weekAgo.getDate() - 7);
|
|
2005
|
-
const { data: movements } = await pub.from(
|
|
2016
|
+
const { data: movements } = await pub.from(T.stockMovements).select("movement_type").gte("movement_date", weekAgo.toISOString().slice(0, 10));
|
|
2006
2017
|
const movs = movements ?? [];
|
|
2007
2018
|
const movementsByType = { entry: 0, exit: 0, adjustment: 0, transfer: 0, loss: 0 };
|
|
2008
2019
|
for (const m of movs) movementsByType[m.movement_type]++;
|
|
@@ -2125,8 +2136,7 @@ var supplierEntity = {
|
|
|
2125
2136
|
{ key: "isActive", label: "Active", type: "boolean", showInTable: true, defaultValue: true }
|
|
2126
2137
|
],
|
|
2127
2138
|
data: {
|
|
2128
|
-
table: "
|
|
2129
|
-
schema: "saas_core",
|
|
2139
|
+
table: "people",
|
|
2130
2140
|
tenantScoped: true,
|
|
2131
2141
|
filters: { kind: "supplier" },
|
|
2132
2142
|
defaults: { kind: "supplier" }
|
|
@@ -2143,7 +2153,7 @@ var measurementUnitEntity = {
|
|
|
2143
2153
|
{ key: "abbreviation", label: "Abbreviation", type: "text", required: true, showInTable: true },
|
|
2144
2154
|
{ key: "isActive", label: "Active", type: "boolean", showInTable: true, defaultValue: true }
|
|
2145
2155
|
],
|
|
2146
|
-
data: { table:
|
|
2156
|
+
data: { table: T.measurementUnits, tenantScoped: true }
|
|
2147
2157
|
};
|
|
2148
2158
|
var productCategoryEntity = {
|
|
2149
2159
|
name: "Product Category",
|
|
@@ -2156,7 +2166,7 @@ var productCategoryEntity = {
|
|
|
2156
2166
|
{ key: "parentId", label: "Parent", type: "text", showInTable: false },
|
|
2157
2167
|
{ key: "isActive", label: "Active", type: "boolean", showInTable: true, defaultValue: true }
|
|
2158
2168
|
],
|
|
2159
|
-
data: { table:
|
|
2169
|
+
data: { table: T.productCategories, tenantScoped: true }
|
|
2160
2170
|
};
|
|
2161
2171
|
var stockLocationEntity = {
|
|
2162
2172
|
name: "Stock Location",
|
|
@@ -2169,7 +2179,7 @@ var stockLocationEntity = {
|
|
|
2169
2179
|
{ key: "description", label: "Description", type: "textarea", showInTable: true },
|
|
2170
2180
|
{ key: "isActive", label: "Active", type: "boolean", showInTable: true, defaultValue: true }
|
|
2171
2181
|
],
|
|
2172
|
-
data: { table:
|
|
2182
|
+
data: { table: T.stockLocations, tenantScoped: true }
|
|
2173
2183
|
};
|
|
2174
2184
|
var inventoryRegistries = [
|
|
2175
2185
|
// --- Editable ---
|