3
ลบโค้ดเดิมออกทั้งหมด แล้ววางโค้ดนี้แทน (มีทั้ง doPost สำหรับบันทึก และ doGet สำหรับแท็บประวัติ):
// ═══════════════════════════════════════════════════
// Progress Report — Apps Script Backend (v3)
// - doPost : บันทึก progress rows / PDF / sync state
// - doGet : โหลดประวัติ / sync state
// ═══════════════════════════════════════════════════
// ── helpers ─────────────────────────────────────────
function getOrCreateFolder(name) {
const iter = DriveApp.getFoldersByName(name);
return iter.hasNext() ? iter.next() : DriveApp.createFolder(name);
}
function getSyncSheet(ss) {
let sh = ss.getSheetByName('_Sync');
if (!sh) {
sh = ss.insertSheet('_Sync');
sh.hideSheet();
}
return sh;
}
// ── doPost ──────────────────────────────────────────
function doPost(e) {
try {
const data = JSON.parse(e.postData.contents);
// 1) PDF → Google Drive
if (data.type === 'pdf') {
const folder = getOrCreateFolder('Progress Reports PDF');
const bytes = Utilities.base64Decode(data.content);
const blob = Utilities.newBlob(bytes, 'application/pdf',
data.filename || 'report.pdf');
const file = folder.createFile(blob);
return ContentService
.createTextOutput(JSON.stringify({ ok: true, id: file.getId() }))
.setMimeType(ContentService.MimeType.JSON);
}
// 2) Sync state (cross-device)
if (data.type === 'sync-save') {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sh = getSyncSheet(ss);
const json = JSON.stringify(data.state || {});
sh.getRange('A1').setValue(json);
sh.getRange('B1').setValue(new Date().toISOString());
return ContentService.createTextOutput('ok');
}
// 3) Progress rows → Sheets
const ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName('Progress');
if (!sheet) {
sheet = ss.insertSheet('Progress');
sheet.appendRow(['เลขที่เอกสาร','วันที่','โครงการ','ชื่องาน','หน่วย',
'ปริมาณวันนี้','สะสม','เป้าหมาย','%','อากาศ','เวลา']);
sheet.setFrozenRows(1);
}
const all = sheet.getDataRange().getValues();
const headers = all[0];
const colDate = headers.indexOf('วันที่');
const colName = headers.indexOf('ชื่องาน');
const idx = {};
for (let i = 1; i < all.length; i++) {
const key = all[i][colDate] + '|' + all[i][colName];
idx[key] = i + 1;
}
(data.rows||[]).forEach(r => {
const row = [r.docno||'', r.date, r.project, r.name, r.unit,
r.todayQty, r.cumulative, r.target, r.pct, r.weather,
new Date().toLocaleString('th-TH')];
const key = r.date + '|' + r.name;
if (idx[key]) {
sheet.getRange(idx[key], 1, 1, row.length).setValues([row]);
} else {
sheet.appendRow(row);
idx[key] = sheet.getLastRow();
}
});
return ContentService.createTextOutput('ok');
} catch(err) {
return ContentService.createTextOutput('error:' + err.message);
}
}
// ── doGet ───────────────────────────────────────────
function doGet(e) {
try {
const ss = SpreadsheetApp.getActiveSpreadsheet();
// sync-load : ส่ง state ล่าสุดกลับมา
if (e.parameter.action === 'sync-load') {
const sh = getSyncSheet(ss);
const val = sh.getRange('A1').getValue();
const ts = sh.getRange('B1').getValue();
const state = val ? JSON.parse(val) : null;
return ContentService
.createTextOutput(JSON.stringify({ state, serverTs: ts ? String(ts) : null }))
.setMimeType(ContentService.MimeType.JSON);
}
// default : ส่ง Progress rows ทั้งหมด
const sheet = ss.getSheetByName('Progress');
if (!sheet) return ContentService.createTextOutput('[]').setMimeType(ContentService.MimeType.JSON);
const all = sheet.getDataRange().getValues();
if (all.length < 2) return ContentService.createTextOutput('[]').setMimeType(ContentService.MimeType.JSON);
const headers = all[0];
const rows = all.slice(1).map(row => {
const obj = {};
headers.forEach((h, i) => { obj[String(h)] = row[i]; });
return obj;
});
return ContentService.createTextOutput(JSON.stringify(rows))
.setMimeType(ContentService.MimeType.JSON);
} catch(err) {
return ContentService
.createTextOutput(JSON.stringify({ error: err.message }))
.setMimeType(ContentService.MimeType.JSON);
}
}
// ── ทดสอบ DriveApp permission ─────────────────────
function testDrive() {
const folder = getOrCreateFolder('Progress Reports PDF');
Logger.log('Folder ID: ' + folder.getId());
}