function jsonOutput(obj) {
return ContentService.createTextOutput(JSON.stringify(obj)).setMimeType(ContentService.MimeType.JSON);
}
function parseJsonCell(value, fallback) {
if (!value) return fallback;
try { return JSON.parse(value); } catch (e) { return fallback; }
}
function valueToMonth(value) {
if (!value) return "";
if (Object.prototype.toString.call(value) === "[object Date]" && !isNaN(value)) {
return Utilities.formatDate(value, Session.getScriptTimeZone(), "yyyy-MM");
}
const text = String(value);
const match = text.match(/\d{4}-\d{2}/);
return match ? match[0] : text;
}
function readLatestRawPlan(ss) {
const rawSheet = ss.getSheetByName("Hrubá data (Záloha)");
if (!rawSheet || rawSheet.getLastRow() < 2) return null;
const parsed = parseJsonCell(rawSheet.getRange(2, 2).getValue(), null);
return parsed && typeof parsed === "object" ? parsed : null;
}
function readSettings(ss) {
const sheet = ss.getSheetByName("Nastavení");
if (!sheet || sheet.getLastRow() < 2) return {};
const map = {
"Aktuální věk": "age",
"Počátek investování": "startMonth",
"Doba vkládání (let)": "sporeniRoky",
"Začátek renty (věk)": "rentaStart",
"Měsíční vklad (Kč)": "vklad",
"Úrok p.a. (%)": "urok",
"Základní RPSN (%)": "urok",
"Plánovaná renta (Kč)": "rentaSuma"
};
const values = sheet.getDataRange().getValues();
const settings = {};
for (let i = 1; i < values.length; i++) {
const key = map[String(values[i][1] || "")];
if (key === "startMonth") settings[key] = valueToMonth(values[i][2]);
else if (key) settings[key] = Number(values[i][2]) || 0;
}
return settings;
}
function readOverrides(ss) {
const sheet = ss.getSheetByName("Měsíční přepisy");
if (!sheet || sheet.getLastRow() < 2) return {};
const values = sheet.getDataRange().getValues();
const overrides = {};
for (let i = 1; i < values.length; i++) {
const month = parseInt(values[i][1], 10);
if (!month) continue;
const ov = {};
if (values[i][2] !== "" && values[i][2] !== null) ov.flow = Number(values[i][2]) || 0;
if (values[i][3] !== "" && values[i][3] !== null) ov.urok = Number(values[i][3]) || 0;
if (values[i][4] !== "" && values[i][4] !== null) ov.zustatek = Number(values[i][4]) || 0;
if (Object.keys(ov).length > 0) overrides[month] = ov;
}
return overrides;
}
function doGet() {
try {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const raw = readLatestRawPlan(ss) || {};
const settings = Object.assign({}, raw.settings || {}, readSettings(ss));
const overrides = Object.assign({}, raw.overrides || {}, readOverrides(ss));
const hasData = Object.keys(settings).length > 0 || Object.keys(overrides).length > 0;
return jsonOutput({ status: "success", data: { settings: settings, overrides: overrides }, hasData: hasData });
} catch (error) {
return jsonOutput({ status: "error", message: error.toString() });
}
}
function doPost(e) {
try {
let payload;
if (e && e.postData && e.postData.contents) {
payload = JSON.parse(e.postData.contents);
} else {
return jsonOutput({ status: "error", message: "Chybí data" });
}
if (payload.action !== 'sync_pension_plan') {
return jsonOutput({ status: "error", message: "Neznámá akce" });
}
const settings = payload.settings || {};
const overrides = payload.overrides || {};
const timestamp = payload.timestamp;
const ss = SpreadsheetApp.getActiveSpreadsheet();
// 1. Hrubá data (Záloha)
let rawSheet = ss.getSheetByName("Hrubá data (Záloha)");
if (!rawSheet) {
rawSheet = ss.insertSheet("Hrubá data (Záloha)");
rawSheet.appendRow(["Čas uložení", "Kompletní JSON data"]);
rawSheet.getRange("A1:B1").setFontWeight("bold");
}
rawSheet.insertRowAfter(1);
rawSheet.getRange(2, 1, 1, 2).setValues([[timestamp, JSON.stringify({ settings: settings, overrides: overrides })]]);
if (rawSheet.getMaxRows() > 50) rawSheet.deleteRows(51, rawSheet.getMaxRows() - 50);
// 2. Nastavení penzijního plánu
let setSheet = ss.getSheetByName("Nastavení");
if (!setSheet) setSheet = ss.insertSheet("Nastavení");
setSheet.clearContents();
setSheet.appendRow(["Poslední Sync", "Parametr", "Hodnota"]);
setSheet.getRange("A1:C1").setFontWeight("bold").setBackground("#f3f4f6");
const rows = [
[timestamp, "Aktuální věk", settings.age || 0],
[timestamp, "Počátek investování", settings.startMonth || ""],
[timestamp, "Doba vkládání (let)", settings.sporeniRoky || 0],
[timestamp, "Začátek renty (věk)", settings.rentaStart || 0],
[timestamp, "Měsíční vklad (Kč)", settings.vklad || 0],
[timestamp, "Základní RPSN (%)", settings.urok || 0],
[timestamp, "Plánovaná renta (Kč)", settings.rentaSuma || 0]
];
setSheet.getRange(2, 1, rows.length, 3).setValues(rows);
// 3. Měsíční přepisy
let ovrSheet = ss.getSheetByName("Měsíční přepisy");
if (!ovrSheet) ovrSheet = ss.insertSheet("Měsíční přepisy");
ovrSheet.clearContents();
ovrSheet.appendRow(["Poslední Sync", "Měsíc index", "Tok hotovosti (Kč)", "RPSN (%)", "Zůstatek (Kč)"]);
ovrSheet.getRange("A1:E1").setFontWeight("bold").setBackground("#f3f4f6");
const ovrEntries = Object.entries(overrides).sort((a, b) => parseInt(a[0]) - parseInt(b[0]));
if (ovrEntries.length > 0) {
const ovrRows = ovrEntries.map(function(entry) {
const m = entry[0];
const ov = entry[1];
return [timestamp, parseInt(m), ov.flow !== undefined ? ov.flow : "", ov.urok !== undefined ? ov.urok : "", ov.zustatek !== undefined ? ov.zustatek : ""];
});
ovrSheet.getRange(2, 1, ovrRows.length, 5).setValues(ovrRows);
}
return jsonOutput({ status: "success", message: "OK" });
} catch (error) {
return jsonOutput({ status: "error", message: error.toString() });
}
}
Kopírovat