/**
* SlipParser.js (Updated with PromptPayQRParser)
* วิเคราะห์และแยกข้อมูลจากข้อความสลิปการโอนเงิน
* รองรับธนาคารไทยหลักทั้งหมด และ QR Code parsing ตามมาตรฐาน
*/
class SlipParser {
constructor() {
// ข้อมูลธนาคารไทย
this.banks = {
'SCB': {
name: 'ธนาคารไทยพาณิชย์',
keywords: ['ไทยพาณิชย์', 'SCB', 'Siam Commercial Bank'],
color: '#4e1a8b',
logo: 'assets/bank-logos/scb.png'
},
'KBANK': {
name: 'ธนาคารกสิกรไทย',
keywords: ['กสิกรไทย', 'KBANK', 'Kasikorn Bank', 'K-Bank'],
color: '#16a34a',
logo: 'assets/bank-logos/kbank.png'
},
'BBL': {
name: 'ธนาคารกรุงเทพ',
keywords: ['กรุงเทพ', 'BBL', 'Bangkok Bank'],
color: '#1e40af',
logo: 'assets/bank-logos/bbl.png'
},
'KTB': {
name: 'ธนาคารกรุงไทย',
keywords: ['กรุงไทย', 'KTB', 'Krung Thai Bank'],
color: '#1e7e34',
logo: 'assets/bank-logos/ktb.png'
},
'TMB': {
name: 'ธนาคารทหารไทย',
keywords: ['ทหารไทย', 'TMB', 'TMB Bank'],
color: '#6366f1',
logo: 'assets/bank-logos/tmb.png'
},
'GSB': {
name: 'ธนาคารออมสิน',
keywords: ['ออมสิน', 'GSB', 'Government Savings Bank'],
color: '#dc2626',
logo: 'assets/bank-logos/gsb.png'
},
'BAAC': {
name: 'ธนาคารเพื่อการเกษตรและสหกรณ์การเกษตร',
keywords: ['เกษตรและสหกรณ์', 'BAAC', 'เกษตร'],
color: '#059669',
logo: 'assets/bank-logos/baac.png'
}
};
// รูปแบบการค้นหาข้อมูล
this.patterns = {
// จำนวนเงิน
amount: [
/จำนวนเงิน[:\s]*฿?\s*([\d,]+\.?\d*)/i,
/Amount[:\s]*฿?\s*([\d,]+\.?\d*)/i,
/฿\s*([\d,]+\.?\d*)/,
/([\d,]+\.?\d*)\s*บาท/,
/เงิน[:\s]*([\d,]+\.?\d*)/
],
// วันที่และเวลา
datetime: [
/(\d{1,2}\/\d{1,2}\/\d{4})\s*(\d{1,2}:\d{2})/,
/(\d{1,2}-\d{1,2}-\d{4})\s*(\d{1,2}:\d{2})/,
/วันที่[:\s]*(\d{1,2}\/\d{1,2}\/\d{4})/,
/เวลา[:\s]*(\d{1,2}:\d{2})/
],
// ผู้โอน
sender: [
/จาก[:\s]*(.+?)(?=\s*ไปยัง|\s*ถึง|\s*To|\n|$)/i,
/From[:\s]*(.+?)(?=\s*To|\s*ไปยัง|\n|$)/i,
/ผู้โอน[:\s]*(.+?)(?=\s*ผู้รับ|\s*ไปยัง|\n|$)/i
],
// ผู้รับ
receiver: [
/ไปยัง[:\s]*(.+?)(?=\s*จำนวน|\s*Amount|\n|$)/i,
/To[:\s]*(.+?)(?=\s*Amount|\s*จำนวน|\n|$)/i,
/ผู้รับ[:\s]*(.+?)(?=\s*จำนวน|\s*Amount|\n|$)/i,
/ถึง[:\s]*(.+?)(?=\s*จำนวน|\s*Amount|\n|$)/i
],
// รหัสอ้างอิง
reference: [
/รหัสอ้างอิง[:\s]*(.+?)(?=\s|\n|$)/i,
/Reference[:\s]*(.+?)(?=\s|\n|$)/i,
/Ref[:\s]*(.+?)(?=\s|\n|$)/i,
/อ้างอิง[:\s]*(.+?)(?=\s|\n|$)/i,
/Transaction ID[:\s]*(.+?)(?=\s|\n|$)/i
]
};
}
/**
* วิเคราะห์ข้อความและแยกข้อมูลสลิป
*/
parse(text) {
const result = {
amount: null,
datetime: null,
sender: null,
receiver: null,
reference: null,
bank: null,
confidence: 0,
raw_text: text
};
if (!text || text.trim().length === 0) {
return result;
}
// ระบุธนาคาร
result.bank = this.identifyBank(text);
// แยกข้อมูลตามรูปแบบ
result.amount = this.extractAmount(text);
result.datetime = this.extractDateTime(text);
result.sender = this.extractSender(text);
result.receiver = this.extractReceiver(text);
result.reference = this.extractReference(text);
// คำนวณความมั่นใจ
result.confidence = this.calculateConfidence(result);
return result;
}
/**
* ระบุธนาคารจากข้อความ
*/
identifyBank(text) {
for (const [code, bank] of Object.entries(this.banks)) {
for (const keyword of bank.keywords) {
if (text.includes(keyword)) {
return code;
}
}
}
return null;
}
/**
* แยกจำนวนเงิน
*/
extractAmount(text) {
for (const pattern of this.patterns.amount) {
const match = text.match(pattern);
if (match) {
const amount = parseFloat(match[1].replace(/,/g, ''));
if (!isNaN(amount) && amount > 0) {
return amount;
}
}
}
return null;
}
/**
* แยกวันที่และเวลา
*/
extractDateTime(text) {
for (const pattern of this.patterns.datetime) {
const match = text.match(pattern);
if (match) {
if (match.length >= 3) {
return `${match[1]} ${match[2]}`;
} else {
return match[1];
}
}
}
return null;
}
/**
* แยกผู้โอน
*/
extractSender(text) {
for (const pattern of this.patterns.sender) {
const match = text.match(pattern);
if (match) {
return match[1].trim();
}
}
return null;
}
/**
* แยกผู้รับ
*/
extractReceiver(text) {
for (const pattern of this.patterns.receiver) {
const match = text.match(pattern);
if (match) {
return match[1].trim();
}
}
return null;
}
/**
* แยกรหัสอ้างอิง
*/
extractReference(text) {
for (const pattern of this.patterns.reference) {
const match = text.match(pattern);
if (match) {
return match[1].trim();
}
}
return null;
}
/**
* คำนวณความมั่นใจ
*/
calculateConfidence(result) {
let score = 0;
const weights = {
amount: 30,
datetime: 20,
sender: 15,
receiver: 15,
reference: 10,
bank: 10
};
Object.keys(weights).forEach(field => {
if (result[field]) {
score += weights[field];
}
});
return Math.min(score, 100);
}
}