-
Notifications
You must be signed in to change notification settings - Fork 847
Closed
Description
<title>តារាងសម្ភារ និងសង្ហារិម</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
font-family: Arial, sans-serif;
}
Originally posted by @user1100007 in refined-github/refined-github#8969
table, th, td {
border: 2px solid #ddd;
}
table td, table th {
white-space: nowrap;
}
th, td {
padding: 1px 5px;
line-height: 1.0;
text-align: center;
}
tbody tr:nth-child(even) {
background-color: #f9f9f9;
}
tbody tr:hover {
background-color: #e0e0e0;
}
.title {
color: #5C6AC4;
font-size: 2em;
margin-bottom: 10px;
}
@media print {
.no-print { display: none !important; }
@page { margin: 1cm; }
.page {
width: 297mm;
min-height: 210mm;
margin: 0 auto;
background: white;
padding: 2mm;
box-shadow: 0 4px 20px rgba(0,0,0,0.2);
}
</style>
តារាងសម្ភារ និងសង្ហារិម
ប្រព័ន្ធគ្រប់គ្រងសម្ភារបរិក្ខារ
<div class="flex gap-2 mt-4 flex-wrap no-print">
<button
onclick="saveData()"
class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700"
>
💾 រក្សាទុក
</button>
<button
onclick="showAddForm()"
class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700"
>
➕ បន្ថែមថ្មី
</button>
</div>
</div>
<!-- បន្ថែម Script SheetJS -->
<script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script>
<div
id="addFormContainer"
class="bg-white rounded-lg shadow-lg p-6 mb-6 no-print hidden"
>
<h3 class="text-xl font-bold mb-4" id="formTitle">បន្ថែមថ្មី</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<select id="inputType" class="px-3 py-2 border rounded">
<option value="MOB">MOB</option>
<option value="MBU">MBU</option>
<option value="MIN">MIN</option>
</select>
<input
type="text"
id="inputDescription"
placeholder="បរិយាយ"
class="px-3 py-2 border rounded"
/>
<input
type="number"
id="inputYear"
placeholder="ឆ្នាំ"
class="px-3 py-2 border rounded"
/>
<input
type="text"
id="inputUser"
placeholder="ឈ្មោះអ្នកប្រើ"
class="px-3 py-2 border rounded"
/>
<input
type="number"
id="inputQuantity"
placeholder="បរិមាណ"
class="px-3 py-2 border rounded"
/>
<input
type="text"
id="inputPrice"
placeholder="តម្លៃ"
class="px-3 py-2 border rounded"
/>
<select id="inputStatus" class="px-3 py-2 border rounded">
<option value="ល្អ">ល្អ</option>
<option value="មធ្យម">មធ្យម</option>
<option value="អន់">អន់</option>
<option value="ខូច">ខូច</option>
</select>
<div class="flex gap-2">
<button
onclick="submitForm()"
class="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700"
>
រក្សាទុក
</button>
<button
onclick="cancelForm()"
class="px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
>
បោះបង់
</button>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-lg mb-6">
<div class="flex border-b no-print">
<button
onclick="switchTab('inventory')"
id="tab-inventory"
class="px-6 py-4 font-semibold bg-indigo-600 text-white"
>
📋 តារាងសម្ភារ និងសង្ហារិម
</button>
<button
onclick="switchTab('yearly')"
id="tab-yearly"
class="px-6 py-4 font-semibold text-gray-600 hover:bg-gray-50"
>
📈 តារាងសម្ភារកើនក្នុងឆ្នាំ
</button>
<button
onclick="switchTab('tracking')"
id="tab-tracking"
class="px-6 py-4 font-semibold text-gray-600 hover:bg-gray-50"
>
📊 តារាងតាមដាន
</button>
</div>
<div class="p-6">
<div id="inventoryTab">
<div class="mb-4 flex gap-4 no-print">
<input
type="text"
id="searchInput"
placeholder="🔍 ស្វែងរក..."
onkeyup="filterData()"
class="flex-1 px-4 py-2 border border-gray-300 rounded-lg"
/>
<select
id="yearFilter"
onchange="filterData()"
class="px-4 py-2 border border-gray-300 rounded-lg"
>
<option value="all">ឆ្នាំទាំងអស់</option>
<option value="2027">2027</option>
<option value="2026">2026</option>
<option value="2025">2025</option>
<option value="2024">2024</option>
<option value="2023">2023</option>
<option value="2022">2022</option>
<option value="2021">2021</option>
<option value="2020">2020</option>
<option value="2019">2019</option>
<option value="2018">2018</option>
<option value="2017">2017</option>
<option value="2016">2016</option>
<option value="2013">2013</option>
<option value="2010">2010</option>
<option value="2004">2004</option>
<option value="2000">2000</option>
<option value="1999">1999</option>
<option value="1998">1998</option>
</select>
</div>
<div class="overflow-x-auto rounded-lg border border-gray-200">
<table class="w-full" id="inventoryTable">
<thead class="bg-indigo-600 text-white">
<tr>
<th class="px-4 py-3 text-left">ល.រ</th>
<th class="px-4 py-3 text-left">តាមប្រភេទ</th>
<th class="px-4 py-3 text-left">បរិយាយ</th>
<th class="px-4 py-3 text-left">ប្រើប្រាស់ពីឆ្នាំ</th>
<th class="px-4 py-3 text-left">ឈ្មោះអ្នកប្រើ</th>
<th class="px-4 py-3 text-right">បរិមាណ</th>
<th class="px-4 py-3 text-right">តម្លៃ(រៀល)</th>
<th class="px-4 py-3 text-center">ស្ថានភាព</th>
<th class="px-4 py-3 text-center no-print">សកម្មភាព</th>
</tr>
</thead>
<tbody id="inventoryBody">
</tr>
<tr class="bg-indigo-50 font-bold">
<td colspan="5" class="px-4 py-3 text-right">សរុប:</td>
<td class="px-4 py-3 text-right">523</td>
<td class="px-4 py-3 text-right">150,966,400</td>
<td colspan="2"></td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="yearlyTab" class="hidden"></div>
<div id="trackingTab" class="hidden"></div>
</div>
</div>
</div>
<script>
let equipmentData = [];
let editingId = null;
const defaultData = [
{ id: 1, type: "MOB", description: "ធុងដែក", year: 1998, user: "ក្នុងស្រុក", quantity: 1, price: "1,200,000", status: "ខូច" },
{ id: 2, type: "MOB", description: "តុសិស្ស៤បង្កុយ(ឈើ)", year: 1999, user: "ក្នុងស្រុក", quantity: 9, price: "900,000", status: "ខូច" },
{ id: 3, type: "MOB", description: "កៅអីគ្រូ", year: 2000, user: "ក្នុងស្រុក", quantity: 6, price: "640,000", status: "អន់" },
{ id: 4, type: "MOB", description: "តុសិស្ស២បង្កុយ(ឈើ)", year: 2000, user: "ក្នុងស្រុក", quantity: 85, price: "7,480,000", status: "ខូច" },
{ id: 5, type: "MOB", description: "ក្ដារខៀនដីស", year: 2000, user: "ក្នុងស្រុក", quantity: 4, price: "400,000", status: "អន់" },
{ id: 6, type: "MOB", description: "ក្ដារខៀនហ្វឺត", year: 2000, user: "ក្នុងស្រុក", quantity: 1, price: "250,000", status: "ខូច" },
{ id: 7, type: "MOB", description: "ទូកញ្ចក់", year: 2004, user: "ក្នុងស្រុក", quantity: 1, price: "250,000", status: "ខូច" },
{ id: 8, type: "MOB", description: "ហិបដែក", year: 2010, user: "ក្នុងស្រុក", quantity: 1, price: "200,000", status: "អន់" },
{ id: 9, type: "MOB", description: "ធ្នើដាក់សៀវភៅធំ", year: 2010, user: "ក្នុងស្រុក", quantity: 1, price: "200,000", status: "មធ្យម" },
{ id: 10, type: "MOB", description: "តុសិស្ស២បង្កុយ(ឈើ)", year: 2013, user: "ក្នុងស្រុក", quantity: 20, price: "1,400,000", status: "អន់" },
{ id: 11, type: "MOB", description: "តុសិស្ស២បង្កុយ(ឈើ)", year: 2013, user: "ក្នុងស្រុក", quantity: 95, price: "40,679,000", status: "អន់" },
{ id: 12, type: "MOB", description: "តុអាន(ដែក)", year: 2013, user: "ក្នុងស្រុក", quantity: 5, price: "2,848,000", status: "មធ្យម" },
{ id: 13, type: "MOB", description: "ធ្នើមុខមួយ", year: 2013, user: "ក្នុងស្រុក", quantity: 2, price: "2,377,400", status: "មធ្យម" },
{ id: 14, type: "MOB", description: "ក្ដារខៀនព័ត៌មាន", year: 2016, user: "SOF", quantity: 2, price: "160,000", status: "មធ្យម" },
{ id: 15, type: "MOB", description: "កៅអីជ័រធុនតូច", year: 2017, user: "W.V.S", quantity: 31, price: "192,000", status: "ខូច" },
{ id: 16, type: "MOB", description: "តុអាន(ដែក)", year: 2017, user: "មន្ទីរអប់រំ", quantity: 12, price: "576,000", status: "ខូច" },
{ id: 17, type: "MBU", description: "ម៉ាស៊ីនព្រីន Epson L360", year: 2018, user: "សប្បុសជន", quantity: 1, price: "1,200,000", status: "ខូច" },
{ id: 18, type: "MBU", description: "កង្ហារភ្ជាប់ពិដាន", year: 2018, user: "មន្ទីរអប់រំ", quantity: 12, price: "960,000", status: "អន់" },
{ id: 19, type: "MOB", description: "តុសម្រាប់គ្រូ", year: 2018, user: "មន្ទីរអប់រំ", quantity: 6, price: "1,800,000", status: "មធ្យម" },
{ id: 20, type: "MOB", description: "តុសិស្ស២បង្កុយ(ដែក)", year: 2018, user: "ក្រសួងអប់រំ", quantity: 145, price: "60,900,000", status: "មធ្យម" },
{ id: 21, type: "MOB", description: "ទោងរំអិល", year: 2018, user: "មន្ទីរអប់រំ", quantity: 3, price: "1,080,000", status: "មធ្យម" },
{ id: 22, type: "MOB", description: "ក្ដារខៀនហ្វឺត", year: 2018, user: "មន្ទីរអប់រំ", quantity: 18, price: "4,500,000", status: "មធ្យម" },
{ id: 23, type: "MIN", description: "កុំព្យូទ័រយួរដៃ Asus", year: 2019, user: "ក្រសួងអប់រំ", quantity: 1, price: "2,713,500", status: "ខូច" },
{ id: 24, type: "MOB", description: "ក្ដាររំអិល", year: 2019, user: "W.V.S", quantity: 4, price: "1,600,000", status: "មធ្យម" },
{ id: 25, type: "MOB", description: "ជណ្ដើរស្វា", year: 2019, user: "W.V.S", quantity: 3, price: "1,584,000", status: "មធ្យម" },
{ id: 26, type: "MOB", description: "ម៉ាស៊ីនព្រីនHP", year: 2019, user: "ក្រសួងអប់រំ", quantity: 1, price: "1,336,500", status: "ខូច" },
{ id: 27, type: "MOB", description: "តុតឿ", year: 2020, user: "W.V.S", quantity: 6, price: "100,000", status: "ល្អ" },
{ id: 28, type: "MOB", description: "ដែកតោង", year: 2020, user: "W.V.S", quantity: 3, price: "200,000", status: "មធ្យម" },
{ id: 29, type: "MOB", description: "ទូដាក់កញ្ចក់ដាក់ឯកសារ", year: 2020, user: "W.V.S", quantity: 1, price: "750,000", status: "ល្អ" },
{ id: 30, type: "MOB", description: "ធ្នើដាក់សៀវភៅតាមថ្នាក់", year: 2020, user: "W.V.S", quantity: 1, price: "60,000", status: "ល្អ" },
{ id: 31, type: "MOB", description: "ធ្នើដាក់សៀវភៅតូច", year: 2020, user: "W.V.S", quantity: 5, price: "40,000", status: "ល្អ" },
{ id: 32, type: "MOB", description: "ធ្នើមុខពីរ", year: 2020, user: "W.V.S", quantity: 3, price: "70,000", status: "ល្អ" },
{ id: 33, type: "MOB", description: "ធ្នើមុខមួយ", year: 2020, user: "W.V.S", quantity: 4, price: "50,000", status: "ល្អ" },
{ id: 34, type: "MIN", description: "កុំព្យូទ័រយួរដៃ Acer", year: 2021, user: "SOF", quantity: 1, price: "2,800,000", status: "មធ្យម" },
{ id: 35, type: "MOB", description: "កៅអីគ្រូ", year: 2021, user: "មន្ទីរអប់រំ", quantity: 6, price: "720,000", status: "មធ្យម" },
{ id: 36, type: "MOB", description: "តុគ្រូ(ដែក)", year: 2021, user: "មន្ទីរអប់រំ", quantity: 6, price: "100,000", status: "ល្អ" },
{ id: 37, type: "MOB", description: "តុវែង", year: 2021, user: "មន្ទីរអប់រំ", quantity: 3, price: "200,000", status: "មធ្យម" },
{ id: 38, type: "MBU", description: "ម៉ាស៊ីនព្រីន Epson L3210", year: 2022, user: "SOF", quantity: 1, price: "800,000", status: "ខូច" },
{ id: 39, type: "MBU", description: "កង្ហារភ្ជាប់ជញ្ជាំង", year: 2023, user: "SOF", quantity: 4, price: "250,000", status: "មធ្យម" },
{ id: 40, type: "MBU", description: "កុំព្យូទ័រលើតុ Desktop", year: 2023, user: "សប្បុសជន", quantity: 1, price: "1,800,000", status: "មធ្យម" },
{ id: 41, type: "MBU", description: "ម៉ាស៊ីនព្រីន Canon", year: 2023, user: "សប្បុសជន", quantity: 1, price: "1,100,000", status: "មធ្យម" },
{ id: 42, type: "MBU", description: "ម៉ូទ័របូមទឹក", year: 2023, user: "SOF", quantity: 1, price: "400,000", status: "មធ្យម" },
{ id: 43, type: "MBU", description: "Speaker", year: 2024, user: "សប្បុរសជន", quantity: 1, price: "800,000", status: "មធ្យម" },
{ id: 44, type: "MBU", description: "Micro sound (តូច)", year: 2024, user: "SOF", quantity: 1, price: "60,000", status: "មធ្យម" },
{ id: 45, type: "MBU", description: "កង្ហារភ្ជាប់ជញ្ជាំង(ធំ)", year: 2024, user: "SOF", quantity: 1, price: "240,000", status: "ខូច" },
{ id: 46, type: "MIN", description: "ម៉ាស៊ីនព្រីន Color", year: 2025, user: "សប្បុរសជន", quantity: 1, price: "1,000,000", status: "ល្អ" },
{ id: 47, type: "MIN", description: "ម៉ាស៊ីនព្រីន Black white", year: 2025, user: "សប្បុរសជន", quantity: 1, price: "1,500,000", status: "មធ្យម" },
{ id: 48, type: "MBU", description: "ម៉ូទ័រកាត់ផ្កា", year: 2025, user: "SOF", quantity: 1, price: "500,000", status: "មធ្យម" }
];
function init() {
const saved = localStorage.getItem('equipmentData');
equipmentData = saved ? JSON.parse(saved) : defaultData;
updateYearFilter();
renderInventory();
}
function saveData() {
localStorage.setItem('equipmentData', JSON.stringify(equipmentData));
alert('បានរក្សាទុកទិន្នន័យ!');
}
function updateYearFilter() {
const years = [...new Set(equipmentData.map(item => item.year))].sort((a, b) => b - a);
const select = document.getElementById('yearFilter');
select.innerHTML = '<option value="all">ឆ្នាំទាំងអស់</option>';
years.forEach(year => {
select.innerHTML += '<option value="' + year + '">' + year + '</option>';
});
}
function getStatusClass(status) {
if (status === 'ល្អ') return 'bg-green-100 text-green-800';
if (status === 'មធ្យម') return 'bg-yellow-100 text-yellow-800';
if (status === 'អន់') return 'bg-orange-100 text-orange-800';
return 'bg-red-100 text-red-800';
}
function renderInventory() {
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
const yearFilter = document.getElementById('yearFilter').value;
let filtered = equipmentData.filter(item => {
const matchesSearch = item.description.toLowerCase().includes(searchTerm) || item.user.toLowerCase().includes(searchTerm);
const matchesYear = yearFilter === 'all' || item.year.toString() === yearFilter;
return matchesSearch && matchesYear;
});
let html = '';
let totalQty = 0;
let totalPrice = 0;
filtered.forEach((item, index) => {
totalQty += item.quantity;
totalPrice += parseInt(item.price.replace(/,/g, ''));
html += '<tr class="hover:bg-gray-50">';
html += '<td class="px-4 py-3">' + (index + 1) + '</td>';
html += '<td class="px-4 py-3"><span class="px-2 py-1 bg-blue-100 text-blue-800 rounded text-sm font-semibold">' + item.type + '</span></td>';
html += '<td class="px-4 py-3">' + item.description + '</td>';
html += '<td class="px-4 py-3">' + item.year + '</td>';
html += '<td class="px-4 py-3">' + item.user + '</td>';
html += '<td class="px-4 py-3 text-right font-semibold">' + item.quantity + '</td>';
html += '<td class="px-4 py-3 text-right">' + item.price + '</td>';
html += '<td class="px-4 py-3 text-center"><span class="px-3 py-1 rounded-full text-sm font-semibold ' + getStatusClass(item.status) + '">' + item.status + '</span></td>';
html += '<td class="px-4 py-3 text-center no-print">';
html += '<button onclick="editItem(' + item.id + ')" class="text-blue-600 hover:text-blue-800 mr-2">✏️</button>';
html += '<button onclick="deleteItem(' + item.id + ')" class="text-red-600 hover:text-red-800">🗑️</button>';
html += '</td></tr>';
});
html += '<tr class="bg-indigo-50 font-bold">';
html += '<td colspan="5" class="px-4 py-3 text-right">សរុប:</td>';
html += '<td class="px-4 py-3 text-right">' + totalQty + '</td>';
html += '<td class="px-4 py-3 text-right">' + totalPrice.toLocaleString() + '</td>';
html += '<td colspan="2"></td></tr>';
document.getElementById('inventoryBody').innerHTML = html;
}
function filterData() {
renderInventory();
}
function showAddForm() {
document.getElementById('formTitle').textContent = 'បន្ថែមថ្មី';
editingId = null;
clearForm();
document.getElementById('addFormContainer').classList.remove('hidden');
}
function cancelForm() {
document.getElementById('addFormContainer').classList.add('hidden');
clearForm();
editingId = null;
}
function clearForm() {
document.getElementById('inputType').value = 'MOB';
document.getElementById('inputDescription').value = '';
document.getElementById('inputYear').value = new Date().getFullYear();
document.getElementById('inputUser').value = '';
document.getElementById('inputQuantity').value = 1;
document.getElementById('inputPrice').value = '';
document.getElementById('inputStatus').value = 'ល្អ';
}
function submitForm() {
const formData = {
type: document.getElementById('inputType').value,
description: document.getElementById('inputDescription').value,
year: parseInt(document.getElementById('inputYear').value),
user: document.getElementById('inputUser').value,
quantity: parseInt(document.getElementById('inputQuantity').value),
price: document.getElementById('inputPrice').value,
status: document.getElementById('inputStatus').value
};
if (editingId) {
equipmentData = equipmentData.map(item =>
item.id === editingId ? {...formData, id: editingId} : item
);
} else {
const newId = Math.max(...equipmentData.map(i => i.id), 0) + 1;
equipmentData.push({...formData, id: newId});
}
updateYearFilter();
renderInventory();
renderYearly();
renderTracking();
cancelForm();
}
function editItem(id) {
const item = equipmentData.find(i => i.id === id);
if (item) {
editingId = id;
document.getElementById('formTitle').textContent = 'កែប្រែ';
document.getElementById('inputType').value = item.type;
document.getElementById('inputDescription').value = item.description;
document.getElementById('inputYear').value = item.year;
document.getElementById('inputUser').value = item.user;
document.getElementById('inputQuantity').value = item.quantity;
document.getElementById('inputPrice').value = item.price;
document.getElementById('inputStatus').value = item.status;
document.getElementById('addFormContainer').classList.remove('hidden');
}
}
function deleteItem(id) {
if (confirm('តើអ្នកប្រាកដទេថាចង់លុប?')) {
equipmentData = equipmentData.filter(item => item.id !== id);
updateYearFilter();
renderInventory();
renderYearly();
renderTracking();
}
}
function downloadJSON() {
const dataStr = JSON.stringify(equipmentData, null, 2);
const dataBlob = new Blob([dataStr], {type: 'application/json'});
const url = URL.createObjectURL(dataBlob);
const link = document.createElement('a');
link.href = url;
link.download = 'equipment_data.json';
link.click();
}
function downloadCSV() {
const headers = ['ល.រ', 'តាមប្រភេទ', 'បរិយាយ', 'ប្រើប្រាស់ពីឆ្នាំ', 'ឈ្មោះអ្នកប្រើ', 'បរិមាណ', 'តម្លៃ(រៀល)', 'ស្ថានភាព'];
let csv = '\uFEFF' + headers.join(',') + '\n';
equipmentData.forEach((item, idx) => {
const row = [
idx + 1,
item.type,
'"' + item.description + '"',
item.year,
'"' + item.user + '"',
item.quantity,
item.price,
item.status
];
csv += row.join(',') + '\n';
});
const blob = new Blob([csv], {type: 'text/csv;charset=utf-8;'});
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'equipment_data.csv';
link.click();
}
function importJSON(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
try {
equipmentData = JSON.parse(e.target.result);
updateYearFilter();
renderInventory();
renderYearly();
renderTracking();
alert('បាននាំចូលទិន្នន័យដោយជោគជ័យ!');
} catch (error) {
alert('មានបញ្ហាក្នុងការនាំចូលទិន្នន័យ!');
}
};
reader.readAsText(file);
}
}
function switchTab(tab) {
document.getElementById('inventoryTab').classList.add('hidden');
document.getElementById('yearlyTab').classList.add('hidden');
document.getElementById('trackingTab').classList.add('hidden');
document.getElementById('tab-inventory').className = 'px-6 py-4 font-semibold text-gray-600 hover:bg-gray-50';
document.getElementById('tab-yearly').className = 'px-6 py-4 font-semibold text-gray-600 hover:bg-gray-50';
document.getElementById('tab-tracking').className = 'px-6 py-4 font-semibold text-gray-600 hover:bg-gray-50';
document.getElementById(tab + 'Tab').classList.remove('hidden');
document.getElementById('tab-' + tab).className = 'px-6 py-4 font-semibold bg-indigo-600 text-white';
if (tab === 'yearly') renderYearly();
if (tab === 'tracking') renderTracking();
}
function renderYearly() {
const yearlyData = {};
equipmentData.forEach(item => {
if (!yearlyData[item.year]) yearlyData[item.year] = [];
yearlyData[item.year].push(item);
});
const years = Object.keys(yearlyData).sort((a, b) => b - a);
let html = '<h2 class="text-2xl font-bold text-indigo-900 mb-4">សម្ភារកើនក្នុងឆ្នាំ</h2><div class="space-y-6">';
years.forEach(year => {
const items = yearlyData[year];
let totalQty = 0;
let totalPrice = 0;
html += '<div class="bg-gray-50 rounded-lg p-4">';
html += '<h3 class="text-xl font-bold text-indigo-800 mb-3">ឆ្នាំ ' + year + '</h3>';
html += '<div class="overflow-x-auto rounded-lg border border-gray-200">';
html += '<table class="w-full bg-white">';
html += '<thead class="bg-indigo-500 text-white"><tr>';
html += '<th class="px-4 py-2 text-left">ល.រ</th>';
html += '<th class="px-4 py-2 text-left">បរិយាយ</th>';
html += '<th class="px-4 py-2 text-left">ប្រភេទ</th>';
html += '<th class="px-4 py-2 text-right">បរិមាណ</th>';
html += '<th class="px-4 py-2 text-right">តម្លៃ(រៀល)</th>';
html += '<th class="px-4 py-2 text-center">ស្ថានភាព</th>';
html += '</tr></thead><tbody class="divide-y divide-gray-200">';
items.forEach((item, idx) => {
totalQty += item.quantity;
totalPrice += parseInt(item.price.replace(/,/g, ''));
html += '<tr class="hover:bg-gray-50">';
html += '<td class="px-4 py-2">' + (idx + 1) + '</td>';
html += '<td class="px-4 py-2">' + item.description + '</td>';
html += '<td class="px-4 py-2"><span class="px-2 py-1 bg-purple-100 text-purple-800 rounded text-sm">' + item.type + '</span></td>';
html += '<td class="px-4 py-2 text-right font-semibold">' + item.quantity + '</td>';
html += '<td class="px-4 py-2 text-right">' + item.price + '</td>';
html += '<td class="px-4 py-2 text-center"><span class="px-2 py-1 rounded-full text-sm ' + getStatusClass(item.status) + '">' + item.status + '</span></td>';
html += '</tr>';
});
html += '<tr class="bg-indigo-50 font-bold">';
html += '<td colspan="3" class="px-4 py-2 text-right">សរុប:</td>';
html += '<td class="px-4 py-2 text-right">' + totalQty + '</td>';
html += '<td class="px-4 py-2 text-right">' + totalPrice.toLocaleString() + '</td>';
html += '<td></td></tr>';
html += '</tbody></table></div></div>';
});
html += '</div>';
document.getElementById('yearlyTab').innerHTML = html;
}
function renderTracking() {
const summary = {};
equipmentData.forEach(item => {
if (!summary[item.description]) {
summary[item.description] = {good: 0, medium: 0, weak: 0, broken: 0, total: 0};
}
summary[item.description].total += item.quantity;
if (item.status === 'ល្អ') summary[item.description].good += item.quantity;
else if (item.status === 'មធ្យម') summary[item.description].medium += item.quantity;
else if (item.status === 'អន់') summary[item.description].weak += item.quantity;
else if (item.status === 'ខូច') summary[item.description].broken += item.quantity;
});
let html = '<h2 class="text-2xl font-bold text-indigo-900 mb-4">តារាងតាមដានស្ថានភាពសម្ភារៈ</h2>';
html += '<div class="overflow-x-auto rounded-lg border border-gray-200">';
html += '<table class="w-full bg-white">';
html += '<thead class="bg-indigo-600 text-white">';
html += '<tr>';
html += '<th class="px-4 py-3 text-left" rowspan="2">ល.រ</th>';
html += '<th class="px-4 py-3 text-left" rowspan="2">ឈ្មោះសម្ភារបរិក្ខារ</th>';
html += '<th class="px-4 py-3 text-center" colspan="5">ស្ថានភាពសម្ភារៈ</th>';
html += '<th class="px-4 py-3 text-center" colspan="2">ការប្រើប្រាស់</th>';
html += '<th class="px-4 py-3 text-center" rowspan="2">ស្ថានភាព</th>';
html += '</tr><tr>';
html += '<th class="px-4 py-2 text-center bg-green-600">ល្អ</th>';
html += '<th class="px-4 py-2 text-center bg-yellow-600">មធ្យម</th>';
html += '<th class="px-4 py-2 text-center bg-orange-600">អន់</th>';
html += '<th class="px-4 py-2 text-center bg-red-600">ខូច</th>';
html += '<th class="px-4 py-2 text-center bg-indigo-700">សរុប</th>';
html += '<th class="px-4 py-2 text-center bg-blue-600">លើស</th>';
html += '<th class="px-4 py-2 text-center bg-purple-600">ខ្វះ</th>';
html += '</tr></thead><tbody class="divide-y divide-gray-200">';
let idx = 0;
let totalGood = 0, totalMedium = 0, totalWeak = 0, totalBroken = 0, grandTotal = 0;
for (const [desc, counts] of Object.entries(summary)) {
idx++;
totalGood += counts.good;
totalMedium += counts.medium;
totalWeak += counts.weak;
totalBroken += counts.broken;
grandTotal += counts.total;
const statusText = counts.broken > 0 ? 'ខូច' : counts.weak > 0 ? 'អន់' : counts.medium > 0 ? 'មធ្យម' : 'ល្អ';
html += '<tr class="hover:bg-gray-50">';
html += '<td class="px-4 py-3">' + idx + '</td>';
html += '<td class="px-4 py-3 font-semibold">' + desc + '</td>';
html += '<td class="px-4 py-3 text-center bg-green-50">' + counts.good + '</td>';
html += '<td class="px-4 py-3 text-center bg-yellow-50">' + counts.medium + '</td>';
html += '<td class="px-4 py-3 text-center bg-orange-50">' + counts.weak + '</td>';
html += '<td class="px-4 py-3 text-center bg-red-50">' + counts.broken + '</td>';
html += '<td class="px-4 py-3 text-center bg-indigo-50 font-bold">' + counts.total + '</td>';
html += '<td class="px-4 py-3 text-center">-</td>';
html += '<td class="px-4 py-3 text-center">-</td>';
html += '<td class="px-4 py-3 text-center"><span class="px-2 py-1 rounded-full text-sm ' + getStatusClass(statusText) + '">' + statusText + '</span></td>';
html += '</tr>';
}
html += '<tr class="bg-indigo-50 font-bold">';
html += '<td colspan="2" class="px-4 py-3 text-right">សរុបទាំងអស់:</td>';
html += '<td class="px-4 py-3 text-center bg-green-100">' + totalGood + '</td>';
html += '<td class="px-4 py-3 text-center bg-yellow-100">' + totalMedium + '</td>';
html += '<td class="px-4 py-3 text-center bg-orange-100">' + totalWeak + '</td>';
html += '<td class="px-4 py-3 text-center bg-red-100">' + totalBroken + '</td>';
html += '<td class="px-4 py-3 text-center bg-indigo-100">' + grandTotal + '</td>';
html += '<td colspan="3"></td></tr>';
html += '</tbody></table></div>';
document.getElementById('trackingTab').innerHTML = html;
}
init();
function downloadXLSX() {
// បំពេញទិន្នន័យទៅ Excel format
const ws_data = [
['ល.រ', 'តាមប្រភេទ', 'បរិយាយ', 'ប្រើប្រាស់ពីឆ្នាំ', 'ឈ្មោះអ្នកប្រើ', 'បរិមាណ', 'តម្លៃ(រៀល)', 'ស្ថានភាព']
];
equipmentData.forEach((item, idx) => {
ws_data.push([
idx + 1,
item.type,
item.description,
item.year,
item.user,
item.quantity,
item.price,
item.status
]);
});
const ws = XLSX.utils.aoa_to_sheet(ws_data);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Equipment");
XLSX.writeFile(wb, "equipment_data.xlsx");
}
</script>
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels