function ProductPrice({ salesUrl, token }) { const [productNo, setProductNo] = React.useState(''); const [rows, setRows] = React.useState([]); const [rowEdits, setRowEdits] = React.useState({}); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(''); async function showProduct(e) { if (e && e.preventDefault) e.preventDefault(); const needle = (productNo || '').toString().trim(); if (!needle) { setError('Enter a product no'); return; } setError(''); setLoading(true); try { const found = await fetchProduct(needle); if (found.length === 0) { setRows([]); alert('Product not available'); } else { setRows(found); // log current quantities console.log('Current quantities for', needle, found.map(r => ({ productNo: r.productNo || r.productId, qty: r.qty != null ? r.qty : (r.centralQty != null ? r.centralQty : 0) }))); } } catch (err) { console.error('ProductPrice fetch error', err); alert('Failed to fetch product details'); } finally { setLoading(false); } } async function fetchProduct(needle) { const base = (salesUrl || '').replace(/\/$/, ''); const url = base + '/api/branch-stock?productNo=' + encodeURIComponent(needle); const res = await fetch(url, { method: 'GET', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', ...(token ? { Authorization: 'Bearer ' + token } : {}) } }); const data = await res.json(); if (!data || !data.success) return []; return Array.isArray(data.rows) ? data.rows : []; } const currency = (n) => new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR', maximumFractionDigits: 2 }).format(n || 0); async function saveWhatsappStock(key, row) { try { const edit = rowEdits[key] || {}; const supplyQty = Number(edit.supplyQty || 0); const sellPercent = Number(edit.sellPercent || 0); // compute selling price same as BranchSupply.jsx: pct ? cost * (1 + pct/100) : row.sellingPrice const cost = Number(row.costPrice ?? row.cost ?? row.totalCostPrice ?? row.totalCost ?? 0); const rawSelling = sellPercent ? (cost * (1 + sellPercent / 100)) : Number(row.sellingPrice || 0); const sellingPrice = Number(Number(rawSelling || 0).toFixed(2)); // set saving flag setRowEdits(s => ({ ...s, [key]: { ...(s[key] || {}), saving: true } })); const base = (salesUrl || '').replace(/\/$/, ''); const payload = { productNo: row.productNo || row.productId || '', productName: row.productName || '', brand: row.brand || '', model: row.model || '', supplyQty, sellPercent, sellingPrice, costPrice: cost, totalCost: Number(row.totalCostPrice || row.totalCost || 0) }; // log current qty before transfer const currentQty = (row.qty != null) ? row.qty : (row.centralQty != null ? row.centralQty : 0); console.log('Before transfer:', { productNo: payload.productNo, currentQty }); const res = await fetch(base + '/api/whatsapp-stock', { method: 'POST', headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: 'Bearer ' + token } : {}) }, body: JSON.stringify(payload) }); const data = await res.json(); if (!res.ok || !data.success) { alert(data.message || 'Save failed'); } else { alert(data.message || 'Saved'); // reflect saved state setRowEdits(s => ({ ...s, [key]: { ...s[key], saving: false } })); // fetch updated product and log new qty try { const refreshed = await fetchProduct(payload.productNo); const updated = refreshed.find(rr => (rr.productNo || rr.productId) === payload.productNo); const newQty = updated ? (updated.qty != null ? updated.qty : (updated.centralQty != null ? updated.centralQty : 0)) : null; console.log('Transfer completed:', { productNo: payload.productNo, supplyQty, before: currentQty, after: newQty }); } catch (e) { console.error('Failed to fetch refreshed product', e); } } } catch (err) { console.error('saveWhatsappStock error', err); alert('Save failed'); setRowEdits(s => ({ ...s, [key]: { ...s[key], saving: false } })); } } return (
Search and manage product pricing for WhatsApp inventory
Set pricing and supply quantities for WhatsApp inventory
| No. | Product No | Product Name | Brand | Model | Stock Qty | Total Cost | Selling Price | Supply Qty | Action |
|---|---|---|---|---|---|---|---|---|---|
| {i + 1} |
{r.productNo || '-'}
|
{r.productName || '-'}
|
{r.brand || '-'} | {r.model || '-'} | {availableQty} | {currency(Number(r.totalCostPrice || r.totalCost || 0))} |
setRowEdits(s => ({ ...s, [key]: { ...edit, sellPercent: e.target.value } }))}
/>
%
{calculatedPrice ? currency(Number(calculatedPrice.toFixed(2))) : '-'}
|
setRowEdits(s => ({ ...s, [key]: { ...edit, supplyQty: e.target.value } }))}
/>
{isOverSupply && (
Exceeds stock
)}
|