Loading QC list...
function doPost(e) {
var data = JSON.parse(e.postData.contents);
var ss = SpreadsheetApp.getActiveSpreadsheet();
if (data.action === 'qcReview') {
var qc0 = ss.getSheetByName('QC') || ss.insertSheet('QC');
qc0.appendRow([new Date(), data.inv, data.id, 'Reviewed', data.name || '']);
return ContentService.createTextOutput(JSON.stringify({status: 'success'})).setMimeType(ContentService.MimeType.JSON);
}
if (data.action === 'qc_rejection') {
var qr = ss.getSheetByName('QC_Rejections') || ss.insertSheet('QC_Rejections');
if (qr.getLastRow() === 0) qr.appendRow(['Timestamp', 'ID', 'Invoice No', 'Supplier', 'Item', 'Size', 'Qty', 'Reason', 'Status', 'By']);
var rejRows = data.rows || [];
for (var ri = 0; ri < rejRows.length; ri++) {
qr.appendRow([new Date(), rejRows[ri].id, rejRows[ri].inv, rejRows[ri].sup, rejRows[ri].item, rejRows[ri].size, rejRows[ri].qty, rejRows[ri].reason, 'Pending', rejRows[ri].name || '']);
}
return ContentService.createTextOutput(JSON.stringify({status: 'success'})).setMimeType(ContentService.MimeType.JSON);
}
var sheet = ss.getActiveSheet();
var imgs = (data.imagesBase64 && data.imagesBase64.length) ? data.imagesBase64 : (data.imageBase64 ? [data.imageBase64] : []);
var urls = [];
for (var i = 0; i < imgs.length; i++) {
var b64 = imgs[i].split(',')[1];
var blob = Utilities.newBlob(Utilities.base64Decode(b64), 'image/jpeg', data.erpKey + '_p' + (i + 1) + '.jpg');
var file = DriveApp.createFile(blob);
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
urls.push(file.getUrl());
}
sheet.appendRow([new Date(), data.invoiceNo, data.supplierName, data.invoiceDate, data.invoiceName, data.erpKey, (data.pageCount || 1), urls.join(' | '), data.operator || '']);
return ContentService.createTextOutput(JSON.stringify({status: 'success'})).setMimeType(ContentService.MimeType.JSON);
}
function doGet(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var out = { rejections: [], invoices: [] };
var qc = ss.getSheetByName('QC');
if (qc) {
var rows = qc.getDataRange().getValues();
// QC sheet columns: Date | InvoiceNo | Supplier | Item | Qty | Reason | Status
for (var i = 1; i < rows.length; i++) {
out.rejections.push({ id: 'row' + i, inv: String(rows[i][1]), sup: String(rows[i][2]), item: String(rows[i][3]), qty: String(rows[i][4]), reason: String(rows[i][5]), date: String(rows[i][0]), status: String(rows[i][6] || 'Pending') });
}
}
var qrGet = ss.getSheetByName('QC_Rejections');
if (qrGet) {
var qrows = qrGet.getDataRange().getValues();
// QC_Rejections columns: Timestamp | ID | InvoiceNo | Supplier | Item | Size | Qty | Reason | Status
for (var qi = 1; qi < qrows.length; qi++) {
if (!qrows[qi][1]) continue;
out.rejections.push({ id: String(qrows[qi][1]), inv: String(qrows[qi][2]), sup: String(qrows[qi][3]), item: String(qrows[qi][4]), size: String(qrows[qi][5]), qty: String(qrows[qi][6]), reason: String(qrows[qi][7]), date: String(qrows[qi][0]), status: String(qrows[qi][8] || 'Pending') });
}
}
// Main sheet: Timestamp | InvoiceNo | Supplier | InvoiceDate | Type | ErpKey | PageCount | PhotoURLs
function driveView(u) {
var m = String(u).match(/\/d\/([-\w]{20,})/) || String(u).match(/[?&]id=([-\w]{20,})/);
if (!m) return { thumb: u, full: u };
return { thumb: 'https://drive.google.com/thumbnail?id=' + m[1] + '&sz=w1600', full: 'https://lh3.googleusercontent.com/d/' + m[1] };
}
var main = ss.getSheets()[0];
var mrows = main.getDataRange().getValues();
for (var j = 1; j < mrows.length; j++) {
if (!mrows[j][1]) continue;
var c6 = String(mrows[j][6] || '');
var c7 = String(mrows[j][7] || '');
var raw = c7 ? c7.split(' | ').filter(Boolean) : (c6.indexOf('http') === 0 ? [c6] : []);
var fulls = [], thumbs = [];
for (var k = 0; k < raw.length; k++) {
var dv = driveView(raw[k]);
fulls.push(dv.full);
thumbs.push(dv.thumb);
}
out.invoices.push({ inv: String(mrows[j][1]), sup: String(mrows[j][2]), date: String(mrows[j][3]), pages: fulls, full: fulls, thumbs: thumbs });
}
return ContentService.createTextOutput(JSON.stringify(out)).setMimeType(ContentService.MimeType.JSON);
}