diff --git a/src/pages/master/sparepart/component/DetailSparepart.jsx b/src/pages/master/sparepart/component/DetailSparepart.jsx
index 132b508..b58ab26 100644
--- a/src/pages/master/sparepart/component/DetailSparepart.jsx
+++ b/src/pages/master/sparepart/component/DetailSparepart.jsx
@@ -43,9 +43,10 @@ const DetailSparepart = (props) => {
sparepart_description: '',
sparepart_model: '',
sparepart_item_type: null,
+ sparepart_qty: 0,
sparepart_unit: '',
sparepart_merk: '',
- sparepart_stok: '0',
+ sparepart_stok: 'Not Available',
sparepart_foto: '',
};
@@ -224,11 +225,14 @@ const DetailSparepart = (props) => {
if (formData.sparepart_merk && formData.sparepart_merk.trim() !== '') {
payload.sparepart_merk = formData.sparepart_merk;
}
- if (formData.sparepart_stok && formData.sparepart_stok.trim() !== '') {
- payload.sparepart_stok = formData.sparepart_stok.toString();
- } else {
- payload.sparepart_stok = '0'; // Set default value jika tidak diisi
- }
+ // sparepart_qty disimpan sebagai angka kuantitas
+ // Untuk menghindari error validasi, jika qty 0, kita tetap kirim 1 ke backend tapi statusnya "Not Available"
+ const qty = parseInt(formData.sparepart_qty) || 0;
+ const actualQty = qty > 0 ? qty : 1; // Kirim minimal 1 ke backend
+ payload.sparepart_qty = actualQty;
+
+ // sparepart_stok ditentukan otomatis berdasarkan qty sebenarnya
+ payload.sparepart_stok = qty > 0 ? 'Available' : 'Not Available';
// Sertakan sparepart_foto hanya jika nilainya tidak kosong, agar tidak memicu validasi
if (imageUrl && imageUrl.trim() !== '') {
payload.sparepart_foto = imageUrl;
@@ -496,12 +500,12 @@ const DetailSparepart = (props) => {
- Stock
+ Qty
@@ -516,6 +520,20 @@ const DetailSparepart = (props) => {
readOnly={props.readOnly}
/>
+
+ Status
+ 0 ? 'Available' : 'Not Available'}
+ readOnly={true}
+ placeholder="Auto calculated"
+ style={{
+ backgroundColor: '#f5f5f5',
+ cursor: 'not-allowed',
+ color: parseInt(formData.sparepart_qty) > 0 ? '#52c41a' : '#ff4d4f'
+ }}
+ />
+
diff --git a/src/pages/master/sparepart/component/ListSparepart.jsx b/src/pages/master/sparepart/component/ListSparepart.jsx
index d71cc72..fc290be 100644
--- a/src/pages/master/sparepart/component/ListSparepart.jsx
+++ b/src/pages/master/sparepart/component/ListSparepart.jsx
@@ -72,11 +72,18 @@ const columns = (showPreviewModal, showEditModal, showDeleteDialog) => [
render: (sparepart_merk) => sparepart_merk || '-'
},
{
- title: 'Stock',
+ title: 'Qty',
+ dataIndex: 'sparepart_qty',
+ key: 'sparepart_qty',
+ width: '8%',
+ render: (sparepart_qty) => sparepart_qty || '0'
+ },
+ {
+ title: 'Status',
dataIndex: 'sparepart_stok',
key: 'sparepart_stok',
width: '8%',
- render: (sparepart_stok) => sparepart_stok || '0'
+ render: (sparepart_stok) => sparepart_stok || 'Not Available'
},
{
title: 'Action',
diff --git a/src/pages/master/sparepart/component/SparepartCardList.jsx b/src/pages/master/sparepart/component/SparepartCardList.jsx
index 97313f0..d97d7f6 100644
--- a/src/pages/master/sparepart/component/SparepartCardList.jsx
+++ b/src/pages/master/sparepart/component/SparepartCardList.jsx
@@ -37,16 +37,22 @@ const SparepartCardList = ({
return;
}
- const newStock = Number(item.sparepart_stok) + quantityToAdd;
- if (newStock < 0) {
- NotifAlert({ icon: 'error', title: 'Error', message: 'Stock cannot be negative.' });
+ const currentQty = Number(item.sparepart_qty) || 0;
+ const newQty = currentQty + quantityToAdd;
+ if (newQty < 0) {
+ NotifAlert({ icon: 'error', title: 'Error', message: 'Quantity cannot be negative.' });
return;
}
setLoadingQuantities((prev) => ({ ...prev, [item.sparepart_id]: true }));
+ // sparepart_qty disimpan sebagai angka kuantitas
+ // sparepart_stok ditentukan otomatis berdasarkan qty
+ // Untuk menghindari error validasi, jika newQty 0, kita tetap kirim 1 ke backend tapi statusnya "Not Available"
+ const actualQty = newQty > 0 ? newQty : 1; // Kirim minimal 1 ke backend
const payload = {
- sparepart_stok: newStock.toString(), // Convert number to string as required by API
+ sparepart_qty: actualQty,
+ sparepart_stok: newQty > 0 ? 'Available' : 'Not Available', // Otomatis tentukan status berdasarkan newQty asli
};
// Hanya tambahkan field jika nilainya tidak kosong untuk menghindari validasi error
@@ -62,6 +68,12 @@ const SparepartCardList = ({
if (item.sparepart_description && item.sparepart_description.trim() !== '') {
payload.sparepart_description = item.sparepart_description;
}
+ if (item.sparepart_item_type && item.sparepart_item_type !== null) {
+ payload.sparepart_item_type = item.sparepart_item_type;
+ }
+ if (item.sparepart_foto && item.sparepart_foto.trim() !== '') {
+ payload.sparepart_foto = item.sparepart_foto;
+ }
try {
const response = await updateSparepart(item.sparepart_id, payload);
@@ -73,6 +85,16 @@ const SparepartCardList = ({
title: 'Success',
message: 'Stock updated successfully.',
});
+
+ // Cek apakah qty baru kurang dari 1, tampilkan alert
+ if (newQty < 1) {
+ NotifAlert({
+ icon: 'warning',
+ title: 'Low Stock',
+ message: `Warning: Sparepart "${item.sparepart_name}" is out of stock. Please restock immediately.`,
+ });
+ }
+
if (onStockUpdate) {
onStockUpdate();
}
@@ -139,7 +161,8 @@ const SparepartCardList = ({
style={{
backgroundColor: '#f0f0f0',
width: '100%',
- paddingTop: '100%', /* Ini membuat tinggi sama dengan lebar (aspect ratio 1:1) */
+ paddingTop:
+ '100%' /* Ini membuat tinggi sama dengan lebar (aspect ratio 1:1) */,
position: 'relative',
borderRadius: '4px',
overflow: 'hidden',
@@ -153,30 +176,50 @@ const SparepartCardList = ({
imgSrc = item.sparepart_foto;
} else {
// Gunakan format file URL seperti di brandDevice
- const fileName = item.sparepart_foto.split('/').pop();
+ const fileName = item.sparepart_foto
+ .split('/')
+ .pop();
// Jika filename adalah default file, gunakan dari public assets
- if (fileName === 'defaultSparepartImg.jpg') {
+ if (
+ fileName === 'defaultSparepartImg.jpg'
+ ) {
imgSrc = `/assets/defaultSparepartImg.jpg`;
} else {
// Gunakan API getFileUrl untuk mendapatkan URL yang benar untuk file upload
- const token = localStorage.getItem('token');
- const baseURL = import.meta.env.VITE_API_SERVER || '';
- imgSrc = `${baseURL}/file-uploads/images/${encodeURIComponent(fileName)}${token ? `?token=${encodeURIComponent(token)}` : ''}`;
+ const token =
+ localStorage.getItem('token');
+ const baseURL =
+ import.meta.env.VITE_API_SERVER ||
+ '';
+ imgSrc = `${baseURL}/file-uploads/images/${encodeURIComponent(
+ fileName
+ )}${
+ token
+ ? `?token=${encodeURIComponent(
+ token
+ )}`
+ : ''
+ }`;
}
}
- console.log('Image path being constructed:', imgSrc);
+ console.log(
+ 'Image path being constructed:',
+ imgSrc
+ );
} else {
imgSrc = 'https://via.placeholder.com/150';
}
return (
-
+
![{item[header]}]({imgSrc})
{
- console.error('Image failed to load:', imgSrc);
- e.target.src = 'https://via.placeholder.com/150';
+ console.error(
+ 'Image failed to load:',
+ imgSrc
+ );
+ e.target.src =
+ 'https://via.placeholder.com/150';
}}
- onLoad={() => console.log('Image loaded successfully:', imgSrc)}
+ onLoad={() =>
+ console.log(
+ 'Image loaded successfully:',
+ imgSrc
+ )
+ }
/>
);
@@ -249,8 +301,9 @@ const SparepartCardList = ({
>
{item[header]}
-
- Available Stock: {item.sparepart_stok || '0'}
+ Qty: {item.sparepart_qty || 0}
+
+ Stok: {item.sparepart_stok || 'Not Available'}