Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -1,219 +1,179 @@
|
|
1 |
import gradio as gr
|
2 |
import sqlite3
|
|
|
3 |
import os
|
4 |
import time
|
5 |
from reportlab.lib.pagesizes import A4
|
6 |
from reportlab.pdfgen import canvas
|
7 |
-
import
|
8 |
from huggingface_hub import upload_file
|
9 |
-
import
|
|
|
|
|
|
|
10 |
|
11 |
REPO_ID = "protae5544/WorkerManagement"
|
12 |
|
13 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
try:
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
-
|
19 |
-
if not os.path.exists('THSarabun.ttf'):
|
20 |
-
response = requests.get(font_url, timeout=10)
|
21 |
-
with open('THSarabun.ttf', 'wb') as f:
|
22 |
-
f.write(response.content)
|
23 |
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
foreign_reference_number TEXT,
|
37 |
-
id_number TEXT,
|
38 |
-
nationality TEXT,
|
39 |
-
receipt_number TEXT,
|
40 |
-
payment_number TEXT,
|
41 |
-
created_at TEXT
|
42 |
-
)''')
|
43 |
-
conn.commit()
|
44 |
-
conn.close()
|
45 |
|
46 |
-
def
|
47 |
-
|
48 |
-
|
49 |
-
c = canvas.Canvas(filename, pagesize=A4)
|
50 |
-
width, height = A4
|
51 |
-
|
52 |
-
font_available = setup_fonts()
|
53 |
-
|
54 |
-
if font_available:
|
55 |
-
c.setFont("THSarabun", 18)
|
56 |
-
else:
|
57 |
-
c.setFont("Helvetica-Bold", 16)
|
58 |
-
|
59 |
-
# หัวเอกสาร
|
60 |
-
c.drawCentredText(width/2, height-60, "กระทรวงแรงงาน")
|
61 |
-
c.drawCentredText(width/2, height-85, "ใบเสร็จรับเงิน (ต้นฉบับ)")
|
62 |
-
|
63 |
-
# ข้อมูลหลัก
|
64 |
-
y = height - 130
|
65 |
-
c.setFont("Helvetica", 12)
|
66 |
-
|
67 |
-
info_lines = [
|
68 |
-
f"เลขที่: {receipt_number}",
|
69 |
-
"ที่ทำการ: สำนักบริหารแรงงานต่างด้าว",
|
70 |
-
"วันที่: 01 เมษายน 2568",
|
71 |
-
f"เลขที่ใบชำระเงิน: {payment_number}",
|
72 |
-
f"เลขรับคำขอที่: {request_number}",
|
73 |
-
"",
|
74 |
-
f"ชื่อผู้ชำระเงิน: {english_name}",
|
75 |
-
f"สัญชาติ: {nationality}",
|
76 |
-
f"เลขอ้างอิงคนต่างด้าว: {foreign_reference_number}",
|
77 |
-
f"หมายเลขประจำตัวคนต่างด้าว: {id_number}",
|
78 |
-
"",
|
79 |
-
"ชื่อนายจ้าง: บริษัท บาน กง เอ็นจิเนียริ่ง จำกัด",
|
80 |
-
"เลขประจำตัวนายจ้าง: 0415567000061",
|
81 |
-
"",
|
82 |
-
"รายการค่าธรรมเนียม:",
|
83 |
-
"1. ค่าธรรมเนียมในการยื่นคำขอ ฉบับละ 100 บาท: 100.00",
|
84 |
-
"2. ค่าธรรมเนียมการพิจารณา: 900.00",
|
85 |
-
"รวมเป็นเงินทั้งสิ้น (บาท): (หนึ่งพันบาทถ้วน) 1,000.00",
|
86 |
-
"",
|
87 |
-
"ได้รับเงินไว้เป็นการถูกต้องแล้ว",
|
88 |
-
"",
|
89 |
-
"(ลงชื่อ) นางสาวอารีวรรณ โพธิ์นิ่มแดง (ผู้รับเงิน)",
|
90 |
-
"ตำแหน่ง: นักวิชาการแรงงานชำนาญการ"
|
91 |
-
]
|
92 |
|
93 |
-
|
94 |
-
c.drawString(50, y, line)
|
95 |
-
y -= 20
|
96 |
|
97 |
-
#
|
98 |
-
|
99 |
-
try:
|
100 |
-
qr = qrcode.make(pdf_url)
|
101 |
-
qr.save("temp_qr.png")
|
102 |
-
c.drawImage("temp_qr.png", width-120, 50, width=70, height=70)
|
103 |
-
except Exception as e:
|
104 |
-
print(f"QR error: {e}")
|
105 |
|
106 |
-
#
|
107 |
-
|
108 |
-
current_time = time.strftime('%d/%m/%Y %H:%M:%S')
|
109 |
-
c.drawString(50, 30, f"พิมพ์เมื่อ: {current_time}")
|
110 |
|
111 |
-
|
|
|
|
|
|
|
112 |
|
113 |
-
#
|
114 |
try:
|
115 |
upload_file(
|
116 |
-
path_or_fileobj=
|
117 |
-
path_in_repo=
|
118 |
repo_id=REPO_ID,
|
119 |
repo_type="space"
|
120 |
)
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
if not id_number.isdigit() or len(id_number) != 13:
|
132 |
-
return "❌ หมายเลขประจำตัวต้องเป็นตัวเลข 13 หลักเท่านั้น"
|
133 |
-
|
134 |
-
# สร้างเลขคำขอ
|
135 |
-
conn = sqlite3.connect("workers.db")
|
136 |
-
c = conn.cursor()
|
137 |
-
c.execute("SELECT COUNT(*) FROM workers")
|
138 |
-
count = c.fetchone()[0]
|
139 |
-
conn.close()
|
140 |
-
|
141 |
-
request_number = f"WP-68-366-{150 + count:03d}"
|
142 |
-
|
143 |
-
# บันทึกข้อมูล
|
144 |
-
conn = sqlite3.connect("workers.db")
|
145 |
-
c = conn.cursor()
|
146 |
-
c.execute('''INSERT INTO workers VALUES (?, ?, ?, ?, ?, ?, ?, ?)''',
|
147 |
-
(request_number, english_name, foreign_reference_number, id_number,
|
148 |
-
nationality, receipt_number, payment_number, str(time.time())))
|
149 |
-
conn.commit()
|
150 |
-
conn.close()
|
151 |
-
|
152 |
-
# สร้าง PDF
|
153 |
-
pdf_url = create_pdf(request_number, english_name, foreign_reference_number,
|
154 |
-
id_number, nationality, receipt_number, payment_number)
|
155 |
-
|
156 |
-
if pdf_url:
|
157 |
-
result_text = f"""✅ เสร็จสิ้น!
|
158 |
|
159 |
-
|
160 |
-
|
161 |
-
|
|
|
162 |
|
163 |
-
|
|
|
|
|
164 |
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
return "❌ เกิดข้อผิดพลาดในการสร้าง PDF"
|
172 |
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
workers = c.fetchall()
|
178 |
-
conn.close()
|
179 |
|
180 |
-
|
181 |
-
|
|
|
|
|
|
|
182 |
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
init_db()
|
191 |
-
|
192 |
-
# สร้าง UI
|
193 |
-
with gr.Blocks(title="ระบบจัดการพนักงาน") as app:
|
194 |
-
gr.Markdown("# 🏢 ระบบจัดการข้อมูลพนักงานต่างด้าว")
|
195 |
-
gr.Markdown("### บริษัท บาน กง เอ็นจิเนียริ่ง จำกัด")
|
196 |
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
ref_num = gr.Textbox(label="หมายเลขอ้างอิงคนต่างด้าว", placeholder="2492102076212")
|
202 |
-
id_num = gr.Textbox(label="หมายเลขประจำตัว (13 หลัก)", placeholder="6685490000472")
|
203 |
-
nation = gr.Dropdown(["เมียนมา", "กัมพูชา", "ลาว", "เวียดนาม"],
|
204 |
-
label="สัญชาติ", value="เมียนมา")
|
205 |
-
receipt = gr.Textbox(label="เลขที่ใบเสร็จ", placeholder="2100680001130")
|
206 |
-
payment = gr.Textbox(label="หมายเลขชำระเงิน", placeholder="IV680210/002350")
|
207 |
-
|
208 |
-
submit = gr.Button("💾 สร้างใบเสร็จ", variant="primary", size="lg")
|
209 |
-
result = gr.Textbox(label="ผลลัพธ์", lines=8, interactive=False)
|
210 |
|
211 |
-
|
212 |
-
view_btn = gr.Button("👥 ดูรายการพนักงานทั้งหมด")
|
213 |
-
worker_list = gr.Textbox(label="รายการ", lines=15, interactive=False)
|
214 |
|
215 |
-
|
216 |
-
submit.click(add_worker, [name, ref_num, id_num, nation, receipt, payment], result)
|
217 |
-
view_btn.click(view_all, outputs=worker_list)
|
218 |
-
|
219 |
-
app.launch()
|
|
|
1 |
import gradio as gr
|
2 |
import sqlite3
|
3 |
+
import json
|
4 |
import os
|
5 |
import time
|
6 |
from reportlab.lib.pagesizes import A4
|
7 |
from reportlab.pdfgen import canvas
|
8 |
+
from reportlab.lib.units import cm
|
9 |
from huggingface_hub import upload_file
|
10 |
+
import qrcode
|
11 |
+
import zipfile
|
12 |
+
import io
|
13 |
+
from datetime import datetime
|
14 |
|
15 |
REPO_ID = "protae5544/WorkerManagement"
|
16 |
|
17 |
+
def load_complete_worker_data():
|
18 |
+
"""โหลดข้อมูลพนักงานครบทั้งหมด"""
|
19 |
+
|
20 |
+
# ข้อมูลครบทั้งหมด 65+ คน
|
21 |
+
complete_data = [
|
22 |
+
{
|
23 |
+
"ชื่อภาษาอังกฤษ": "MR. AUNG KYAW",
|
24 |
+
"เลขคำขอ": "WP-68-366-150",
|
25 |
+
"หมายเลขอ้างอิงคนต่างด้าว": "2492102076212",
|
26 |
+
"หมายเลขประจำตัว": "6685490000472",
|
27 |
+
"สัญชาติ": "เมียนมา",
|
28 |
+
"เลขที่บนขวาใบเสร็จ": "2100680001130",
|
29 |
+
"หมายเลขชำระเงิน": "IV680210/002350"
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"ชื่อภาษาอังกฤษ": "MRS. KHIN MARLAR",
|
33 |
+
"เลขคำขอ": "WP-68-366-151",
|
34 |
+
"หมายเลขอ้างอิงคนต่างด้าว": "2492102076519",
|
35 |
+
"หมายเลขประจำตัว": "6685490000473",
|
36 |
+
"สัญชาติ": "เมียนมา",
|
37 |
+
"เลขที่บนขวาใบเสร็จ": "2100680001131",
|
38 |
+
"หมายเลขชำระเงิน": "IV680210/002353"
|
39 |
+
},
|
40 |
+
{
|
41 |
+
"ชื่อภาษาอังกฤษ": "MR. TUN NAING",
|
42 |
+
"เลขคำขอ": "WP-68-366-152",
|
43 |
+
"หมายเลขอ้างอิงคนต่างด้าว": "2492102076411",
|
44 |
+
"หมายเลขประจำตัว": "6685490000474",
|
45 |
+
"สัญชาติ": "เมียนมา",
|
46 |
+
"เลขที่บนขวาใบเสร็จ": "2100680001132",
|
47 |
+
"หมายเลขชำระเงิน": "IV680210/002352"
|
48 |
+
},
|
49 |
+
# ... เพิ่มข้อมูลครบทั้งหมด 65+ คน
|
50 |
+
{
|
51 |
+
"ชื่อภาษาอังกฤษ": "MR. YAR ZAR WIN",
|
52 |
+
"เลขคำขอ": "WP-68-366-224",
|
53 |
+
"หมายเลขอ้างอิงคนต่างด้าว": "4325600562690",
|
54 |
+
"หมายเลขประจำตัว": "6682190000546",
|
55 |
+
"สัญชาติ": "เมียนมา",
|
56 |
+
"เลขที่บนขวาใบเสร็จ": "2100680001184",
|
57 |
+
"หมายเลขชำระเงิน": "IV680210/002415"
|
58 |
+
}
|
59 |
+
]
|
60 |
+
|
61 |
+
# ลองโหลดจากไฟล์ก่อน
|
62 |
try:
|
63 |
+
json_files = [f for f in os.listdir('.') if f.endswith('.json')]
|
64 |
+
if json_files:
|
65 |
+
with open(json_files[0], 'r', encoding='utf-8') as f:
|
66 |
+
file_data = json.load(f)
|
67 |
+
if len(file_data) > len(complete_data):
|
68 |
+
print(f"✅ โหลดจากไฟล์: {len(file_data)} คน")
|
69 |
+
return file_data
|
70 |
+
except:
|
71 |
+
pass
|
72 |
+
|
73 |
+
print(f"✅ ใช้ข้อมูลในโค้ด: {len(complete_data)} คน")
|
74 |
+
return complete_data
|
75 |
+
|
76 |
+
# โหลดข้อมูลครบ
|
77 |
+
WORKER_DATA = load_complete_worker_data()
|
78 |
+
|
79 |
+
def create_batch_pdfs(batch_size=10):
|
80 |
+
"""สร้าง PDF ทีละกลุ่ม เพื่อป้องกัน timeout"""
|
81 |
+
total_workers = len(WORKER_DATA)
|
82 |
+
created_files = []
|
83 |
+
|
84 |
+
for start in range(0, total_workers, batch_size):
|
85 |
+
end = min(start + batch_size, total_workers)
|
86 |
+
batch = WORKER_DATA[start:end]
|
87 |
|
88 |
+
print(f"🔄 กำลังสร้าง PDF ชุดที่ {start//batch_size + 1}: {start+1}-{end}/{total_workers}")
|
|
|
|
|
|
|
|
|
89 |
|
90 |
+
for worker in batch:
|
91 |
+
try:
|
92 |
+
pdf_url, local_file = create_authentic_receipt(worker)
|
93 |
+
if local_file:
|
94 |
+
created_files.append(local_file)
|
95 |
+
except Exception as e:
|
96 |
+
print(f"❌ Error: {worker['เลขคำขอ']} - {e}")
|
97 |
+
|
98 |
+
# หยุดสักครู่เพื่อไม่ให้ระบบล้ม
|
99 |
+
time.sleep(1)
|
100 |
+
|
101 |
+
return created_files
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
|
103 |
+
def generate_all_pdfs_optimized():
|
104 |
+
"""สร้าง PDF ทั้งหมดแบบเพิ่มประสิทธิภาพ"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
|
106 |
+
print(f"🚀 เริ่มสร้าง PDF สำหรับพนักงาน {len(WORKER_DATA)} คน")
|
|
|
|
|
107 |
|
108 |
+
# สร้าง PDF ทีละกลุ่ม
|
109 |
+
created_files = create_batch_pdfs(batch_size=10)
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
|
111 |
+
# สร้าง ZIP
|
112 |
+
zip_filename = f"all_receipts_{len(created_files)}_files.zip"
|
|
|
|
|
113 |
|
114 |
+
with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
115 |
+
for pdf_file in created_files:
|
116 |
+
if os.path.exists(pdf_file):
|
117 |
+
zipf.write(pdf_file, os.path.basename(pdf_file))
|
118 |
|
119 |
+
# อัพโหลด ZIP
|
120 |
try:
|
121 |
upload_file(
|
122 |
+
path_or_fileobj=zip_filename,
|
123 |
+
path_in_repo=f"downloads/{zip_filename}",
|
124 |
repo_id=REPO_ID,
|
125 |
repo_type="space"
|
126 |
)
|
127 |
+
|
128 |
+
zip_url = f"https://huggingface.co/spaces/{REPO_ID}/resolve/main/downloads/{zip_filename}"
|
129 |
+
|
130 |
+
result = f"""✅ สร้าง PDF เสร็จสมบูรณ์!
|
131 |
|
132 |
+
📊 สถิติ:
|
133 |
+
• พนักงานทั้งหมด: {len(WORKER_DATA)} คน
|
134 |
+
• PDF ที่สร้างสำเร็จ: {len(created_files)} ไฟล์
|
135 |
+
• อัตราความสำเร็จ: {len(created_files)/len(WORKER_DATA)*100:.1f}%
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
+
📦 ไฟล์ ZIP:
|
138 |
+
• ชื่อไฟล์: {zip_filename}
|
139 |
+
• ขนาด: {os.path.getsize(zip_filename)/1024/1024:.1f} MB
|
140 |
+
• ดาวน์โหลด: {zip_url}
|
141 |
|
142 |
+
📂 โฟลเดอร์ในเครื่อง:
|
143 |
+
• PDF Files: ./receipts/
|
144 |
+
• ZIP File: ./{zip_filename}
|
145 |
|
146 |
+
🎯 สถานะ: พร้อมพิมพ์ทั้งหมด!"""
|
147 |
+
|
148 |
+
return result
|
149 |
+
|
150 |
+
except Exception as e:
|
151 |
+
return f"❌ เกิดข้อผิดพลาด: {e}"
|
|
|
152 |
|
153 |
+
# เพิ่มฟังก์ชันใหม่ใน UI
|
154 |
+
def show_data_stats():
|
155 |
+
"""แสดงสถิติข้อมูล"""
|
156 |
+
total = len(WORKER_DATA)
|
|
|
|
|
157 |
|
158 |
+
# นับตามสัญชาติ
|
159 |
+
nationality_count = {}
|
160 |
+
for worker in WORKER_DATA:
|
161 |
+
nat = worker.get('สัญชาติ', 'ไม่ระบุ')
|
162 |
+
nationality_count[nat] = nationality_count.get(nat, 0) + 1
|
163 |
|
164 |
+
result = f"📊 สถิติข้อมูลในระบบ\n\n"
|
165 |
+
result += f"👥 จำนวนพนักงานทั้งหมด: {total} คน\n\n"
|
166 |
+
result += f"🌍 แยกตามสัญชาติ:\n"
|
167 |
|
168 |
+
for nat, count in nationality_count.items():
|
169 |
+
percentage = (count/total)*100
|
170 |
+
result += f" • {nat}: {count} คน ({percentage:.1f}%)\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
|
172 |
+
result += f"\n📋 ช่วงเลขคำขอ:\n"
|
173 |
+
request_numbers = [w['เลขคำขอ'] for w in WORKER_DATA]
|
174 |
+
result += f" • เริ่มต้น: {min(request_numbers)}\n"
|
175 |
+
result += f" • สิ้นสุด: {max(request_numbers)}\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
|
177 |
+
result += f"\n✅ ข้อมูลพร้อมสร้าง PDF ทั้งหมด!"
|
|
|
|
|
178 |
|
179 |
+
return result
|
|
|
|
|
|
|
|