MIF_E31211908/resources/views/page/dashboard/pembelian/tambah.blade.php

528 lines
23 KiB
PHP

@extends('layout.app')
@section('content')
<div class="grid lg:grid-cols-2 md:grid-cols-1 sm:grid-cols-1 gap-4">
<div class="bg-white rounded-lg w-full h-fit p-5">
<div class="mb-6 flex bg-gray-50 rounded-lg p-2.5 border border-gray-300">
<div class="flex items-center mr-3">
<svg class="w-4 h-4 text-gray-500" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
</svg>
</div>
<input type="text" name="kode" id="kode" class="block text-sm text-gray-900 bg-gray-50 focus:outline-none w-full" placeholder="Cari Barang" autofocus>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 3.75 9.375v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 13.5 9.375v-4.5Z" />
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 6.75h.75v.75h-.75v-.75ZM6.75 16.5h.75v.75h-.75v-.75ZM16.5 6.75h.75v.75h-.75v-.75ZM13.5 13.5h.75v.75h-.75v-.75ZM13.5 19.5h.75v.75h-.75v-.75ZM19.5 13.5h.75v.75h-.75v-.75ZM19.5 19.5h.75v.75h-.75v-.75ZM16.5 16.5h.75v.75h-.75v-.75Z" />
</svg>
</div>
<div id="cameraModal" class="fixed top-0 left-0 w-full h-full flex items-center justify-center bg-black bg-opacity-50 hidden">
<div class="bg-white p-8 rounded-lg">
<video id="preview" class="w-full"></video>
<button id="closeCameraModal" class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">Close</button>
</div>
</div>
<div id="searchResults" class="absolute mt-1 bg-white border border-gray-300 rounded-lg shadow-md hidden w-1/2 max-h-48 overflow-y-auto z-10"></div>
<div class="mb-6" id="preview">
<div class="mb-6">
<select id="supplier" name="supllier" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" required>
<option value="" disabled selected>Pilih Supplier</option>
@foreach ($data['supplier'] as $item )
<option value="{{ $item->id }}">{{ $item->nama_supplier }}</option>
@endforeach
</select>
</div>
<div class="mb-6">
<input placeholder="Kode Barang" type="text" id="previewKode" class="bg-gray-200 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" disabled>
</div>
<div class="mb-6">
<input placeholder="Nama Barang" type="text" id="previewNama" class="bg-gray-200 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" disabled>
</div>
<div class="mb-6">
<input placeholder="Harga Barang" type="text" id="previewHarga" class="bg-gray-200 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" disabled>
</div>
<button onclick="window.history.back()" class="bg-red-500 text-white py-2 px-4 rounded-lg cursor-pointer">Batal</button>
<button class="bg-blue-500 text-white py-2 px-4 rounded-lg cursor-pointer" id="tambahBtn">Tambah</button>
<button class="bg-blue-500 text-white py-2 px-4 rounded-lg cursor-pointer" id="selesaiBtn">Selesai</button>
</div>
</div>
<div class="grid grid-cols-1 gap-4 w-full">
<div class="flex justify-between bg-white rounded-lg h-fit p-5">
<div class="p-5 bg-gray-200 h-fit text-2xl rounded-lg font-bold">TOTAL</div>
<div class="bg-yellow-500 text-2xl rounded-lg font-bold w-full h-fit text-right p-5" id="subtotal">IDR 0</div>
</div>
<div id="tableContainer" class="bg-white rounded-lg">
<table id="dataTable" class="text-sm font-thin w-full">
<thead>
<tr class="text-left border-b-2">
<td class="p-5">Kode</td>
<td class="p-5">Nama Barang</td>
<td class="p-5">Harga</td>
<td class="p-5 text-center">Qty</td>
<td class="p-5">Sub Total</td>
<td class="p-5">Aksi</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<div id="modal" class="modal hidden fixed inset-0 z-50 overflow-auto bg-gray-500 bg-opacity-50 flex justify-center items-center">
<div class="modal-content bg-white w-1/2 p-4 rounded-lg">
<div class="bg-[#ee69b1] flex justify-between rounded-lg p-2 mb-2">
<h2 class="text-xl font-bold">Bayar</h2>
<button id="closeModalButton" class="text-white">&times;</button>
</div>
<div class="modal-body">
<form id="formData">
<div class="container mx-auto p-4 bg-gray-100 rounded-lg">
<div class="flex justify-between">
<h1 class="text-xl font-bold">BAYAR</h1>
<div class="flex items-center">
<p class="text-base mr-2">Tanggal</p>
<p class="text-base">{{ now()->format('Y-m-d') }}</p>
</div>
</div>
<div class="mt-4 pt-4">
<div class="grid grid-cols-3 gap-4">
<p class="text-base font-medium">Kasir</p>
<p class="text-base font-medium">{{ Auth::user()->name }}</p>
<p class="text-base font-medium text-right">Total (Rp)</p>
</div>
</div>
<div class="mt-4 pt-4">
<div class="grid grid-cols-2 gap-4">
<p class="text-base font-medium">No. Transaksi</p>
<input type="text" id="noTransaksi" class="text-base" readonly>
<p class="text-base font-medium">Dibayar (Rp)</p>
<input type="number" id="paymentAmount" class="text-base focus:outline-none outline-none bg-red-500 p-2">
<p class="text-base font-medium">Supplier</p>
</div>
</div>
<div class="flex justify-center mt-4">
<button class="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-700">SIMPAN</button>
<button class="ml-4 bg-gray-300 text-gray-700 px-4 py-2 rounded-md hover:bg-gray-400">BATAL</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div id="printContent" style="display: none;">
<h1>Your Print Content Here</h1>
</div>
@endsection
@section('script')
<script>
function addCommas(nStr){
nStr += '';
var x = nStr.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
function removeComas(nilai){
var hasil = nilai.split(',');
var shasil = "";
for (var i = 0; i < hasil.length; i++) {
shasil = shasil +""+ hasil[i];
}
return shasil;
}
$(document).ready(function() {
function debounce(func, delay) {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
func.apply(context, args);
}, delay);
};
}
function handleInputChange() {
const code = $('#kode').val();
const baseUrl = "{{ route('barang.scan', ['kode' => '__KODE__']) }}";
$.ajax({
url: baseUrl.replace('__KODE__', code),
type: 'GET',
contentType: 'application/json',
success: function(response) {
console.log(response);
addToTable(response.kode, response.nama, response.harga_beli, 1);
$('#kode').val('');
},
error: function(xhr, status, error) {
console.error('Error:', error);
}
});
}
function handleInput() {
return;
}
$('#kode').on('input', handleInput);
$('#kode').on('paste', debounce(handleInputChange, 2000));
});
const searchInput = document.getElementById('kode');
const searchResults = document.getElementById('searchResults');
const previewKodeInput = document.getElementById('previewKode');
const previewNamaInput = document.getElementById('previewNama');
const previewHargaInput = document.getElementById('previewHarga');
const tambahBtn = document.getElementById('tambahBtn');
const selesaiBtn = document.getElementById('selesaiBtn');
const dataTable = document.getElementById('dataTable').getElementsByTagName('tbody')[0];
function filterData(data, query) {
return data.filter(item =>
item.kode.toLowerCase().includes(query.toLowerCase()) ||
item.nama.toLowerCase().includes(query.toLowerCase()) ||
item.harga_beli.toString().includes(query.toLowerCase())
);
}
const BASEURL = 'http://127.0.0.1:8000/';
function displayResults(results) {
if (results.length === 0) {
searchResults.innerHTML = '<div class="p-2">No results found</div>';
} else {
const html = results.map(item =>
`<div class="flex justify-between items-center p-2 border-b cursor-pointer" onclick="showPreview('${item.kode}', '${item.nama}','${item.harga_beli}')">
<div class="flex">
<img src="${BASEURL}gambar/${item.gambar}" alt="${item.nama}" class="h-8 w-8 mr-2 border-r-2">
${item.kode} - ${item.nama} - IDR ${addCommas(item.harga_beli)}
</div>
</div>`
).join('');
searchResults.innerHTML = html;
}
}
function showPreview(kode, nama, harga) {
previewKodeInput.value = kode;
previewNamaInput.value = nama;
previewHargaInput.value = "IDR " + addCommas(harga);
}
tambahBtn.addEventListener('click', () => {
const kode = previewKodeInput.value;
const nama = previewNamaInput.value;
const harga = parseInt(removeComas(previewHargaInput.value.replace("IDR ", "")));
if (!kode || !nama || isNaN(harga)) {
alert('Please fill in all fields.');
return;
}
const qty = 1;
addToTable(kode, nama, harga, qty);
});
closeModalButton.addEventListener('click', () => {
closeModal();
});
function getAllItems() {
const items = [];
const rows = dataTable.getElementsByTagName('tr');
for (let i = 0; i < rows.length; i++) {
const kode = rows[i].getElementsByTagName('td')[0].textContent;
const nama = rows[i].getElementsByTagName('td')[1].textContent;
const harga = parseInt(removeComas(rows[i].getElementsByTagName('td')[2].textContent.replace("IDR ", "")));
const qty = parseInt(rows[i].getElementsByTagName('td')[3].querySelector('input').value);
items.push({ kode, nama, harga, qty });
}
return items;
}
selesaiBtn.addEventListener('click', () => {
const total = calculateTotal();
const noTransaksi = generateNoTransaksi();
const items = getAllItems();
displayModal(total, noTransaksi, items);
});
function generateNoTransaksi() {
return 'IDTRN' + Math.floor(Date.now() / 1000);
}
function displayModal(total, noTransaksi, items) {
const modalBody = document.querySelector('.modal-body');
modalBody.innerHTML = `
<div class="container mx-auto p-4 bg-gray-100 rounded-lg">
<div class="flex justify-between">
<h1 class="text-xl font-bold">BAYAR</h1>
<div class="flex items-center">
<p class="text-base mr-2">Tanggal</p>
<p class="text-base">${new Date().toISOString().slice(0, 10)}</p>
</div>
</div>
<div class="border-t border-gray-300 mt-4 pt-4">
<div class="grid grid-cols-2 gap-4">
<p class="text-base font-medium">Operator</p>
<p class="text-base font-medium">{{ Auth::user()->name }}</p>
<p class="text-base font-medium">Total (Rp)</p>
<p class="text-base">IDR ${addCommas(total)}</p>
<p class="text-base">No. Transaksi</p>
<p class="text-base">${noTransaksi}</p>
<p class="text-base font-medium">Dibayar (Rp)</p>
<input type="number" id="paymentAmount" class="text-base rounded-lg bg-gray-200 p-2">
</div>
</div>
<div class="flex justify-center mt-4">
<button class="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-700" id="saveAndPrint">SIMPAN</button>
</div>
</div>
`;
toggleModal();
const saveAndPrintButton = document.getElementById('saveAndPrint');
saveAndPrintButton.addEventListener('click', function() {
const paymentAmount = parseFloat(document.getElementById('paymentAmount').value);
if (paymentAmount < total) {
alert("Pembayaran Kurang!");
} else {
const change = paymentAmount - total;
if (change > 0) {
alert(`Kembalian: IDR ${addCommas(change)}`);
}
saveAndPrint(noTransaksi, items, paymentAmount,change,total);
}
});
}
const formatter = new Intl.NumberFormat('id-ID', {
style: 'currency',
currency: 'IDR',
});
function exportToPdf(noTransaksi, items) {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
doc.setFontSize(18);
const text = "RUMAH PAMPERS ALIN";
const textWidth = doc.getTextWidth(text); // Get the width of the text
const pageWidth = doc.internal.pageSize.getWidth(); // Get the width of the page
const xCoordinate = (pageWidth - textWidth) / 2; // Calculate the x-coordinate for centering
doc.text(text, xCoordinate, 10);
doc.setFontSize(10);
doc.text(`${noTransaksi}`, 10, 30);
doc.text(`${new Date().toLocaleString()}`, 150, 30);
doc.setLineWidth(0.5);
doc.setLineDash([2, 2]);
doc.line(10, 40, 200, 40);
let y = 50;
const lineHeight = 20;
items.forEach((item) => {
const subtotal = item.harga * item.qty;
doc.setFontSize(10);
doc.text(`${item.nama}`, 10, y);
doc.text(`${item.qty} x ${item.harga}`, 10, y + 10);
doc.text(formatter.format(subtotal), 150, y);
y += lineHeight;
});
doc.setLineWidth(0.5);
doc.setLineDash([2, 2]);
doc.line(10, y, 200, y);
const lineHeightTotal = 10;
const total = items.reduce((acc, item) => acc + (item.harga * item.qty), 0);
doc.setFontSize(10);
const labelX = 10;
const valueX = 150;
doc.text(`TOTAL:`, labelX, y += lineHeightTotal);
doc.text(`${formatter.format(total)}`, valueX, y);
doc.text(`POTONGAN:`, labelX, y += lineHeightTotal);
doc.text(`${formatter.format(0)}`, valueX, y);
doc.text(`TUNAI:`, labelX, y += lineHeightTotal);
doc.text(`${formatter.format(total)}`, valueX, y);
doc.text("Terimakasih atas kunjungan anda", xCoordinate, y + 10);
doc.save(`struk_${noTransaksi}.pdf`);
}
function saveAndPrint(noTransaksi, items, bayar,sisa,total) {
const csrfToken = $('meta[name="csrf-token"]').attr('content');
const data = {
no_transaksi: noTransaksi,
items: items,
bayar : bayar,
sisa : sisa,
total : total,
supplier : $("#supplier").val()
};
$.ajax({
url: '{{ route('pembelian.tambah') }}',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(data),
headers: {
'X-CSRF-TOKEN': csrfToken
},
success: function(response) {
console.log('Data saved:', response);
if(confirm("Berhasil Menyimpan Data Pembelian")){
window.location.reload(history.back());
}
// exportToPdf(noTransaksi, items)
},
error: function(xhr, status, error) {
console.error('Error:', error);
}
});
}
function calculateTotal() {
let total = 0;
const rows = dataTable.getElementsByTagName('tr');
for (let i = 0; i < rows.length; i++) {
const hargaCell = rows[i].getElementsByTagName('td')[2];
const qtyCell = rows[i].getElementsByTagName('td')[3];
const harga = parseInt(removeComas(hargaCell.textContent.replace("IDR ", "")));
const qty = parseInt(qtyCell.querySelector('input').value);
total += harga * qty;
}
return total;
}
function addToTable(kode, nama, harga, qty) {
const existingRows = dataTable.getElementsByTagName('tr');
for (let i = 0; i < existingRows.length; i++) {
const existingKode = existingRows[i].getElementsByTagName('td')[0].textContent;
if (existingKode === kode) {
alert('Barang sudah ada di keranjang.');
return;
}
}
const row = dataTable.insertRow();
const subtotal = harga * qty;
row.innerHTML = `
<td class="p-5">${kode}</td>
<td class="p-5">${nama}</td>
<td class="p-5">IDR ${addCommas(harga)}</td>
<td class="p-5 text-center">
<button class="py-1 px-2 rounded-lg" onclick="decreaseQty(this)">-</button>
<input type="text" class="w-12 text-center mx-2 outline-none border-none" value="${qty}" readonly>
<button class="py-1 px-2 rounded-lg" onclick="increaseQty(this)">+</button>
</td>
<td class="p-5">IDR ${addCommas(subtotal)}</td>
<td class="p-5">
<button class="bg-red-500 text-white py-1 px-2 rounded-lg" onclick="removeItem(this)">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
</svg>
</button>
</td>
`;
calculateSubtotal();
}
function removeItem(button) {
const row = button.parentNode.parentNode;
row.parentNode.removeChild(row);
calculateSubtotal();
}
function calculateSubtotal() {
let subtotal = 0;
const rows = dataTable.getElementsByTagName('tr');
for (let i = 0; i < rows.length; i++) {
const hargaCell = rows[i].getElementsByTagName('td')[2];
const qtyCell = rows[i].getElementsByTagName('td')[3];
const harga = parseInt(removeComas(hargaCell.textContent.replace("IDR ", "")));
const qty = parseInt(qtyCell.querySelector('input').value);
subtotal += harga * qty;
}
document.getElementById('subtotal').textContent = 'IDR ' + addCommas(subtotal);
}
function decreaseQty(button) {
const input = button.nextElementSibling;
let qty = parseInt(input.value);
if (qty > 1) {
qty--;
input.value = qty;
updateSubtotal(input.parentNode.parentNode);
}
}
function increaseQty(button) {
const input = button.previousElementSibling;
let qty = parseInt(input.value);
qty++;
input.value = qty;
updateSubtotal(input.parentNode.parentNode);
}
function updateSubtotal(row) {
const harga = parseInt(removeComas(row.cells[2].textContent.replace("IDR ", "")));
const qty = parseInt(row.cells[3].querySelector('input').value);
row.cells[4].textContent = 'IDR ' + addCommas((harga * qty));
calculateSubtotal();
}
searchInput.addEventListener('input', () => {
$(document).ready(function() {
$.ajax({
url: '{{ route('penjualan') }}',
type: 'GET',
success: function(response) {
const data = response.message;
const query = searchInput.value.trim();
const filteredData = filterData(data, query);
displayResults(filteredData);
searchResults.classList.remove('hidden');
},
error: function(xhr, status, error) {
console.error('Error fetching data:', error);
}
});
});
});
document.addEventListener('click', (event) => {
if (!searchInput.contains(event.target)) {
searchResults.classList.add('hidden');
}
});
</script>
@endsection