Skip to content

</html> #445

@tongexe3-blip

Description

@tongexe3-blip
<title>តារាងសម្ភារ និងសង្ហារិម</title> <script src="https://cdn.tailwindcss.com"></script> <style> table { width: 100%; border-collapse: collapse; margin-top: 10px; font-family: Arial, sans-serif; }
    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>
Originally posted by @user1100007 in refined-github/refined-github#8969

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions