Spaces:
Running
Running
Update services.js
Browse files- services.js +91 -27
services.js
CHANGED
|
@@ -1,49 +1,113 @@
|
|
| 1 |
-
// services.js - Core Business Logic
|
| 2 |
-
|
| 3 |
-
import { appState, saveState } from './state.js';
|
| 4 |
import { refreshUI, showToast } from './ui.js';
|
|
|
|
| 5 |
|
| 6 |
-
export function handleUpdateStock(productName, quantity) {
|
| 7 |
if (isNaN(quantity) || quantity <= 0) return;
|
| 8 |
const recipe = appState.productRecipes[productName];
|
| 9 |
-
if (!recipe) {
|
|
|
|
|
|
|
|
|
|
| 10 |
|
|
|
|
| 11 |
for (const materialName in recipe) {
|
| 12 |
const required = recipe[materialName] * quantity;
|
| 13 |
const material = appState.materials.find(m => m.name === materialName);
|
| 14 |
if (!material || material.currentStock < required) {
|
| 15 |
-
showToast(`Insufficient materials for ${quantity}x ${productName}.`, 'error');
|
| 16 |
return;
|
| 17 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
}
|
| 19 |
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
}
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
}
|
| 38 |
|
| 39 |
-
export function handleRestock(materialName, quantity) {
|
| 40 |
if (isNaN(quantity) || quantity <= 0) return;
|
| 41 |
const material = appState.materials.find(m => m.name === materialName);
|
| 42 |
if (!material) return;
|
| 43 |
|
| 44 |
-
material.currentStock +
|
| 45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
-
|
| 48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
}
|
|
|
|
| 1 |
+
// services.js - Core Business Logic with Supabase
|
| 2 |
+
import { appState } from './state.js';
|
|
|
|
| 3 |
import { refreshUI, showToast } from './ui.js';
|
| 4 |
+
import { supabase } from './supabaseClient.js';
|
| 5 |
|
| 6 |
+
export async function handleUpdateStock(productName, quantity) {
|
| 7 |
if (isNaN(quantity) || quantity <= 0) return;
|
| 8 |
const recipe = appState.productRecipes[productName];
|
| 9 |
+
if (!recipe) {
|
| 10 |
+
showToast(`Error: No recipe found for ${productName}.`, 'error');
|
| 11 |
+
return;
|
| 12 |
+
}
|
| 13 |
|
| 14 |
+
const stockUpdates = [];
|
| 15 |
for (const materialName in recipe) {
|
| 16 |
const required = recipe[materialName] * quantity;
|
| 17 |
const material = appState.materials.find(m => m.name === materialName);
|
| 18 |
if (!material || material.currentStock < required) {
|
| 19 |
+
showToast(`Insufficient materials for ${quantity}x ${productName}. Needed ${required} of ${materialName}, but only have ${material ? material.currentStock : 0}.`, 'error');
|
| 20 |
return;
|
| 21 |
}
|
| 22 |
+
stockUpdates.push({
|
| 23 |
+
id: material.id,
|
| 24 |
+
newStock: material.currentStock - required
|
| 25 |
+
});
|
| 26 |
}
|
| 27 |
|
| 28 |
+
showToast(`Producing ${quantity}x ${productName}...`, 'info');
|
| 29 |
+
|
| 30 |
+
try {
|
| 31 |
+
for (const update of stockUpdates) {
|
| 32 |
+
const { error } = await supabase
|
| 33 |
+
.from('materials')
|
| 34 |
+
.update({ current_stock: update.newStock, updated_at: new Date().toISOString() })
|
| 35 |
+
.eq('id', update.id);
|
| 36 |
+
if (error) throw error;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
const { error: logError } = await supabase
|
| 40 |
+
.from('production_log')
|
| 41 |
+
.insert({ product_name: productName, quantity: quantity });
|
| 42 |
+
if (logError) throw logError;
|
| 43 |
+
|
| 44 |
+
for (const update of stockUpdates) {
|
| 45 |
+
const material = appState.materials.find(m => m.id === update.id);
|
| 46 |
+
if (material) material.currentStock = update.newStock;
|
| 47 |
}
|
| 48 |
+
appState.productionLog.unshift({ productName, quantity, date: new Date().toISOString() });
|
| 49 |
+
|
| 50 |
+
refreshUI();
|
| 51 |
+
showToast(`Produced ${quantity}x ${productName}.`, 'success');
|
| 52 |
+
|
| 53 |
+
document.querySelectorAll('.dashboard-card').forEach(card => {
|
| 54 |
+
const h3 = card.querySelector('h3');
|
| 55 |
+
if (h3 && h3.textContent === productName) {
|
| 56 |
+
card.querySelector('input').value = '0';
|
| 57 |
+
}
|
| 58 |
+
});
|
| 59 |
+
|
| 60 |
+
} catch (error) {
|
| 61 |
+
showToast(`Production failed: ${error.message}`, 'error');
|
| 62 |
+
}
|
| 63 |
}
|
| 64 |
|
| 65 |
+
export async function handleRestock(materialName, quantity) {
|
| 66 |
if (isNaN(quantity) || quantity <= 0) return;
|
| 67 |
const material = appState.materials.find(m => m.name === materialName);
|
| 68 |
if (!material) return;
|
| 69 |
|
| 70 |
+
const newStock = material.currentStock + quantity;
|
| 71 |
+
|
| 72 |
+
try {
|
| 73 |
+
const { data, error } = await supabase
|
| 74 |
+
.from('materials')
|
| 75 |
+
.update({ current_stock: newStock, updated_at: new Date().toISOString() })
|
| 76 |
+
.eq('id', material.id)
|
| 77 |
+
.select();
|
| 78 |
+
|
| 79 |
+
if (error) throw error;
|
| 80 |
+
|
| 81 |
+
material.currentStock = data[0].current_stock;
|
| 82 |
+
showToast(`Restocked ${quantity} ${material.unit} of ${materialName}.`, 'success');
|
| 83 |
+
refreshUI();
|
| 84 |
+
} catch (error) {
|
| 85 |
+
showToast(`Restock failed: ${error.message}`, 'error');
|
| 86 |
+
}
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
export async function handleSetStock(materialName, newStock) {
|
| 90 |
+
if (isNaN(newStock) || newStock < 0) {
|
| 91 |
+
showToast('Stock must be a valid positive number.', 'error');
|
| 92 |
+
refreshUI();
|
| 93 |
+
return;
|
| 94 |
+
}
|
| 95 |
+
const material = appState.materials.find(m => m.name === materialName);
|
| 96 |
+
if (!material) return;
|
| 97 |
|
| 98 |
+
try {
|
| 99 |
+
const { data, error } = await supabase
|
| 100 |
+
.from('materials')
|
| 101 |
+
.update({ current_stock: newStock, updated_at: new Date().toISOString() })
|
| 102 |
+
.eq('id', material.id)
|
| 103 |
+
.select();
|
| 104 |
+
|
| 105 |
+
if (error) throw error;
|
| 106 |
+
|
| 107 |
+
material.currentStock = data[0].current_stock;
|
| 108 |
+
showToast(`Stock for ${materialName} set to ${newStock}.`, 'success');
|
| 109 |
+
refreshUI();
|
| 110 |
+
} catch (error) {
|
| 111 |
+
showToast(`Failed to set stock: ${error.message}`, 'error');
|
| 112 |
+
}
|
| 113 |
}
|