/***********************
* CONFIG
***********************/
const SPREADSHEET_ID = 'GANTI_DENGAN_ID_SHEET_LU';
const SHEET_TRX = 'TRX';
const SHEET_SALDO = 'SALDO';
/***********************
* ENTRY POINT
***********************/
function doGet(e){
const fn = e.parameter.fn;
const payload = e.parameter.payload
? JSON.parse(e.parameter.payload)
: {};
if (!fn || typeof this[fn] !== 'function'){
return _json({ ok:false, error:'Function tidak ditemukan' });
}
try {
const res = this[fn](payload);
return _json(res);
} catch(err){
return _json({ ok:false, error: err.message });
}
}
/***********************
* ROUTER
***********************/
function api_submitPayment(payload){
const jenis = _safe(payload?.jenis).toUpperCase();
if (jenis === 'TOPUP_DANA'){
return api_topupDana_v2(payload);
}
throw new Error('Jenis transaksi tidak dikenali');
}
/***********************
* API TOPUP DANA
***********************/
function api_topupDana_v2(payload){
initSheets();
const extra = payload.extra || {};
const nominal = _num(extra.nominal);
const admin = _num(extra.admin);
const posisi = _safe(extra.posisi).toUpperCase(); // DALAM / LUAR
const modalDari = _safe(extra.modal_dari).toUpperCase() || 'BANK';
const bayarMasuk = _safe(extra.bayar_masuk).toUpperCase() || 'CASH';
if (nominal <= 0) throw new Error('Nominal harus > 0');
if (admin < 0) throw new Error('Admin tidak valid');
const modalOut = (posisi === 'DALAM')
? Math.max(0, nominal - admin)
: nominal;
const totalBayar = (posisi === 'LUAR')
? nominal + admin
: nominal;
// ambil saldo
let saldo = _getSaldo();
let dCash = 0, dBank = 0;
// modal keluar
if (modalDari === 'CASH') dCash -= modalOut;
else dBank -= modalOut;
// uang masuk
if (bayarMasuk === 'CASH') dCash += totalBayar;
else dBank += totalBayar;
saldo.cash += dCash;
saldo.bank += dBank;
_setSaldo(saldo);
_appendTrx({
ts: new Date(),
jenis: 'TOPUP_DANA',
catatan: payload.catatan || '',
d_cash: dCash,
d_bank: dBank,
total_bayar: totalBayar,
profit: admin
});
return {
ok: true,
cash: saldo.cash,
bank: saldo.bank,
profit: admin
};
}
/***********************
* SHEET HELPERS
***********************/
function initSheets(){
const ss = SpreadsheetApp.openById(SPREADSHEET_ID);
if (!ss.getSheetByName(SHEET_TRX)){
ss.insertSheet(SHEET_TRX).appendRow([
'TS','JENIS','CATATAN','D_CASH','D_BANK','TOTAL_BAYAR','PROFIT'
]);
}
if (!ss.getSheetByName(SHEET_SALDO)){
ss.insertSheet(SHEET_SALDO)
.appendRow(['CASH','BANK'])
.appendRow([0,0]);
}
}
function _appendTrx(o){
const sh = SpreadsheetApp
.openById(SPREADSHEET_ID)
.getSheetByName(SHEET_TRX);
sh.appendRow([
o.ts,
o.jenis,
o.catatan,
o.d_cash,
o.d_bank,
o.total_bayar,
o.profit
]);
}
function _getSaldo(){
const sh = SpreadsheetApp
.openById(SPREADSHEET_ID)
.getSheetByName(SHEET_SALDO);
const v = sh.getRange(2,1,1,2).getValues()[0];
return { cash: Number(v[0]), bank: Number(v[1]) };
}
function _setSaldo(s){
const sh = SpreadsheetApp
.openById(SPREADSHEET_ID)
.getSheetByName(SHEET_SALDO);
sh.getRange(2,1,1,2).setValues([[s.cash, s.bank]]);
}
/***********************
* UTIL
***********************/
function _num(v){ return Number(v) || 0; }
function _safe(v){ return (v || '').toString(); }
function _json(o){
return ContentService
.createTextOutput(JSON.stringify(o))
.setMimeType(ContentService.MimeType.JSON);
}
Dashboard Konter Dashboard Konter Cash & Bank Saldo Awal Topup DANA Setor/Tarik Riwayat Saldo CASH + BANK CASH Rp 0 BANK Rp 0 TOTAL Rp 0 Refresh Laporan Buka Laporan Filter tanggal + ringkasan profit & total transaksi. Saldo Awal Saldo Bank Saldo Cash Catatan: nilai ini jadi saldo dasar (bank & cash). Batal Simpan Topup DANA ...
Komentar
Posting Komentar