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