/** * BilantAPI.ro pentru Google Sheets * * Formule noi in foaia ta: * =BILANT("33741906"; "cifra_afaceri") ultimul an depus * =BILANT("33741906"; "profit_net"; 2023) un an anume * =BILANT_DENUMIRE("33741906") numele firmei * =BILANTAPI("bilant/33741906/risc"; "scor") orice ruta din documentatie, orice camp * * Instalare: Extensii > Apps Script, lipesti acest cod, salvezi, apoi din * meniul „BilantAPI” al foii alegi „Seteaza cheia API”. Cheia ramane in contul * tau Google (proprietatile utilizatorului), nu in foaie. * * Raspunsurile se tin minte 6 ore: aceeasi formula, recalculata, nu consuma * credite de fiecare data. */ var BILANTAPI_ADRESA = 'https://www.bilantapi.ro/api/v1/'; var BILANTAPI_CACHE_SECUNDE = 6 * 60 * 60; function onOpen() { SpreadsheetApp.getUi() .createMenu('BilantAPI') .addItem('Setează cheia API', 'bilantapiSeteazaCheia') .addItem('Golește memoria (recitește datele)', 'bilantapiGolesteMemoria') .addToUi(); } function bilantapiSeteazaCheia() { var ui = SpreadsheetApp.getUi(); var r = ui.prompt('Cheia API BilantAPI', 'O găsești în contul tău, la „Chei API” (începe cu ba_live_).', ui.ButtonSet.OK_CANCEL); if (r.getSelectedButton() === ui.Button.OK) { PropertiesService.getUserProperties().setProperty('BILANTAPI_CHEIE', r.getResponseText().trim()); ui.alert('Gata. Formulele =BILANT(...) folosesc acum cheia ta.'); } } function bilantapiGolesteMemoria() { PropertiesService.getUserProperties().setProperty('BILANTAPI_GENERATIE', String(Date.now())); SpreadsheetApp.getUi().alert('Gata. Formulele vor citi din nou datele (consumă credite).'); } /** * Un indicator din bilantul unei firme. * * @param {string} cui CUI-ul firmei, fara RO * @param {string} camp ex. cifra_afaceri, profit_net, rezultat_net, venituri_totale, datorii, capitaluri, angajati, marja_neta, roe * @param {number} an optional: anul bilantului; fara el, ultimul an depus * @return valoarea * @customfunction */ function BILANT(cui, camp, an) { var c = bilantapiCui(cui); if (an) { var d = bilantapiCere('bilant/' + c + '/' + an).data || {}; return bilantapiPrimul([d.date, d.indicatori, d], camp); } var s = (bilantapiCere('bilant/' + c + '/sumar').data || {}).sumar || {}; return bilantapiPrimul([s, s.indicatori], camp); } /** * Denumirea firmei. * * @param {string} cui CUI-ul firmei * @return denumirea * @customfunction */ function BILANT_DENUMIRE(cui) { return (bilantapiCere('bilant/' + bilantapiCui(cui) + '/sumar').data || {}).denumire || ''; } /** * Orice ruta din API, orice camp din raspuns. * * @param {string} ruta ex. "bilant/33741906/risc" sau "registru/firme/33741906" * @param {string} cale campul, cu puncte: ex. "scor" sau "sediu.judet"; gol = tot raspunsul, ca text * @return valoarea * @customfunction */ function BILANTAPI(ruta, cale) { var data = bilantapiCere(String(ruta).replace(/^\/+/, '').replace(/^v1\//, '')).data; if (!cale) return JSON.stringify(data); var v = String(cale).split('.').reduce(function (o, k) { return o == null ? null : o[k]; }, data); return v != null && typeof v === 'object' ? JSON.stringify(v) : v; } /* ── Intern ─────────────────────────────────────────────────────────── */ function bilantapiCui(cui) { var c = String(cui).replace(/\D/g, ''); if (!c) throw new Error('CUI lipsă sau greșit.'); return c; } function bilantapiPrimul(surse, camp) { for (var i = 0; i < surse.length; i++) { if (surse[i] && surse[i][camp] !== undefined) return surse[i][camp]; } throw new Error('Câmpul „' + camp + '” nu există în răspuns.'); } function bilantapiCere(ruta) { var p = PropertiesService.getUserProperties(); var cheie = p.getProperty('BILANTAPI_CHEIE'); if (!cheie) throw new Error('Setează cheia: meniul BilantAPI > Setează cheia API.'); var cache = CacheService.getUserCache(); var cheieCache = 'b:' + (p.getProperty('BILANTAPI_GENERATIE') || '0') + ':' + ruta; var tinut = cache.get(cheieCache); if (tinut) return JSON.parse(tinut); var r = UrlFetchApp.fetch(BILANTAPI_ADRESA + ruta, { headers: { 'X-API-KEY': cheie, Accept: 'application/json' }, muteHttpExceptions: true, }); var corp = r.getContentText(); var json; try { json = JSON.parse(corp); } catch (e) { throw new Error('Răspuns neașteptat (' + r.getResponseCode() + ').'); } if (r.getResponseCode() >= 400 || json.success === false) { throw new Error((json.error && (json.error.message || json.error.mesaj)) || json.message || ('Eroare ' + r.getResponseCode())); } if (corp.length < 90000) cache.put(cheieCache, corp, BILANTAPI_CACHE_SECUNDE); return json; }