V3.18
This commit is contained in:
+1
-1
@@ -77,7 +77,7 @@ async function readPushoverConfig(){const value=await readJsonFile(pushoverFile,
|
||||
async function savePushoverConfig(input){const token=String(input?.token||'').trim();const user=String(input?.user||'').trim();if(!pushoverKeyPattern.test(token))throw new Error('Der Pushover Application API Token muss 30 alphanumerische Zeichen enthalten.');if(!pushoverKeyPattern.test(user))throw new Error('Der Pushover User/Group Key muss 30 alphanumerische Zeichen enthalten.');await writePrivateJson(pushoverFile,{token,user,updatedAt:new Date().toISOString()});return {configured:true,userMasked:maskKey(user)};}
|
||||
async function sendPushover(config,{title,message}){
|
||||
const body=new URLSearchParams({token:config.token,user:config.user,title,message});
|
||||
const response=await fetch(PUSHOVER_ENDPOINT,{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded','User-Agent':'FixFin/3.17'},body});
|
||||
const response=await fetch(PUSHOVER_ENDPOINT,{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded','User-Agent':'FixFin/3.18'},body});
|
||||
let payload={}; try{payload=await response.json();}catch{}
|
||||
if(!response.ok||payload.status!==1)throw new Error(Array.isArray(payload.errors)?payload.errors.join(' '):`Pushover-API Fehler (${response.status})`);
|
||||
return payload;
|
||||
|
||||
+10
-1
@@ -103,7 +103,16 @@ export async function createPdfReport(data,{year,accountId}={}){
|
||||
const cols=[{label:'Art',width:88},{label:'Bezeichnung',width:167},{label:'Kategorie',width:105},{label:'Zufluss',width:68,align:'right'},{label:'Abfluss',width:67,align:'right'}];
|
||||
for(let monthIndex=0;monthIndex<12;monthIndex++){
|
||||
const monthRows=rows.filter(r=>r.monthIndex===monthIndex);const month=forecast.rows[monthIndex];
|
||||
addPageIfNeeded(doc,115);doc.fillColor('#17233B').font('Helvetica-Bold').fontSize(14).text(month.name);doc.moveDown(.35);
|
||||
|
||||
// Jeder Monat beginnt auf einer eigenen Seite. Der Monatsname steht immer
|
||||
// links und nutzt die volle Inhaltsbreite, damit er niemals umbrechen kann.
|
||||
doc.addPage();
|
||||
drawPdfHeader(doc,`Kontoauszug ${reportYear}`,account.name);
|
||||
const monthY=doc.y;
|
||||
doc.fillColor('#17233B').font('Helvetica-Bold').fontSize(16)
|
||||
.text(month.name,50,monthY,{width:495,align:'left',lineBreak:false});
|
||||
doc.y=monthY+24;
|
||||
|
||||
pdfMetricRow(doc,[{label:'Zuflüsse',value:pdfMoney(month.displayIncome),positive:true},{label:'Abflüsse',value:pdfMoney(month.displayExpense),negative:true},{label:'Nettofluss',value:pdfMoney(month.balance),positive:month.balance>=0,negative:month.balance<0}]);
|
||||
if(!monthRows.length){doc.fillColor('#667085').font('Helvetica').fontSize(8).text('Keine geplanten Kontobewegungen.');doc.moveDown(.8);continue;}
|
||||
pdfTableHeader(doc,cols);
|
||||
|
||||
Reference in New Issue
Block a user