🛠️ โค้ด Google Apps Script (Code.gs) สำหรับนำไปวางใน Google Sheets
/**
* Google Apps Script สำหรับเชื่อมต่อกับเว็บแอป index.html (FB & Affiliate Tracker)
*/
const SHEET_ID = '1HODr9FK8qSeicKon313Hf8tJRoqNReDhI74j0F0xAdI';
function getTargetSpreadsheet() {
try {
return SpreadsheetApp.getActiveSpreadsheet() || SpreadsheetApp.openById(SHEET_ID);
} catch (e) {
return SpreadsheetApp.openById(SHEET_ID);
}
}
function doGet(e) {
const ss = getTargetSpreadsheet();
const dataSheet = ss.getSheetByName('Data');
const transactions = [];
if (dataSheet && dataSheet.getLastRow() >= 2) {
const values = dataSheet.getRange(2, 1, dataSheet.getLastRow() - 1, 18).getValues();
for (let i = 0; i < values.length; i++) {
const r = values[i];
if (!r[0] || String(r[0]).toLowerCase() === 'total') continue;
let dateStr = '';
if (r[1] instanceof Date) {
dateStr = Utilities.formatDate(r[1], Session.getScriptTimeZone(), 'yyyy-MM-dd');
} else if (r[1]) {
dateStr = String(r[1]).slice(0, 10);
}
transactions.push({
id: Number(r[0]) || (transactions.length + 1),
date: dateStr,
month: String(r[2] || ''),
year: Number(r[3]) || new Date().getFullYear(),
title: String(r[4] || ''),
page: String(r[5] || ''),
category: String(r[6] || ''),
account: String(r[7] || ''),
fbIncome: Number(r[8]) || 0,
affIncome: Number(r[9]) || 0,
expense: Number(r[11]) || 0,
docStatus: String(r[13] || ''),
verified: Boolean(r[14] === true || String(r[14]).toUpperCase() === 'TRUE'),
note: String(r[15] || ''),
affCategory: String(r[16] || ''),
wht: Number(r[17]) || 0
});
}
}
return ContentService.createTextOutput(JSON.stringify({
status: 'ok',
transactions: transactions,
syncedAt: new Date().toISOString()
})).setMimeType(ContentService.MimeType.JSON);
}
function doPost(e) {
try {
const payload = JSON.parse(e.postData.contents);
const ss = getTargetSpreadsheet();
let dataSheet = ss.getSheetByName('Data');
if (!dataSheet) dataSheet = ss.insertSheet('Data');
const headers = [
'ลำดับ', 'วันที่', 'เดือน', 'ปี', 'รายการ', 'ชื่อเพจ / ช่องทาง', 'หมวดหมู่',
'ช่องทางเงิน / บัญชี', 'รายได้สุทธิ\nเนื้อหา FB', 'รายได้สุทธิ\nAffiliate',
'รายได้สุทธิ\nรวม', 'รายจ่าย', 'กำไรสุทธิ', 'เอกสาร /\nใบเสร็จ',
'ตรวจสลิปแล้ว', 'หมายเหตุ', 'หมวดสินค้า Affiliate', 'ภาษีหัก ณ ที่จ่าย (WHT 3%)'
];
dataSheet.getRange(1, 1, 1, headers.length).setValues([headers]);
if (dataSheet.getLastRow() > 1) {
dataSheet.getRange(2, 1, dataSheet.getLastRow() - 1, 18).clearContent();
}
const txList = payload.transactions || [];
if (txList.length > 0) {
const rows = txList.map((t, idx) => {
const rowNum = idx + 2;
return [
t.id || (idx + 1),
t.date || '',
t.month || '',
t.year || '',
t.title || '',
t.page || '',
t.category || '',
t.account || '',
Number(t.fbIncome) || 0,
Number(t.affIncome) || 0,
`=I${rowNum}+J${rowNum}`,
Number(t.expense) || 0,
`=K${rowNum}-L${rowNum}`,
t.docStatus || '',
Boolean(t.verified),
t.note || '',
t.affCategory || '',
Number(t.wht) > 0 ? Number(t.wht) : ''
];
});
dataSheet.getRange(2, 1, rows.length, 18).setValues(rows);
const lastRow = rows.length + 1;
const totalRowNum = rows.length + 2;
const totalRow = [
'Total', '', '', '', '', '', '', '',
`=SUM(I2:I${lastRow})`, `=SUM(J2:J${lastRow})`, `=SUM(K2:K${lastRow})`,
`=SUM(L2:L${lastRow})`, `=SUM(M2:M${lastRow})`, '', '', '', '', ''
];
dataSheet.getRange(totalRowNum, 1, 1, 18).setValues([totalRow]);
}
return ContentService.createTextOutput(JSON.stringify({
status: 'ok',
count: txList.length,
syncedAt: new Date().toISOString()
})).setMimeType(ContentService.MimeType.JSON);
} catch (err) {
return ContentService.createTextOutput(JSON.stringify({
status: 'error',
message: err.toString()
})).setMimeType(ContentService.MimeType.JSON);
}
}