@fayz-ai/plugin-inventory 0.18.9 → 0.18.10
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/dist/index.js +58 -18
- package/dist/index.js.map +1 -1
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/pt-BR.d.ts.map +1 -1
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/views/ProductStockTab.d.ts.map +1 -1
- package/dist/views/productFichas.d.ts +1 -1
- package/dist/views/productFichas.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -193,6 +193,11 @@ function ProductStockTab({ item, onChanged }) {
|
|
|
193
193
|
" ",
|
|
194
194
|
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground tabular-nums", children: onHand })
|
|
195
195
|
] }),
|
|
196
|
+
hasMinimum(item.minQuantity) && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
197
|
+
t("inventory.productDetail.minimum"),
|
|
198
|
+
": ",
|
|
199
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground tabular-nums", children: item.minQuantity })
|
|
200
|
+
] }),
|
|
196
201
|
/* @__PURE__ */ jsxs(Button, { size: "sm", onClick: () => setEntryVerb("entry"), children: [
|
|
197
202
|
/* @__PURE__ */ jsx(Plus, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
198
203
|
t("inventory.productDetail.newMovement")
|
|
@@ -682,8 +687,6 @@ function packagingFields(t) {
|
|
|
682
687
|
function ingredientFields(t) {
|
|
683
688
|
const when = yes("isIngredient");
|
|
684
689
|
return [
|
|
685
|
-
{ key: "ingMinimumQuantity", label: t("inventory.productForm.ingMinQuantity"), type: "number", group: "ingredient", min: 0, visibleWhen: when, showInTable: false },
|
|
686
|
-
{ key: "ingMaximumQuantity", label: t("inventory.productForm.ingMaxQuantity"), type: "number", group: "ingredient", min: 0, placeholder: t("inventory.productForm.optional"), visibleWhen: when, showInTable: false },
|
|
687
690
|
{
|
|
688
691
|
key: "ingReorderPoint",
|
|
689
692
|
label: t("inventory.productForm.ingReorderPoint"),
|
|
@@ -848,15 +851,9 @@ function fichaGroups(t) {
|
|
|
848
851
|
var FICHA_KEYS = {
|
|
849
852
|
ingredientInfo: {
|
|
850
853
|
prefix: "ing",
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
"reorderPoint",
|
|
855
|
-
"leadTimeDays",
|
|
856
|
-
"shelfLifeDays",
|
|
857
|
-
"storageTemperature",
|
|
858
|
-
"notes"
|
|
859
|
-
]
|
|
854
|
+
// No minimum/maximum here: the stock minimum is the general one
|
|
855
|
+
// (product_settings), the only one alerts and restock read.
|
|
856
|
+
keys: ["reorderPoint", "leadTimeDays", "shelfLifeDays", "storageTemperature", "notes"]
|
|
860
857
|
},
|
|
861
858
|
saleInfo: {
|
|
862
859
|
prefix: "sale",
|
|
@@ -1001,8 +998,6 @@ function toFichas(values) {
|
|
|
1001
998
|
taxInfo: values.isForSale === true
|
|
1002
999
|
};
|
|
1003
1000
|
const numeric = /* @__PURE__ */ new Set([
|
|
1004
|
-
"minimumQuantity",
|
|
1005
|
-
"maximumQuantity",
|
|
1006
1001
|
"reorderPoint",
|
|
1007
1002
|
"leadTimeDays",
|
|
1008
1003
|
"shelfLifeDays",
|
|
@@ -7658,6 +7653,7 @@ var en = {
|
|
|
7658
7653
|
"inventory.productDetail.stockTab": "Stock",
|
|
7659
7654
|
"inventory.productDetail.positionsTitle": "Stock by location",
|
|
7660
7655
|
"inventory.productDetail.onHand": "On hand",
|
|
7656
|
+
"inventory.productDetail.minimum": "Minimum",
|
|
7661
7657
|
"inventory.productDetail.noPositions": "No stock in any location",
|
|
7662
7658
|
"inventory.productDetail.historyTitle": "Movement history",
|
|
7663
7659
|
"inventory.productDetail.undoLast": "Undo last movement",
|
|
@@ -7753,8 +7749,6 @@ var en = {
|
|
|
7753
7749
|
"inventory.productForm.notes": "Notes",
|
|
7754
7750
|
"inventory.productForm.ingredientSection": "Ingredient",
|
|
7755
7751
|
"inventory.productForm.ingredientSectionDesc": "What purchasing needs to restock in time.",
|
|
7756
|
-
"inventory.productForm.ingMinQuantity": "Minimum quantity",
|
|
7757
|
-
"inventory.productForm.ingMaxQuantity": "Maximum quantity",
|
|
7758
7752
|
"inventory.productForm.ingReorderPoint": "Reorder point",
|
|
7759
7753
|
"inventory.productForm.ingReorderPointHint": "Sits ABOVE the minimum: the warning that still arrives in time to buy.",
|
|
7760
7754
|
"inventory.productForm.ingLeadTime": "Lead time (days)",
|
|
@@ -8527,6 +8521,7 @@ var ptBR = {
|
|
|
8527
8521
|
"inventory.productDetail.stockTab": "Estoque",
|
|
8528
8522
|
"inventory.productDetail.positionsTitle": "Estoque por local",
|
|
8529
8523
|
"inventory.productDetail.onHand": "Em estoque",
|
|
8524
|
+
"inventory.productDetail.minimum": "M\xEDnimo",
|
|
8530
8525
|
"inventory.productDetail.noPositions": "Sem estoque em nenhum local",
|
|
8531
8526
|
"inventory.productDetail.historyTitle": "Movimenta\xE7\xE3o",
|
|
8532
8527
|
"inventory.productDetail.undoLast": "Desfazer \xFAltimo movimento",
|
|
@@ -8622,8 +8617,6 @@ var ptBR = {
|
|
|
8622
8617
|
"inventory.productForm.notes": "Observa\xE7\xF5es",
|
|
8623
8618
|
"inventory.productForm.ingredientSection": "Insumo",
|
|
8624
8619
|
"inventory.productForm.ingredientSectionDesc": "O que a compra precisa saber para repor na hora certa.",
|
|
8625
|
-
"inventory.productForm.ingMinQuantity": "Quantidade m\xEDnima",
|
|
8626
|
-
"inventory.productForm.ingMaxQuantity": "Quantidade m\xE1xima",
|
|
8627
8620
|
"inventory.productForm.ingReorderPoint": "Ponto de reposi\xE7\xE3o",
|
|
8628
8621
|
"inventory.productForm.ingReorderPointHint": "Fica ACIMA do m\xEDnimo: \xE9 o aviso que ainda chega a tempo de comprar.",
|
|
8629
8622
|
"inventory.productForm.ingLeadTime": "Prazo de entrega (dias)",
|
|
@@ -18488,6 +18481,52 @@ BEGIN
|
|
|
18488
18481
|
EXECUTE v_new;
|
|
18489
18482
|
END $patch$;
|
|
18490
18483
|
`;
|
|
18484
|
+
var MIGRATION_030_THE_MINIMUM_CAN_BE_SAVED = `-- ============================================================================
|
|
18485
|
+
-- 030 \u2014 the minimum can be saved
|
|
18486
|
+
--
|
|
18487
|
+
-- The product form saves its minimum with an upsert on
|
|
18488
|
+
-- (tenant_id, product_id, unit_id). The only unique index on those columns
|
|
18489
|
+
-- was the expression index (tenant_id, product_id, COALESCE(unit_id, zero)),
|
|
18490
|
+
-- which ON CONFLICT cannot infer from a column list, so every save came back
|
|
18491
|
+
-- 42P10 and the client never looked at the error: "Quantidade M\xEDnima" was
|
|
18492
|
+
-- dropped in silence.
|
|
18493
|
+
--
|
|
18494
|
+
-- A plain column index with NULLS NOT DISTINCT is an arbiter for that
|
|
18495
|
+
-- conflict target and treats the tenant-wide row (unit_id NULL) as one row,
|
|
18496
|
+
-- which is what the expression index already enforced. Both are kept: they
|
|
18497
|
+
-- agree on every row, and dropping the old one is not this fix's business.
|
|
18498
|
+
--
|
|
18499
|
+
-- Hand-applied on cluster-squash-test on 2026-10-22 under this same name, so
|
|
18500
|
+
-- this file must be a no-op there.
|
|
18501
|
+
--
|
|
18502
|
+
-- Second part: the Insumo tab had its own minimum/maximum, stored on
|
|
18503
|
+
-- plg_inventory_product_ingredient_info, which no alert or restock list
|
|
18504
|
+
-- reads. The tab no longer offers them. Whatever was typed there is copied
|
|
18505
|
+
-- into the tenant-wide settings row when the product has none yet, so the
|
|
18506
|
+
-- number the person entered becomes the one that is acted on. The columns
|
|
18507
|
+
-- stay; nothing is dropped.
|
|
18508
|
+
-- ============================================================================
|
|
18509
|
+
|
|
18510
|
+
CREATE UNIQUE INDEX IF NOT EXISTS plg_inventory_product_settings_upsert_key
|
|
18511
|
+
ON public.plg_inventory_product_settings (tenant_id, product_id, unit_id) NULLS NOT DISTINCT;
|
|
18512
|
+
|
|
18513
|
+
INSERT INTO public.plg_inventory_product_settings (tenant_id, product_id, unit_id, min_quantity, max_quantity)
|
|
18514
|
+
SELECT i.tenant_id,
|
|
18515
|
+
i.product_id,
|
|
18516
|
+
NULL,
|
|
18517
|
+
GREATEST(COALESCE(i.minimum_quantity, 0), 0),
|
|
18518
|
+
CASE WHEN i.maximum_quantity >= 0 THEN i.maximum_quantity END
|
|
18519
|
+
FROM public.plg_inventory_product_ingredient_info i
|
|
18520
|
+
JOIN public.products p ON p.id = i.product_id AND p.tenant_id = i.tenant_id
|
|
18521
|
+
WHERE (COALESCE(i.minimum_quantity, 0) > 0 OR i.maximum_quantity IS NOT NULL)
|
|
18522
|
+
AND NOT EXISTS (
|
|
18523
|
+
SELECT 1
|
|
18524
|
+
FROM public.plg_inventory_product_settings s
|
|
18525
|
+
WHERE s.tenant_id = i.tenant_id
|
|
18526
|
+
AND s.product_id = i.product_id
|
|
18527
|
+
AND s.unit_id IS NULL)
|
|
18528
|
+
ON CONFLICT (tenant_id, product_id, unit_id) DO NOTHING;
|
|
18529
|
+
`;
|
|
18491
18530
|
var MIGRATIONS = [
|
|
18492
18531
|
{ id: "000_baseline", sql: MIGRATION_000_BASELINE },
|
|
18493
18532
|
{ id: "001_the_usage_that_left_stock_can_be_audited", sql: MIGRATION_001_THE_USAGE_THAT_LEFT_STOCK_CAN_BE_AUDITED },
|
|
@@ -18518,7 +18557,8 @@ var MIGRATIONS = [
|
|
|
18518
18557
|
{ id: "026_stock_cost_knows_its_currency", sql: MIGRATION_026_STOCK_COST_KNOWS_ITS_CURRENCY },
|
|
18519
18558
|
{ id: "027_a_receipt_names_the_line_it_came_from", sql: MIGRATION_027_A_RECEIPT_NAMES_THE_LINE_IT_CAME_FROM },
|
|
18520
18559
|
{ id: "028_a_receipt_keeps_the_variant", sql: MIGRATION_028_A_RECEIPT_KEEPS_THE_VARIANT },
|
|
18521
|
-
{ id: "029_a_reversal_undoes_the_same_variant", sql: MIGRATION_029_A_REVERSAL_UNDOES_THE_SAME_VARIANT }
|
|
18560
|
+
{ id: "029_a_reversal_undoes_the_same_variant", sql: MIGRATION_029_A_REVERSAL_UNDOES_THE_SAME_VARIANT },
|
|
18561
|
+
{ id: "030_the_minimum_can_be_saved", sql: MIGRATION_030_THE_MINIMUM_CAN_BE_SAVED }
|
|
18522
18562
|
];
|
|
18523
18563
|
var DEFAULT_LABELS = {
|
|
18524
18564
|
pageTitle: "Inventory",
|