[Update] Minor bug fixed
This commit is contained in:
parent
8674ec9828
commit
70c15edc27
@ -46,20 +46,20 @@
|
|||||||
@click="openMovePopup(item)">
|
@click="openMovePopup(item)">
|
||||||
<!-- Gambar & Info Produk -->
|
<!-- Gambar & Info Produk -->
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<img v-if="item.produk.foto?.length" :src="item.produk.foto[0].url"
|
<img v-if="item.produk?.foto?.length" :src="item.produk?.foto[0].url"
|
||||||
class="size-12 object-cover rounded"
|
class="size-12 object-cover rounded"
|
||||||
@error="handleImageError" />
|
@error="handleImageError" />
|
||||||
<div class="size-12 bg-gray-200 rounded flex items-center justify-center" v-else>
|
<div class="size-12 bg-gray-200 rounded flex items-center justify-center" v-else>
|
||||||
<i class="fas fa-image text-gray-400"></i>
|
<i class="fas fa-image text-gray-400"></i>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="font-semibold text-D">{{ item.produk.nama }}</p>
|
<p class="font-semibold text-D">{{ item.produk?.nama }}</p>
|
||||||
<p class="text-sm text-gray-500 font-semibold">{{ item.kode_item }}</p>
|
<p class="text-sm text-gray-500 font-semibold">{{ item.kode_item }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Berat -->
|
<!-- Berat -->
|
||||||
<span class="font-medium text-D">{{ item.produk.berat }}g</span>
|
<span class="font-medium text-D">{{ item.produk?.berat }}g</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -191,7 +191,9 @@ const qrCodeUrl = computed(() => {
|
|||||||
|
|
||||||
// Computed untuk statistik
|
// Computed untuk statistik
|
||||||
const totalWeight = computed(() => {
|
const totalWeight = computed(() => {
|
||||||
const total = filteredItems.value.reduce((sum, item) => sum + (item.produk.berat || 0), 0);
|
const total = filteredItems.value.reduce((sum, item) => {
|
||||||
|
return sum + (item?.produk?.berat || 0);
|
||||||
|
}, 0);
|
||||||
return total.toFixed(2);
|
return total.toFixed(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -331,8 +333,7 @@ const refreshData = async () => {
|
|||||||
|
|
||||||
// Filter hanya item yang ada di brankas (id_nampan = null atau tidak ada)
|
// Filter hanya item yang ada di brankas (id_nampan = null atau tidak ada)
|
||||||
items.value = itemRes.data.filter(item => !item.id_nampan);
|
items.value = itemRes.data.filter(item => !item.id_nampan);
|
||||||
trays.value = trayRes.data;
|
trays.value = trayRes.data;
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error fetching data:", err);
|
console.error("Error fetching data:", err);
|
||||||
alert.value = { error: err.response?.data?.message || "Gagal mengambil data" };
|
alert.value = { error: err.response?.data?.message || "Gagal mengambil data" };
|
||||||
|
|||||||
@ -31,7 +31,14 @@
|
|||||||
<!-- Input Harga Jual -->
|
<!-- Input Harga Jual -->
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-sm font-medium text-D">Harga Jual</label>
|
<label class="block text-sm font-medium text-D">Harga Jual</label>
|
||||||
<InputField v-model="hargaJual" type="number" placeholder="Masukkan Harga Jual" />
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="hargaJualFormatted"
|
||||||
|
@input="formatHargaInput"
|
||||||
|
@keypress="onlyNumbers"
|
||||||
|
placeholder="Masukkan Harga Jual"
|
||||||
|
class="bg-A focus:outline-none focus:border-C focus:ring focus:ring-D focus:ring-opacity-50 p-2 w-full rounded-md border border-B shadow-sm sm:text-sm"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tombol Aksi -->
|
<!-- Tombol Aksi -->
|
||||||
@ -120,6 +127,7 @@ const kodeItem = ref("");
|
|||||||
const info = ref("");
|
const info = ref("");
|
||||||
const error = ref("");
|
const error = ref("");
|
||||||
const hargaJual = ref(null);
|
const hargaJual = ref(null);
|
||||||
|
const hargaJualFormatted = ref("");
|
||||||
const item = ref(null);
|
const item = ref(null);
|
||||||
const loadingItem = ref(false);
|
const loadingItem = ref(false);
|
||||||
const pesanan = ref([]);
|
const pesanan = ref([]);
|
||||||
@ -131,6 +139,45 @@ const showStruk = ref(false);
|
|||||||
let errorTimeout = null;
|
let errorTimeout = null;
|
||||||
let infoTimeout = null;
|
let infoTimeout = null;
|
||||||
|
|
||||||
|
// Format angka dengan pemisah ribuan
|
||||||
|
const formatNumber = (num) => {
|
||||||
|
if (!num) return "";
|
||||||
|
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Menghapus format dan mengambil angka asli
|
||||||
|
const unformatNumber = (str) => {
|
||||||
|
if (!str) return null;
|
||||||
|
const cleaned = str.replace(/\./g, "");
|
||||||
|
const number = parseInt(cleaned);
|
||||||
|
return isNaN(number) ? null : number;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handler untuk format input harga
|
||||||
|
const formatHargaInput = (event) => {
|
||||||
|
const value = event.target.value;
|
||||||
|
// Hapus semua karakter selain angka
|
||||||
|
const cleanValue = value.replace(/\D/g, "");
|
||||||
|
|
||||||
|
if (cleanValue) {
|
||||||
|
// Format dengan pemisah ribuan
|
||||||
|
const formatted = formatNumber(cleanValue);
|
||||||
|
hargaJualFormatted.value = formatted;
|
||||||
|
hargaJual.value = parseInt(cleanValue);
|
||||||
|
} else {
|
||||||
|
hargaJualFormatted.value = "";
|
||||||
|
hargaJual.value = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hanya izinkan angka saat mengetik
|
||||||
|
const onlyNumbers = (event) => {
|
||||||
|
const char = String.fromCharCode(event.which);
|
||||||
|
if (!/[0-9]/.test(char)) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const inputItem = async () => {
|
const inputItem = async () => {
|
||||||
if (!kodeItem.value) return;
|
if (!kodeItem.value) return;
|
||||||
|
|
||||||
@ -149,6 +196,8 @@ const inputItem = async () => {
|
|||||||
});
|
});
|
||||||
item.value = response.data;
|
item.value = response.data;
|
||||||
hargaJual.value = item.value.produk.harga_jual;
|
hargaJual.value = item.value.produk.harga_jual;
|
||||||
|
// Format harga untuk tampilan
|
||||||
|
hargaJualFormatted.value = formatNumber(item.value.produk.harga_jual);
|
||||||
|
|
||||||
console.log(item.value);
|
console.log(item.value);
|
||||||
|
|
||||||
@ -167,6 +216,7 @@ const inputItem = async () => {
|
|||||||
error.value = "Item tidak ditemukan";
|
error.value = "Item tidak ditemukan";
|
||||||
info.value = "";
|
info.value = "";
|
||||||
hargaJual.value = null;
|
hargaJual.value = null;
|
||||||
|
hargaJualFormatted.value = "";
|
||||||
item.value = null;
|
item.value = null;
|
||||||
|
|
||||||
errorTimeout = setTimeout(() => {
|
errorTimeout = setTimeout(() => {
|
||||||
@ -201,6 +251,7 @@ const tambahItem = () => {
|
|||||||
// Reset input fields
|
// Reset input fields
|
||||||
kodeItem.value = "";
|
kodeItem.value = "";
|
||||||
hargaJual.value = null;
|
hargaJual.value = null;
|
||||||
|
hargaJualFormatted.value = "";
|
||||||
item.value = null;
|
item.value = null;
|
||||||
info.value = "";
|
info.value = "";
|
||||||
clearTimeout(infoTimeout);
|
clearTimeout(infoTimeout);
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
<div v-if="isOpen"
|
<div v-if="isOpen"
|
||||||
class="text-D pt-serif-regular-italic fixed inset-0 bg-black/75 flex items-center justify-center z-[9999]">
|
class="text-D pt-serif-regular-italic fixed inset-0 bg-black/75 flex items-center justify-center z-[9999]">
|
||||||
<div class="bg-white w-[1224px] h-[528px] rounded-md shadow-lg relative overflow-hidden">
|
<div class="bg-white w-[1224px] h-[528px] rounded-md shadow-lg relative overflow-hidden">
|
||||||
<div class="bg-yellow-500 h-8 w-full">
|
<div class="bg-yellow-500 h-8 w-full">
|
||||||
<div class="bg-D h-6 w-full"></div>
|
<div class="bg-D h-6 w-full"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-6 text-sm flex flex-col h-full relative">
|
<div class="p-6 text-sm flex flex-col h-full relative">
|
||||||
<div class="relative flex items-center justify-between top-0 pb-1 mb-2">
|
<div class="relative flex items-center justify-between top-0 pb-1 mb-2">
|
||||||
@ -19,50 +19,40 @@
|
|||||||
<i class="fab fa-whatsapp text-green-500 text-xl"></i> 08158851178
|
<i class="fab fa-whatsapp text-green-500 text-xl"></i> 08158851178
|
||||||
</p>
|
</p>
|
||||||
<p class=" text-sm">{{ generateTransactionCode() }}</p>
|
<p class=" text-sm">{{ generateTransactionCode() }}</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="absolute inset-x-0 top-[-48px] flex flex-col items-center">
|
<div class="absolute inset-x-0 top-[-48px] flex flex-col items-center">
|
||||||
<img :src="logo" alt="Logo" class="h-40" />
|
<img :src="logo" alt="Logo" class="h-40" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="grid grid-cols-[130px_1fr] gap-y-0 text-xs items-center -mt-5 relative z-10">
|
<div class="grid grid-cols-[130px_1fr] gap-y-0 text-xs items-center -mt-5 relative z-10">
|
||||||
<div class="text-right font-semibold pr-3">Tanggal :</div>
|
<div class="text-right font-semibold pr-3">Tanggal :</div>
|
||||||
|
|
||||||
<p class="mt-1 text-left pl-2">{{ getCurrentDate() }}</p>
|
<p class="mt-1 text-left pl-2">{{ getCurrentDate() }}</p>
|
||||||
|
|
||||||
<div class="text-right font-semibold pr-3">Nama :</div>
|
<div class="text-right font-semibold pr-3">Nama :</div>
|
||||||
|
|
||||||
<inputField v-model="namaPembeli" class="h-7 text-sm rounded bg-blue-200 w-full" />
|
<inputField v-model="namaPembeli" class="h-7 text-sm rounded bg-blue-200 w-full" />
|
||||||
|
|
||||||
|
|
||||||
<div class="text-right font-semibold pr-3">Alamat :</div>
|
<div class="text-right font-semibold pr-3">Alamat :</div>
|
||||||
|
|
||||||
<inputField v-model="alamat" class="h-7 px-2 text-sm rounded bg-blue-200 w-full" />
|
<inputField v-model="alamat" class="h-7 px-2 text-sm rounded bg-blue-200 w-full" />
|
||||||
|
|
||||||
<div class="text-right font-semibold pr-3">No.Hp :</div>
|
<div class="text-right font-semibold pr-3">No.Hp :</div>
|
||||||
|
|
||||||
<inputField v-model="nomorTelepon" class="h-7 px-2 text-sm rounded bg-blue-200 w-full" />
|
<inputField v-model="nomorTelepon" class="h-7 px-2 text-sm rounded bg-blue-200 w-full" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="flex justify-between items-center mb-1 w-full">
|
<div class="flex justify-between items-center mb-1 w-full">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<img :src="logo_bca" alt="Logo_bca" class="h-5" />
|
<img :src="logo_bca" alt="Logo_bca" class="h-5" />
|
||||||
<img :src="logo_bri" alt="Logo_bri" class="h-5" />
|
<img :src="logo_bri" alt="Logo_bri" class="h-5" />
|
||||||
<img :src="logo_bni" alt="Logo_bni" class="h-5" />
|
<img :src="logo_bni" alt="Logo_bni" class="h-5" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<img :src="logo_mastercard" alt="Logo_mastercard" class="h-5" />
|
<img :src="logo_mastercard" alt="Logo_mastercard" class="h-5" />
|
||||||
<img :src="logo_visa" alt="Logo_visa" class="h-5" />
|
<img :src="logo_visa" alt="Logo_visa" class="h-5" />
|
||||||
<img :src="logo_mandiri" alt="Logo_mandiri" class="h-5" />
|
<img :src="logo_mandiri" alt="Logo_mandiri" class="h-5" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table class="w-full border-D text-sm table-fixed border-b">
|
<table class="w-full border-D text-sm table-fixed border-b">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="border-b border-t border-D">
|
<tr class="border-b border-t border-D">
|
||||||
<th class="w-[40px] border-r text-lg border-D">Jml</th>
|
<th class="w-[40px] border-r text-lg border-D">Jml</th>
|
||||||
@ -88,7 +78,7 @@
|
|||||||
</template>
|
</template>
|
||||||
{{ item.produk?.nama || '' }}
|
{{ item.produk?.nama || '' }}
|
||||||
</td>
|
</td>
|
||||||
<td class="border-r border-D">{{ item.nampan?.nama || 'Brankas' }}</td>
|
<td class="border-r border-D">{{ item.produk.nama ? (item.nampan?.nama || 'Brankas') : '' }}</td>
|
||||||
<td class="border-r border-D">
|
<td class="border-r border-D">
|
||||||
<span v-if="item.produk?.berat">{{ item.produk.berat }}g</span>
|
<span v-if="item.produk?.berat">{{ item.produk.berat }}g</span>
|
||||||
</td>
|
</td>
|
||||||
@ -132,15 +122,10 @@
|
|||||||
<p class="text-red-500 text-xs">diluar harga jual</p>
|
<p class="text-red-500 text-xs">diluar harga jual</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center w-40">
|
<div class="flex items-center w-40">
|
||||||
<p>Rp</p>
|
<p>Rp</p>
|
||||||
<input
|
<input type="text" v-model="ongkosBikinFormatted" @input="formatInput"
|
||||||
type="text"
|
class="h-7 px-2 text-sm rounded bg-blue-200 text-left w-full" />
|
||||||
v-model="ongkosBikinFormatted"
|
</div>
|
||||||
@input="formatInput"
|
|
||||||
class="h-7 px-2 text-sm rounded bg-blue-200 text-left w-full"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Total -->
|
<!-- Total -->
|
||||||
@ -170,7 +155,30 @@
|
|||||||
<p class="absolute p-8 bottom-0 left-0 w-full text-left text-xs bg-D text-white py-1">
|
<p class="absolute p-8 bottom-0 left-0 w-full text-left text-xs bg-D text-white py-1">
|
||||||
Terima kasih sudah berbelanja dengan kami
|
Terima kasih sudah berbelanja dengan kami
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Simple Toast Alert -->
|
||||||
|
<div v-if="showToast"
|
||||||
|
class="fixed top-4 left-1/2 transform -translate-x-1/2 z-[10001]
|
||||||
|
transition-all duration-300 ease-in-out"
|
||||||
|
:class="toastClasses">
|
||||||
|
<div class="flex items-center gap-2 px-4 py-3 rounded-lg shadow-lg max-w-sm">
|
||||||
|
<!-- Icon -->
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<svg v-if="toastType === 'error'" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
<svg v-else-if="toastType === 'success'" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
<svg v-else class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Message -->
|
||||||
|
<p class="text-sm font-medium">{{ toastMessage }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -204,7 +212,6 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const emit = defineEmits(['close', 'confirm'])
|
const emit = defineEmits(['close', 'confirm'])
|
||||||
|
|
||||||
const namaPembeli = ref('')
|
const namaPembeli = ref('')
|
||||||
@ -213,7 +220,22 @@ const alamat = ref('')
|
|||||||
const ongkosBikin = ref(0)
|
const ongkosBikin = ref(0)
|
||||||
const selectedSales = ref(null)
|
const selectedSales = ref(null)
|
||||||
const salesOptions = ref([])
|
const salesOptions = ref([])
|
||||||
const ongkosBikinFormatted = ref("");
|
const ongkosBikinFormatted = ref("")
|
||||||
|
|
||||||
|
// Simple Toast State
|
||||||
|
const showToast = ref(false)
|
||||||
|
const toastType = ref('error') // 'error', 'success', 'info'
|
||||||
|
const toastMessage = ref('')
|
||||||
|
|
||||||
|
const toastClasses = computed(() => {
|
||||||
|
const baseClasses = 'text-white'
|
||||||
|
const typeClasses = {
|
||||||
|
error: 'bg-red-500',
|
||||||
|
success: 'bg-green-500',
|
||||||
|
info: 'bg-blue-500'
|
||||||
|
}
|
||||||
|
return `${baseClasses} ${typeClasses[toastType.value]}`
|
||||||
|
})
|
||||||
|
|
||||||
const grandTotal = computed(() => {
|
const grandTotal = computed(() => {
|
||||||
return props.total + (ongkosBikin.value || 0)
|
return props.total + (ongkosBikin.value || 0)
|
||||||
@ -238,6 +260,17 @@ const generateTransactionCode = () => {
|
|||||||
return `TRS-${timestamp}`
|
return `TRS-${timestamp}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simple Toast Function
|
||||||
|
const showSimpleToast = (type, message, duration = 3000) => {
|
||||||
|
toastType.value = type
|
||||||
|
toastMessage.value = message
|
||||||
|
showToast.value = true
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
showToast.value = false
|
||||||
|
}, duration)
|
||||||
|
}
|
||||||
|
|
||||||
const fetchSales = async () => {
|
const fetchSales = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get('/api/sales', {
|
const response = await axios.get('/api/sales', {
|
||||||
@ -251,7 +284,6 @@ const fetchSales = async () => {
|
|||||||
label: sales.nama
|
label: sales.nama
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
||||||
if (salesOptions.value.length > 0) {
|
if (salesOptions.value.length > 0) {
|
||||||
selectedSales.value = salesOptions.value[0].value
|
selectedSales.value = salesOptions.value[0].value
|
||||||
}
|
}
|
||||||
@ -261,28 +293,26 @@ const fetchSales = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleSimpan = () => {
|
const handleSimpan = () => {
|
||||||
|
|
||||||
if (!namaPembeli.value.trim()) {
|
if (!namaPembeli.value.trim()) {
|
||||||
alert('Nama pembeli harus diisi!')
|
showSimpleToast('error', 'Nama pembeli harus diisi!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nomorTelepon.value.trim()) {
|
if (!nomorTelepon.value.trim()) {
|
||||||
alert('Nomor telepon harus diisi!')
|
showSimpleToast('error', 'Nomor telepon harus diisi!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!alamat.value.trim()) {
|
if (!alamat.value.trim()) {
|
||||||
alert('Alamat harus diisi!')
|
showSimpleToast('error', 'Alamat harus diisi!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!selectedSales.value) {
|
if (!selectedSales.value) {
|
||||||
alert('Sales harus dipilih!')
|
showSimpleToast('error', 'Sales harus dipilih!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
simpanTransaksi({
|
simpanTransaksi({
|
||||||
id_sales: selectedSales.value,
|
id_sales: selectedSales.value,
|
||||||
nama_pembeli: namaPembeli.value,
|
nama_pembeli: namaPembeli.value,
|
||||||
@ -294,7 +324,6 @@ const handleSimpan = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const simpanTransaksi = async (dataTransaksi) => {
|
const simpanTransaksi = async (dataTransaksi) => {
|
||||||
console.log('Data transaksi yang akan disimpan:', dataTransaksi);
|
console.log('Data transaksi yang akan disimpan:', dataTransaksi);
|
||||||
|
|
||||||
@ -305,15 +334,19 @@ const simpanTransaksi = async (dataTransaksi) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
showSimpleToast('success', 'Transaksi berhasil disimpan!', 2000)
|
||||||
props.pesanan.value = [];
|
|
||||||
props.isOpen = false;
|
// Delay untuk memberikan waktu user membaca notifikasi
|
||||||
|
setTimeout(() => {
|
||||||
window.location.reload();
|
props.pesanan.value = [];
|
||||||
|
props.isOpen = false;
|
||||||
|
window.location.reload();
|
||||||
|
}, 2200);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error saving transaksi:', error);
|
console.error('Error saving transaksi:', error);
|
||||||
alert('Error menyimpan transaksi: ' + (error.response?.data?.message || error.message));
|
const errorMessage = error.response?.data?.message || error.message || 'Terjadi kesalahan saat menyimpan transaksi';
|
||||||
|
showSimpleToast('error', `Error: ${errorMessage}`, 4000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -332,18 +365,12 @@ const pesananMinimal = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function formatInput(e) {
|
function formatInput(e) {
|
||||||
|
|
||||||
let value = e.target.value.replace(/\D/g, "");
|
let value = e.target.value.replace(/\D/g, "");
|
||||||
|
|
||||||
|
|
||||||
ongkosBikin.value = value ? parseInt(value, 10) : null;
|
ongkosBikin.value = value ? parseInt(value, 10) : null;
|
||||||
|
|
||||||
|
|
||||||
ongkosBikinFormatted.value = value
|
ongkosBikinFormatted.value = value
|
||||||
? new Intl.NumberFormat("id-ID").format(value)
|
? new Intl.NumberFormat("id-ID").format(value)
|
||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -353,4 +380,4 @@ function formatInput(e) {
|
|||||||
font-family: "PT Serif", serif;
|
font-family: "PT Serif", serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -61,18 +61,18 @@
|
|||||||
>
|
>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<img
|
<img
|
||||||
v-if="item.produk.foto && item.produk.foto.length > 0"
|
v-if="item.produk?.foto && item.produk?.foto.length > 0"
|
||||||
:src="item.produk.foto[0].url"
|
:src="item.produk?.foto[0].url"
|
||||||
alt="foto produk"
|
alt="foto produk"
|
||||||
class="size-12 object-cover rounded"
|
class="size-12 object-cover rounded"
|
||||||
/>
|
/>
|
||||||
<div class="text-D">
|
<div class="text-D">
|
||||||
<p class="text-sm">{{ item.produk.nama }}</p>
|
<p class="text-sm">{{ item.produk?.nama }}</p>
|
||||||
<p class="text-sm font-medium">{{ item.kode_item }}</p>
|
<p class="text-sm font-medium">{{ item.kode_item }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="font-medium">{{ item.produk.berat }}g</span>
|
<span class="font-medium">{{ item.produk?.berat }}g</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -107,7 +107,7 @@
|
|||||||
{{ selectedItem.kode_item }}
|
{{ selectedItem.kode_item }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center text-gray-700 font-medium mb-3">
|
<div class="text-center text-gray-700 font-medium mb-3">
|
||||||
{{ selectedItem.produk.nama }}
|
{{ selectedItem.produk?.nama }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-center mb-4">
|
<div class="flex justify-center mb-4">
|
||||||
@ -248,7 +248,7 @@ const saveMove = async () => {
|
|||||||
// Hitung total berat
|
// Hitung total berat
|
||||||
const totalWeight = (tray) => {
|
const totalWeight = (tray) => {
|
||||||
if (!tray.items) return 0;
|
if (!tray.items) return 0;
|
||||||
const total = tray.items.reduce((sum, item) => sum + (item.produk.berat || 0), 0);
|
const total = tray.items.reduce((sum, item) => sum + (item.produk?.berat || 0), 0);
|
||||||
return total.toFixed(2);
|
return total.toFixed(2);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user