Skip to content

Building #706

@user1100007

Description

@user1100007

<thml lang"km">

school_id authority unit user school name_building log_num log_total building_num building_total usage_bur usage_tec usage_log usage_mix province district commune address width length area type_stone type_wood type_mix year has_water has_elec cadastral floors total_room total_value status created_at
1030401017 ក្រសួងអប់រំ យុវជន និងកីឡា មន្ទីរអប់រំ យុវជន និងកីឡាខេត្តបន្ទាយមានជ័យ ការិយាយល័យអប់រំ យុវជន និងកីឡាស្រុកភ្នំស្រុក សាលាបឋមសិក្សា រោគ A 9 51 1 5 FALSE FALSE FALSE TRUE Banteay Meanchey Phnum srok Spean sreng Rauk 8 20 160 FALSE TRUE FALSE 1891 TRUE TRUE E0 3 3050000 បាត់ពីដី(រុះរើ) ""2025-12-23T08:35:32.832Z""
1030401017 ក្រសួងអប់រំ យុវជន និងកីឡា មន្ទីរអប់រំ យុវជន និងកីឡាខេត្តបន្ទាយមានជ័យ ការិយាយល័យអប់រំ យុវជន និងកីឡាស្រុកភ្នំស្រុក សាលាបឋមសិក្សា រោគ B 9 51 2 5 FALSE FALSE FALSE TRUE Banteay Meanchey Phnum srok Spean sreng Rauk 7 24 168 TRUE FALSE FALSE 2012 TRUE TRUE E0 3 13010000 មធ្យម ""2025-12-23T08:42:55.379Z""
1030401017 ក្រសួងអប់រំ យុវជន និងកីឡា មន្ទីរអប់រំ យុវជន និងកីឡាខេត្តបន្ទាយមានជ័យ ការិយាយល័យអប់រំ យុវជន និងកីឡាស្រុកភ្នំស្រុក សាលាបឋមសិក្សា រោគ C 9 51 3 5 FALSE FALSE FALSE TRUE Banteay Meanchey Phnum srok Spean sreng Rauk 9 32 288 TRUE FALSE FALSE 2014 TRUE TRUE E0 4 190170000 មធ្យម ""2025-12-28T17:36:57.646Z""
1030401017 ក្រសួងអប់រំ យុវជន និងកីឡា មន្ទីរអប់រំ យុវជន និងកីឡាខេត្តបន្ទាយមានជ័យ ការិយាយល័យអប់រំ យុវជន និងកីឡាស្រុកភ្នំស្រុក សាលាបឋមសិក្សា រោគ D 9 51 4 5 FALSE FALSE FALSE TRUE Banteay Meanchey Phnum srok Spean sreng Rauk 9 42 342 TRUE FALSE FALSE 2018 TRUE TRUE E0 6 288000000 ល្អ ""2025-12-28T17:46:12.865Z""
1030401017 ក្រសួងអប់រំ យុវជន និងកីឡា មន្ទីរអប់រំ យុវជន និងកីឡាខេត្តបន្ទាយមានជ័យ ការិយាយល័យអប់រំ យុវជន និងកីឡាស្រុកភ្នំស្រុក សាលាបឋមសិក្សា រោគ E 9 51 5 5 TRUE FALSE FALSE FALSE Banteay Meanchey Phnum srok Spean sreng Rauk 7 8 56 TRUE FALSE FALSE 2025 TRUE TRUE E0 2 3500000 ល្អ ""2025-12-28T17:46:12.865Z""

– Building Permit System Database Schema
– Based on Cambodian Government Building Permit Form

CREATE TABLE IF NOT EXISTS permits (
id INTEGER PRIMARY KEY AUTOINCREMENT,

– Basic Info (Header)
authority TEXT NOT NULL, – អាជ្ញាធរកាន់កាប់ទ្រព្យសម្បត្តិរដ្ឋ
unit TEXT NOT NULL, – អង្គភាពប្រើប្រាស់
user TEXT NOT NULL, – អ្នកប្រើប្រាស់
school TEXT, – ឈ្មោះសាលា (or project name)

– Permit Numbers
log_num INTEGER NOT NULL, – សលាកបត្រលម្អិតអាគារសង់លើដី លេខ X
log_total INTEGER NOT NULL DEFAULT 51, – លើ Y
building_num INTEGER NOT NULL, – អគារលេខ X
building_total INTEGER NOT NULL DEFAULT 4, – លើ Y

– Usage Type (ការប្រើប្រាស់)
usage_bur BOOLEAN DEFAULT FALSE, – ការិយាល័យ (BUR)
usage_tec BOOLEAN DEFAULT FALSE, – អគារបច្ចេកទេស (TEC)
usage_log BOOLEAN DEFAULT FALSE, – លំនៅដ្ឋាន (LOG)
usage_mix BOOLEAN DEFAULT FALSE, – ចម្រុះ (MIX)

– Location (ទីតាំង)
province TEXT NOT NULL, – ក្រុង/ខេត្ត
district TEXT NOT NULL, – ស្រុក
commune TEXT NOT NULL, – ឃុំ
village TEXT, – ភូមិ
address TEXT, – អាស័យដ្ឋានពិតប្រាកដ

– Dimensions (ទំហំ)
width REAL NOT NULL, – ទទឹង (ម៉ែត្រ)
length REAL NOT NULL, – បណ្ដោយ (ម៉ែត្រ)
area REAL NOT NULL, – ផ្ទៃក្រឡា (ម៉ែត្រក្រឡា)

– Construction Details
type_stone BOOLEAN DEFAULT FALSE, – ធ្វើអំពីថ្ម
type_wood BOOLEAN DEFAULT FALSE, – ធ្វើអំពីឈើ
type_mix BOOLEAN DEFAULT FALSE, – ធ្វើចម្រុះ

cadastral TEXT, – លេខចុះបញ្ជីសុរិយោដី
year INTEGER NOT NULL, – ឆ្នាំសាងសង់
floors TEXT NOT NULL DEFAULT ‘E0’, – ចំនួនជាន់

– Utilities (ប្រើប្រាស់)
has_water BOOLEAN DEFAULT FALSE, – មានទឹក
has_phone BOOLEAN DEFAULT FALSE, – ទូរស័ព្ទ
has_elec BOOLEAN DEFAULT FALSE, – អគ្គិសនី
has_spare BOOLEAN DEFAULT FALSE, – ទំនេរ

– Financial
total_value REAL NOT NULL, – តម្លៃអគារសរុប (រៀល)

– Structure Condition (លំនឹងពីទូទៅ)
cond_foundation TEXT DEFAULT ‘មធ្យម’, – មូលដ្ឋាន
cond_wall TEXT DEFAULT ‘មធ្យម’, – ជញ្ជាំង
cond_roof TEXT DEFAULT ‘មធ្យម’, – ដំបូល
cond_interior TEXT DEFAULT ‘មធ្យម’, – រៀបចំខាងក្នុង

– Additional Notes
notes TEXT, – ព័ត៌មានផ្សេងៗ

– Timestamps (កាលបរិច្ឆេទ)
date_created TEXT NOT NULL, – កាលបរិច្ឆេទបង្កើត (YYYY-MM-DD)
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

– Indexes for common queries
CREATE INDEX IF NOT EXISTS idx_permits_province ON permits(province);
CREATE INDEX IF NOT EXISTS idx_permits_user ON permits(user);
CREATE INDEX IF NOT EXISTS idx_permits_building_num ON permits(building_num);
CREATE INDEX IF NOT EXISTS idx_permits_date_created ON permits(date_created);

import { usePermit } from “@/hooks/use-permits”;
import { useRoute, Link } from “wouter”;
import { Button } from “@/components/ui/button”;
import { Printer, ArrowLeft, PenLine } from “lucide-react”;
import { useRef } from “react”;
import { formatKhmerDate, formatWesternDate, formatKhmerNumber } from “@/lib/khmer-date-utils”;

export default function ViewPermit() {
const [, params] = useRoute(”/permit/:id”);
const id = parseInt(params?.id || “0”);
const { data: permit, isLoading } = usePermit(id);
const printRef = useRef(null);

const handlePrint = () => {
window.print();
};

if (isLoading) return

កំពុងភ្ជាប់…
;
if (!permit) return
រក្សាទុកមិនឃើញ។
;

const dateCreated = permit.dateCreated ? new Date(permit.dateCreated) : new Date();
const khmerDate = formatKhmerDate(dateCreated);
const westernDate = formatWesternDate(dateCreated);

return (

  {/* Controls (Hidden on Print) */}
  <div className="max-w-[297mm] mx-auto mb-3 flex justify-center gap-3 no-print">
    <Link href="/">
      <Button variant="outline" size="sm" className="gap-2">
        <ArrowLeft className="w-4 h-4" /> ត្រឡប់ក្រោយ
      </Button>
    </Link>
    <Link href={`/edit/${id}`}>
      <Button variant="outline" size="sm" className="gap-2">
        <PenLine className="w-4 h-4" /> កែសម្រួល
      </Button>
    </Link>
    <Button onClick={handlePrint} size="sm" className="bg-green-600 hover:bg-green-700 gap-2 text-white">
      <Printer className="w-4 h-4" /> បោះពុម្ព
    </Button>
  </div>

  {/* A4 Landscape Paper (297mm x 210mm) */}
  <div 
    ref={printRef}
    className="max-w-[297mm] h-[210mm] mx-auto bg-white shadow-xl print:shadow-none p-[10mm] text-[11px] leading-tight text-black font-khmer relative"
  >
    
    {/* Header */}
    <div className="text-center mb-3">
      <div className="text-[12px] font-bold leading-tight">
        <p>ព្រះរាជាណាចក្រកម្ពុជា</p>
        <p>ជាតិ សាសនា ព្រះមហាក្សត្រ</p>
      </div>
      <div className="text-[11px] mt-1">
        ════ ◉◉◉❂❂◉◉◉ ════
      </div>
    </div>

    {/* Authority Lines */}
    <div className="text-[10px] leading-tight mb-2">
      <p>អាជ្ញាធរកាន់កាប់ទ្រព្យសម្បត្តិរដ្ឋ : <span className="font-semibold">{permit.authority}</span></p>
      <p>អង្គភាពប្រើប្រាស់ : <span className="font-semibold">{permit.unit}</span></p>
    </div>

    {/* Title */}
    <div className="text-center font-bold mb-2">
      <p className="text-[13px]">សលាកបត្រលម្អិតនៃអាគារសង់លើដី លេខ {permit.logNum} លើ {permit.logTotal}</p>
    </div>

    {/* Building Number Row */}
    <div className="flex gap-4 mb-1 text-[10px]">
      <div className="flex-1">
        អគារលេខ <span className="font-bold">{permit.buildingNum}</span> លើ <span className="font-bold">{permit.buildingTotal}</span>
      </div>
    </div>

    {/* Usage Type Row */}
    <div className="flex gap-2 items-center mb-2 text-[10px]">
      <span className="font-semibold">ការប្រើប្រាស់ សូមគូស :</span>
      <div className="flex gap-3">
        <label className="flex items-center gap-1">
          <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.usageBur ? 'font-bold' : ''}`}>
            {permit.usageBur && '✓'}
          </div>
          <span>ការិយាល័យ(BUR)</span>
        </label>
        <label className="flex items-center gap-1">
          <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.usageTec ? 'font-bold' : ''}`}>
            {permit.usageTec && '✓'}
          </div>
          <span>អគារបច្ចេកទេស(TEC)</span>
        </label>
        <label className="flex items-center gap-1">
          <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.usageLog ? 'font-bold' : ''}`}>
            {permit.usageLog && '✓'}
          </div>
          <span>លំនៅដ្ឋាន(LOG)</span>
        </label>
        <label className="flex items-center gap-1">
          <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.usageMix ? 'font-bold' : ''}`}>
            {permit.usageMix && '✓'}
          </div>
          <span>ចម្រុះ(MIX)</span>
        </label>
      </div>
    </div>

    {/* Two Column Layout */}
    <div className="grid grid-cols-2 gap-6 mb-2">
      
      {/* Left Column: Location */}
      <div className="text-[10px] space-y-0.5">
        <div className="flex gap-2">
          <span className="font-semibold w-20">ទីតាំង-ខេត្ត :</span>
          <span className="flex-1">{permit.province}</span>
          <span className="font-semibold w-16">ទំហំ</span>
        </div>
        <div className="flex gap-2">
          <span className="font-semibold w-20">ស្រុក :</span>
          <span className="flex-1">{permit.district}</span>
          <span className="font-semibold w-16">ទទឹង (ម៉ែត្រ) :</span>
          <span>{permit.width}</span>
        </div>
        <div className="flex gap-2">
          <span className="font-semibold w-20"></span>
          <span className="flex-1"></span>
          <span className="font-semibold w-16">បណ្ដោយ (ម៉ែត្រ) :</span>
          <span>{permit.length}</span>
        </div>
        <div className="flex gap-2">
          <span className="font-semibold">អាស័យដ្ឋានពិតប្រាកដ :</span>
          <span className="flex-1">{permit.address || `ភូមិ${permit.village || ''} ឃុំ${permit.commune} ស្រុក${permit.district} ខេត្ត${permit.province}`}</span>
        </div>
        <div className="flex gap-2">
          <span className="font-semibold w-20"></span>
          <span className="flex-1"></span>
          <span className="font-semibold w-16">ផ្ទៃក្រឡា (ម²) :</span>
          <span>{permit.area}</span>
        </div>
      </div>

      {/* Right Column: Construction Details */}
      <div className="text-[10px] space-y-0.5">
        <div className="flex gap-2 items-center">
          <span className="font-semibold">ប្រភេទសំណង់ :</span>
          <label className="flex items-center gap-1">
            <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.typeStone ? 'font-bold' : ''}`}>
              {permit.typeStone && '✓'}
            </div>
            <span>ធ្វើអំពីថ្ម</span>
          </label>
          <label className="flex items-center gap-1">
            <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.typeWood ? 'font-bold' : ''}`}>
              {permit.typeWood && '✓'}
            </div>
            <span>ធ្វើអំពីឈើ</span>
          </label>
          <label className="flex items-center gap-1">
            <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.typeMix ? 'font-bold' : ''}`}>
              {permit.typeMix && '✓'}
            </div>
            <span>ធ្វើចម្រុះ</span>
          </label>
        </div>
        <div className="flex gap-2">
          <span className="font-semibold w-32">លេខចុះបញ្ជីសុរិយោដី :</span>
          <span className="flex-1">{permit.cadastral || ''}</span>
        </div>
        <div className="flex gap-2">
          <span className="font-semibold w-20">ឆ្នាំសាងសង់ :</span>
          <span>{permit.year}</span>
          <span className="font-semibold ml-4">ចំនួនជាន់ :</span>
          <span>{permit.floors}</span>
        </div>
        <div className="flex gap-2">
          <span className="font-semibold">តម្លៃអគារសរុប(រៀល) :</span>
          <span className="font-bold">{formatKhmerNumber(permit.totalValue)}</span>
        </div>
        <div className="flex gap-4">
          <div className="flex gap-2 items-center">
            <span className="font-semibold">មានទឹក :</span>
            <label className="flex items-center gap-1">
              <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.hasWater ? 'font-bold' : ''}`}>
                {permit.hasWater && '✓'}
              </div>
              <span>មាន</span>
            </label>
            <label className="flex items-center gap-1">
              <div className={`w-3 h-3 border border-black flex items-center justify-center ${!permit.hasWater ? 'font-bold' : ''}`}>
                {!permit.hasWater && '✓'}
              </div>
              <span>គ្មាន</span>
            </label>
          </div>
          <div className="flex gap-2 items-center">
            <span className="font-semibold">ទូរស័ព្ទ :</span>
            <label className="flex items-center gap-1">
              <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.hasPhone ? 'font-bold' : ''}`}>
                {permit.hasPhone && '✓'}
              </div>
              <span>មាន</span>
            </label>
            <label className="flex items-center gap-1">
              <div className={`w-3 h-3 border border-black flex items-center justify-center ${!permit.hasPhone ? 'font-bold' : ''}`}>
                {!permit.hasPhone && '✓'}
              </div>
              <span>គ្មាន</span>
            </label>
          </div>
        </div>
        <div className="flex gap-4">
          <div className="flex gap-2 items-center">
            <span className="font-semibold">អគ្គិសនី :</span>
            <label className="flex items-center gap-1">
              <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.hasElec ? 'font-bold' : ''}`}>
                {permit.hasElec && '✓'}
              </div>
              <span>មាន</span>
            </label>
            <label className="flex items-center gap-1">
              <div className={`w-3 h-3 border border-black flex items-center justify-center ${!permit.hasElec ? 'font-bold' : ''}`}>
                {!permit.hasElec && '✓'}
              </div>
              <span>គ្មាន</span>
            </label>
          </div>
          <div className="flex gap-2 items-center">
            <span className="font-semibold">ទំនេរ :</span>
            <label className="flex items-center gap-1">
              <div className={`w-3 h-3 border border-black flex items-center justify-center ${permit.hasSpare ? 'font-bold' : ''}`}>
                {permit.hasSpare && '✓'}
              </div>
              <span>មាន</span>
            </label>
            <label className="flex items-center gap-1">
              <div className={`w-3 h-3 border border-black flex items-center justify-center ${!permit.hasSpare ? 'font-bold' : ''}`}>
                {!permit.hasSpare && '✓'}
              </div>
              <span>គ្មាន</span>
            </label>
          </div>
        </div>
      </div>
    </div>

    {/* Structure Condition Table */}
    <div className="mb-2 text-[10px]">
      <div className="font-semibold mb-1">លំនឹងពីទូទៅ:</div>
      <table className="w-full border border-black">
        <thead>
          <tr className="bg-gray-100">
            <th className="border border-black p-1 text-center">គូស ធិក</th>
            <th className="border border-black p-1 text-center">ល្អ</th>
            <th className="border border-black p-1 text-center">មធ្យម</th>
            <th className="border border-black p-1 text-center">អន់</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td className="border border-black p-1">មូលដ្ឋាន</td>
            <td className="border border-black p-1 text-center">{permit.condFoundation === 'ល្អ' && '✓'}</td>
            <td className="border border-black p-1 text-center">{permit.condFoundation === 'មធ្យម' && '✓'}</td>
            <td className="border border-black p-1 text-center">{permit.condFoundation === 'អន់' && '✓'}</td>
          </tr>
          <tr>
            <td className="border border-black p-1">ជញ្ជាំង</td>
            <td className="border border-black p-1 text-center">{permit.condWall === 'ល្អ' && '✓'}</td>
            <td className="border border-black p-1 text-center">{permit.condWall === 'មធ្យម' && '✓'}</td>
            <td className="border border-black p-1 text-center">{permit.condWall === 'អន់' && '✓'}</td>
          </tr>
          <tr>
            <td className="border border-black p-1">ដំបូល</td>
            <td className="border border-black p-1 text-center">{permit.condRoof === 'ល្អ' && '✓'}</td>
            <td className="border border-black p-1 text-center">{permit.condRoof === 'មធ្យម' && '✓'}</td>
            <td className="border border-black p-1 text-center">{permit.condRoof === 'អន់' && '✓'}</td>
          </tr>
          <tr>
            <td className="border border-black p-1">រៀបចំខាងក្នុង</td>
            <td className="border border-black p-1 text-center">{permit.condInterior === 'ល្អ' && '✓'}</td>
            <td className="border border-black p-1 text-center">{permit.condInterior === 'មធ្យម' && '✓'}</td>
            <td className="border border-black p-1 text-center">{permit.condInterior === 'អន់' && '✓'}</td>
          </tr>
        </tbody>
      </table>
    </div>

    {/* Additional Notes / Comments */}
    <div className="text-[9px] mb-2">
      <div className="font-semibold mb-0.5">
        ព័ត៌មានផ្សេងទៀត (បញ្ជាក់ៈ បើមានវិធីកម្មលើចលនា ឬចលនប់កម្មសិទ្ធិ ការកាន់កាប់ខុសចលនា ឬអគារ បើដី ឬអគាររបស់សហគ្រាសជួលរួចហើយឬសេចក្តីផ្សេងៗដែលចាំបាច់):
      </div>
      <div className="border border-gray-400 p-1.5 min-h-[30px] bg-gray-50">
        {permit.notes || ''}
      </div>
    </div>

    {/* Signature Section - Bottom Right */}
    <div className="absolute bottom-[10mm] right-[10mm] text-[10px] text-center">
      <div className="mb-1">{khmerDate}</div>
      <div className="mb-1">{permit.school} {westernDate}</div>
      <div className="h-12"></div>
      <div className="font-bold">ប្រធានអង្គភាព</div>
    </div>

  </div>
</div>

);
}

// Khmer Date Utilities - Matching Budget Request System
// ឧបករណ៍ប្រើប្រាស់កាលបរិច្ឆេទខ្មែរ

export function toKhmerNumeral(num: number | string): string {
const khmerDigits = [‘០’, ‘១’, ‘២’, ‘៣’, ‘៤’, ‘៥’, ‘៦’, ‘៧’, ‘៨’, ‘៩’];
return String(num).split(’’).map(d => khmerDigits[parseInt(d)] || d).join(’’);
}

export function getKhmerLunarDate(date: Date): {
month: string;
day: number;
phase: string;
} {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();

const a = Math.floor((14 - month) / 12);
const y = year + 4800 - a;
const m = month + 12 * a - 3;

const jd = day + Math.floor((153 * m + 2) / 5) + 365 * y +
Math.floor(y / 4) - Math.floor(y / 100) +
Math.floor(y / 400) - 32045;

const lunarMonths = [
‘មិគសិរ’, ‘បុស្ស’, ‘មាឃ’, ‘ផល្គុន’, ‘ចេត្រ’, ‘ពិសាខ’,
‘ជេស្ឋ’, ‘អាសាឍ’, ‘ស្រាពណ៍’, ‘ភទ្របទ’, ‘អស្សុជ’, ‘កក្ដិក’
];

const daysSinceEpoch = jd - 2451550.1;
const lunarCycle = 29.530588853;

const totalLunarDays = daysSinceEpoch % lunarCycle;
const lunarDay = Math.floor(totalLunarDays) + 1;

const totalLunarMonths = Math.floor(daysSinceEpoch / lunarCycle);
const monthIndex = totalLunarMonths % 12;

const lunarPhase = lunarDay <= 15 ? ‘កើត’ : ‘រោច’;
const displayDay = lunarDay <= 15 ? lunarDay : lunarDay - 15;

return {
month: lunarMonths[(monthIndex + 1) % 12],
day: Math.min(displayDay, 15),
phase: lunarPhase
};
}

export function formatKhmerDate(date: Date): string {
const year = date.getFullYear() + 543; // Buddhist Era

const khmerDays = [
‘អាទិត្យ’, ‘ច័ន្ទ’, ‘អង្គារ’, ‘ពុធ’, ‘ព្រហស្បតិ៍’, ‘សុក្រ’, ‘សៅរ៍’
];

const dayOfWeek = khmerDays[date.getDay()];
const lunar = getKhmerLunarDate(date);

const animalYears = [
‘ជូត’, ‘ឆ្លូវ’, ‘ខាល’, ‘ថោះ’, ‘រោង’, ‘ម្សាញ់’,
‘មមី’, ‘ម្ត’, ‘វក’, ‘រកា’, ‘ច’, ‘កុរ’
];
const animalIndex = (date.getFullYear() + 4) % 12;

const eraCycles = [
‘ឯកស័ក’, ‘ទោស័ក’, ‘ត្រីស័ក’, ‘ចត្វាស័ក’, ‘បញ្ចស័ក’,
‘ឆស័ក’, ‘សប្តស័ក’, ‘អដ្ឋស័ក’, ‘នព្វស័ក’, ‘សំរឹទ្ធិស័ក’
];
const eraIndex = (date.getFullYear() + 5) % 10;

const yearCycle = ${animalYears[animalIndex]} ${eraCycles[eraIndex]};

return ថ្ងៃ${dayOfWeek} ${toKhmerNumeral(lunar.day)}${lunar.phase} ខែ${lunar.month} ឆ្នាំ${yearCycle} ព.ស ${toKhmerNumeral(year)};
}

export function formatWesternDate(date: Date): string {
const day = date.getDate();
const month = date.getMonth() + 1;
const year = date.getFullYear();

const khmerMonths = [
‘មករា’, ‘កុម្ភៈ’, ‘មីនា’, ‘មេសា’, ‘ឧសភា’, ‘មិថុនា’,
‘កក្កដា’, ‘សីហា’, ‘កញ្ញា’, ‘តុលា’, ‘វិច្ឆិកា’, ‘ធ្នូ’
];

return ថ្ងៃទី${toKhmerNumeral(day)} ខែ${khmerMonths[month - 1]} ឆ្នាំ${toKhmerNumeral(year)};
}

// Format number to Khmer with commas
export function formatKhmerNumber(num: number): string {
const formatted = num.toLocaleString(‘en-US’);
return toKhmerNumeral(formatted);
}

// Convert number to Khmer words
export function numberToKhmerWords(num: number): string {
if (num === 0) return ‘សូន្យរៀលគត់’;

const ones = [’’, ‘មួយ’, ‘ពីរ’, ‘បី’, ‘បួន’, ‘ប្រាំ’, ‘ប្រាំមួយ’, ‘ប្រាំពីរ’, ‘ប្រាំបី’, ‘ប្រាំបួន’];
const tens = [’’, ‘ដប់’, ‘ម្ភៃ’, ‘សាមសិប’, ‘សែសិប’, ‘ហាសិប’, ‘ហុកសិប’, ‘ចិតសិប’, ‘ប៉ែតសិប’, ‘កៅសិប’];

function convertThreeDigits(n: number): string {
let result = ‘’;
const hundreds = Math.floor(n / 100);
if (hundreds > 0) {
result += ones[hundreds] + ‘រយ’;
n %= 100;
}
const tensDigit = Math.floor(n / 10);
if (tensDigit > 0) {
result += tens[tensDigit];
n %= 10;
}
if (n > 0) {
result += ones[n];
}
return result;
}

let result = ‘’;
let n = Math.floor(num);

const millions = Math.floor(n / 1000000);
if (millions > 0) {
result += convertThreeDigits(millions) + ‘លាន’;
n %= 1000000;
}

const thousands = Math.floor(n / 1000);
if (thousands > 0) {
result += convertThreeDigits(thousands) + ‘ពាន់’;
n %= 1000;
}

const hundreds = Math.floor(n / 100);
if (hundreds > 0) {
result += ones[hundreds] + ‘រយ’;
n %= 100;
}

const tensDigit = Math.floor(n / 10);
if (tensDigit > 0) {
result += tens[tensDigit];
n %= 10;
}

if (n > 0) {
result += ones[n];
}

return result + ‘រៀលគត់’;
}

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