commit
parent
4051e01463
commit
4f7ce9a1ba
|
|
@ -0,0 +1,7 @@
|
|||
var rh = 14;
|
||||
var sp = 4;
|
||||
var y = sp;
|
||||
|
||||
exports.rh = rh;
|
||||
exports.sp = sp;
|
||||
exports.y = y;
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* Utility functions that concern about retrieving and storing data in a project file.
|
||||
* this file also includes a default project in case a user want to start anew.
|
||||
*/
|
||||
|
||||
const VERSION = "0.1";
|
||||
|
||||
let projectData = {
|
||||
version: VERSION,
|
||||
expenses: [],
|
||||
accounts: [
|
||||
{
|
||||
name: "Current",
|
||||
entries: [
|
||||
{
|
||||
date: 1704067200000,
|
||||
subject: '(Savings) Initial Deposit',
|
||||
amount: -500,
|
||||
targetAccount: "Savings"
|
||||
},
|
||||
{
|
||||
date: 1704067200000,
|
||||
subject: 'Salary',
|
||||
amount: 2182.15
|
||||
},
|
||||
{
|
||||
date: 1704153600000,
|
||||
subject: 'Rent',
|
||||
amount: -800
|
||||
},
|
||||
{
|
||||
date: 1704240000000,
|
||||
subject: 'Groceries',
|
||||
amount: -24.19
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Savings",
|
||||
entries: [
|
||||
{
|
||||
date: 1704067200000,
|
||||
subject: 'Initial Deposit',
|
||||
amount: 500
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
class Project {
|
||||
|
||||
#projectData;
|
||||
|
||||
addAccount(accountName) {
|
||||
|
||||
}
|
||||
|
||||
closeAccount(accountName, transferToOtherAccount) {
|
||||
|
||||
}
|
||||
|
||||
getSummation(accountName) {
|
||||
const acc = this.#projectData.accounts.find(p => p.name === accountName);
|
||||
return acc.entries.reduce((sum, e) => sum + parseFloat(e.amount), 0);
|
||||
}
|
||||
|
||||
getAccounts() {
|
||||
|
||||
}
|
||||
|
||||
getAccountEntries(accountName) {
|
||||
|
||||
}
|
||||
|
||||
save(to) {
|
||||
|
||||
}
|
||||
|
||||
constructor(projectData) {
|
||||
|
||||
}
|
||||
|
||||
static open(from) {
|
||||
return new Project()
|
||||
}
|
||||
|
||||
}
|
||||
394
index.js
394
index.js
|
|
@ -1,279 +1,17 @@
|
|||
var gui = require('gui');
|
||||
var fs = require('fs');
|
||||
const { waitForAddAccountWindow } = require('./waitForAddAccountWindow');
|
||||
const { waitForDataEntryWindow } = require('./waitForDataEntryWindow');
|
||||
const { waitForCloseAccountWindow } = require('./waitForCloseAccountWindow');
|
||||
const { getAccounts, toListViewEntries, getSummation } = require('./utils');
|
||||
const { waitForChartWindow } = require('./waitForChartWindow');
|
||||
|
||||
function mainWindow(projectData) {
|
||||
|
||||
var rh = 14;
|
||||
var sp = 4;
|
||||
var y = sp;
|
||||
|
||||
function getAccounts(data) {
|
||||
const resultData = [];
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
resultData.push(data[i].name);
|
||||
}
|
||||
return resultData
|
||||
}
|
||||
|
||||
function toListViewEntries(entries, visibleCols) {
|
||||
let cols = visibleCols;
|
||||
return entries.map(e => {
|
||||
const amount = parseFloat(e.amount);
|
||||
const subject = ("" + e.subject).substr(0, cols - 20).padEnd(cols - 20, ' ');
|
||||
const sum = ((amount >= 0 ? "+" : "") + amount.toFixed(2)).substr(0, 10).padStart(10, ' ');
|
||||
const d = new Date(e.date);
|
||||
const date = d.getDate().toString().padStart(2, '0') + "-" + (d.getMonth() + 1).toString().padStart(2, '0') + "-" + d.getFullYear();
|
||||
let s = (date.substr(0, 10)) + " " + subject + " " + sum;
|
||||
return s;
|
||||
});
|
||||
}
|
||||
|
||||
function getSummation(entries) {
|
||||
return entries.reduce((sum, e) => sum + parseFloat(e.amount), 0);
|
||||
}
|
||||
|
||||
function toDateByComponents(s) {
|
||||
const parts = s.split("-");
|
||||
if (parts.length !== 3) return null;
|
||||
const day = parseInt(parts[0]);
|
||||
const month = parseInt(parts[1]) - 1;
|
||||
const year = parseInt(parts[2]);
|
||||
if (isNaN(day) || isNaN(month) || isNaN(year)) return null;
|
||||
return new Date(year, month, day).getTime();
|
||||
}
|
||||
|
||||
function closeAccount(data, selectedAccount) {
|
||||
let gadgets = [];
|
||||
|
||||
const accountNameId = 301;
|
||||
const remainingId = 302;
|
||||
const transferCheckboxId = 303;
|
||||
const targetAccountId = 304;
|
||||
const executeButtonId = 305;
|
||||
|
||||
gadgets.push({ kind: 'text', id: accountNameId, label: "Account:", left: sp+128, top: y, width: 200, height: rh, value: selectedAccount.name});
|
||||
const openStanding = getSummation(selectedAccount.entries);
|
||||
gadgets.push({ kind: 'text', id: remainingId, label: "Remaining " + (openStanding>0? "funds": "debt"), left: sp+128, top: y+rh+sp, width: 100, height: rh})
|
||||
gadgets.push({ kind: 'checkbox', id: transferCheckboxId, label: "Transfer to:", left: sp, top: y+rh+sp+rh+sp, height: rh, value: 0});
|
||||
let accounts = [];
|
||||
for (let i = 0; i < data.length; ++i) {
|
||||
if (data[i].name != selectedAccount.name) {
|
||||
accounts.push(data[i].name);
|
||||
}
|
||||
}
|
||||
gadgets.push({ kind: 'cycle', id: targetAccountId, left: sp+128, top: y+rh+sp+rh+sp, width: 120, height: rh, items: accounts, value: 0 });
|
||||
gadgets.push({ kind: 'button', id: executeButtonId, left: sp+128, top: y+rh+sp+rh+sp+rh+sp, height: rh, width: 120, label: "Close Account"})
|
||||
|
||||
let win = gui.createWindow({
|
||||
title: "Close Account '" + selectedAccount.name + "'",
|
||||
width: sp+128+240+sp,
|
||||
height: y+rh+sp+rh+sp+rh+sp+rh+sp,
|
||||
left: 30,
|
||||
top: 30,
|
||||
gadgets: gadgets
|
||||
});
|
||||
|
||||
gui.setDisabled(win, targetAccountId, true);
|
||||
gui.set(win, remainingId, openStanding.toFixed(2));
|
||||
|
||||
while (true) {
|
||||
var evt = gui.waitEvent(win);
|
||||
if (!evt) continue;
|
||||
|
||||
if (evt.type === 'close') {
|
||||
gui.closeWindow(win);
|
||||
return null;
|
||||
}
|
||||
if (evt.type === 'gadgetup') {
|
||||
if (evt.id === transferCheckboxId) {
|
||||
gui.setDisabled(win, targetAccountId, !gui.get(win, transferCheckboxId));
|
||||
}
|
||||
if (evt.id === executeButtonId) {
|
||||
if (gui.get(win, transferCheckboxId)) {
|
||||
let otherAccount;
|
||||
let target = accounts[gui.get(win, targetAccountId)];
|
||||
for (let i = 0; data.length;++i) {
|
||||
if (data[i].name === target) {
|
||||
otherAccount = data[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (otherAccount) {
|
||||
otherAccount.entries.push({
|
||||
date: Date.now(),
|
||||
subject: '('+ selectedAccount.name + ') Closing Statement',
|
||||
amount: -openStanding,
|
||||
targetAccount: null
|
||||
})
|
||||
}
|
||||
gui.closeWindow(win);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addAccount(data) {
|
||||
let gadgets = [];
|
||||
|
||||
gadgets.push({ kind: 'string', id: 201, label: "Name:", left: sp + 80, top: y, width: 300, height: rh});
|
||||
gadgets.push({ kind: 'button', id: 202, label: "Open Account", left: sp+80, top: y + rh + sp, width: 100, height: rh});
|
||||
|
||||
let win = gui.createWindow({
|
||||
title: "New Account",
|
||||
width: sp+80+300+sp,
|
||||
height: y + rh+ sp+ rh + sp,
|
||||
left: 30,
|
||||
top: 30,
|
||||
gadgets: gadgets
|
||||
});
|
||||
|
||||
let indexOfNewAccount = -1;
|
||||
while (true) {
|
||||
var evt = gui.waitEvent(win);
|
||||
if (!evt) continue;
|
||||
|
||||
if (evt.type === 'close') {
|
||||
gui.closeWindow(win);
|
||||
return null;
|
||||
}
|
||||
if (evt.type === 'gadgetup') {
|
||||
if (evt.id === 202) {
|
||||
const newAccountName = gui.get(win, 201);
|
||||
|
||||
if (newAccountName.trim() != '') {
|
||||
data.push(
|
||||
{
|
||||
name: newAccountName,
|
||||
entries: []
|
||||
}
|
||||
)
|
||||
indexOfNewAccount = data.findIndex( p => p.name == newAccountName);
|
||||
console.log(indexOfNewAccount);
|
||||
gui.closeWindow(win);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return indexOfNewAccount;
|
||||
}
|
||||
|
||||
function subWindow(data) {
|
||||
let gadgets = [];
|
||||
let removable = false;
|
||||
|
||||
const subjectInputId = 401;
|
||||
const amountInputId = 402;
|
||||
const dateInputId = 403;
|
||||
const transferCheckboxId = 404;
|
||||
const transferAccountInputId = 405;
|
||||
const executeButtonId = 406;
|
||||
const deleteButtonId = 407;
|
||||
|
||||
const innerData = {
|
||||
date: Date.now(),
|
||||
subject: '',
|
||||
amount: 0,
|
||||
targetAccount: null
|
||||
}
|
||||
|
||||
if (data) {
|
||||
innerData.date = data.date;
|
||||
innerData.subject = data.subject;
|
||||
innerData.amount = data.amount;
|
||||
innerData.targetAccount = data.targetAccount;
|
||||
removable = true;
|
||||
}
|
||||
|
||||
let d = new Date(innerData.date);
|
||||
let formattedDate = (""+d.getDate()).padStart(2, "0") + "-" + (""+(d.getMonth() + 1)).padStart(2, "0") + "-" + d.getFullYear();
|
||||
|
||||
gadgets.push({
|
||||
kind: 'string', id: subjectInputId, label: 'Subject:',
|
||||
left: sp + 80, top: y, width: 400 - sp - 80 - sp, height: rh,
|
||||
value: innerData.subject
|
||||
});
|
||||
gadgets.push({
|
||||
kind: 'string', id: amountInputId, label: 'Amount:',
|
||||
left: sp + 80, top: sp + rh + sp, width: 100, height: rh,
|
||||
value: innerData.amount.toFixed(2)
|
||||
});
|
||||
gadgets.push({
|
||||
kind: 'string', id: dateInputId, label: 'Date:',
|
||||
left: sp + 80, top: sp + rh + sp + rh + sp, width: 150, height: rh,
|
||||
value: formattedDate
|
||||
});
|
||||
gadgets.push({ kind: 'checkbox', id: transferCheckboxId, label: "Account:", left: sp + 80, top: sp + rh + sp + rh + sp + rh + sp + 2, width: rh, height: rh, value: 0 });
|
||||
|
||||
const accounts = getAccounts(projectData);
|
||||
|
||||
gadgets.push({ kind: 'cycle', id: transferAccountInputId, left: sp + 160 + rh + sp, top: sp + rh + sp + rh + sp + rh + sp, width: 120, height: rh, items: accounts, value: 0 });
|
||||
|
||||
gadgets.push({ kind: 'button', id: executeButtonId, left: sp + 80, top: sp + rh + sp + rh + sp + rh + sp + rh + sp, width: 80, label: "Save", height: rh });
|
||||
gadgets.push({ kind: 'button', id: deleteButtonId, left: sp + 80 + sp + 80, top: sp + rh + sp + rh + sp + rh + sp + rh + sp, width: 80, label: "Remove", height: rh });
|
||||
|
||||
let win = gui.createWindow({
|
||||
title: 'Entry Details',
|
||||
width: 400,
|
||||
height: sp + rh + sp + rh + sp + rh + sp + rh + sp + rh + sp,
|
||||
left: 30,
|
||||
top: 30,
|
||||
gadgets: gadgets
|
||||
});
|
||||
|
||||
if (innerData.targetAccount) {
|
||||
gui.set(win, transferCheckboxId, 1);
|
||||
let i = -1;
|
||||
for (i = 0; i < accounts.length; i++) {
|
||||
if (accounts[i] === innerData.targetAccount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
gui.set(win, 7, i);
|
||||
gui.setDisabled(win, transferAccountInputId, false);
|
||||
} else {
|
||||
gui.setDisabled(win, transferAccountInputId, true);
|
||||
}
|
||||
|
||||
gui.setDisabled(win, deleteButtonId, !removable);
|
||||
|
||||
while (true) {
|
||||
var evt = gui.waitEvent(win);
|
||||
if (!evt) continue;
|
||||
|
||||
if (evt.type === 'close') {
|
||||
gui.closeWindow(win);
|
||||
return null;
|
||||
}
|
||||
if (evt.type === 'gadgetup') {
|
||||
if (evt.id === transferCheckboxId) {
|
||||
gui.setDisabled(win, transferAccountInputId, !gui.get(win, transferAccountInputId));
|
||||
}
|
||||
if (evt.id === executeButtonId) {
|
||||
innerData.subject = gui.get(win, subjectInputId);
|
||||
innerData.amount = parseFloat(gui.get(win, amountInputId));
|
||||
innerData.date = toDateByComponents(gui.get(win, dateInputId));
|
||||
|
||||
if (gui.get(win, transferCheckboxId)) {
|
||||
const targetAccountIndex = gui.get(win, transferAccountInputId);
|
||||
if (targetAccountIndex !== null && targetAccountIndex !== undefined) {
|
||||
innerData.targetAccount = data[targetAccountIndex].name;
|
||||
}
|
||||
}
|
||||
|
||||
gui.closeWindow(win);
|
||||
return innerData;
|
||||
}
|
||||
if (evt.id === deleteButtonId) {
|
||||
gui.closeWindow(win);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mainWindow(projectData) {
|
||||
|
||||
let internalProjectData = projectData;
|
||||
|
||||
let invalidate = false;
|
||||
|
|
@ -293,29 +31,42 @@ function mainWindow(projectData) {
|
|||
items: getAccounts(internalProjectData), value: 0
|
||||
});
|
||||
|
||||
gadgets.push({ kind: 'button', id: addButtonId, left: 500 - 80 - sp, top: y, width: 80, label: "+Transfer", height: rh });
|
||||
|
||||
gadgets.push({
|
||||
kind: 'listview', id: listViewId, left: sp, top: y + rh + sp, width: 500 - sp - sp, height: 186,
|
||||
flex: true,
|
||||
items: toListViewEntries(internalProjectData[0].entries, cols), value: 0
|
||||
kind: 'button', id: addButtonId,
|
||||
left: -(sp + 80),
|
||||
top: y,
|
||||
width: 80,
|
||||
label: "+Transfer",
|
||||
height: rh
|
||||
});
|
||||
|
||||
gadgets.push({
|
||||
kind: 'text', id: balanceId, label: 'Balance:',
|
||||
left: 100, top: y + rh + sp + 186, width: 400 - sp, height: rh,
|
||||
kind: 'listview', id: listViewId,
|
||||
left: sp,
|
||||
top: y + rh + sp,
|
||||
width: 500 - sp - sp,
|
||||
height: 186,
|
||||
items: toListViewEntries(internalProjectData[0].entries, cols),
|
||||
value: 0
|
||||
});
|
||||
|
||||
gadgets.push({
|
||||
kind: 'text', id: balanceId,
|
||||
label: 'Balance:',
|
||||
left: 100,
|
||||
top: -(sp + rh),
|
||||
width: 400 - sp,
|
||||
height: rh,
|
||||
value: getSummation(internalProjectData[0].entries).toFixed(2)
|
||||
});
|
||||
|
||||
|
||||
|
||||
let win = gui.createWindow({
|
||||
title: 'Budget',
|
||||
width: 500,
|
||||
height: 14 + 4 + 4 + 200 + 4,
|
||||
left: 20,
|
||||
top: 15,
|
||||
gadgets: gadgets
|
||||
gadgets: gadgets,
|
||||
});
|
||||
|
||||
/* Set up menu bar */
|
||||
|
|
@ -333,8 +84,15 @@ function mainWindow(projectData) {
|
|||
{
|
||||
title: 'Accounts',
|
||||
items: [
|
||||
{ label: "Add...", id:104, key: 'A'},
|
||||
{ label: "Close...", id:105, key: 'C'}
|
||||
{ label: "Add...", id: 104, key: 'A' },
|
||||
{ label: "Close...", id: 105, key: 'C' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Charts',
|
||||
items: [
|
||||
{ label: "---" },
|
||||
{ label: "New", id: 106 }
|
||||
]
|
||||
}
|
||||
]);
|
||||
|
|
@ -342,12 +100,14 @@ function mainWindow(projectData) {
|
|||
let currentAccountIndex = 0;
|
||||
|
||||
let updateView = (accountIndex, data) => {
|
||||
if (accountIndex!=null) {
|
||||
if (accountIndex != null) {
|
||||
gui.set(win, cycleId, getAccounts(data));
|
||||
gui.set(win, cycleId, accountIndex);
|
||||
}else {
|
||||
} else {
|
||||
accountIndex = gui.get(win, cycleId);
|
||||
}
|
||||
// sort
|
||||
data[accountIndex].entries = data[accountIndex].entries.sort((a, b) => a.date - b.date);
|
||||
gui.set(win, 2, toListViewEntries(data[accountIndex].entries, cols));
|
||||
gui.set(win, 3, getSummation(data[accountIndex].entries).toFixed(2));
|
||||
}
|
||||
|
|
@ -375,7 +135,7 @@ function mainWindow(projectData) {
|
|||
}
|
||||
}
|
||||
|
||||
gui.setMenuItem(win, 105, {disabled: internalProjectData.length<=1});
|
||||
gui.setMenuItem(win, 105, { disabled: internalProjectData.length <= 1 });
|
||||
|
||||
|
||||
while (!invalidate) {
|
||||
|
|
@ -400,7 +160,7 @@ function mainWindow(projectData) {
|
|||
doSave();
|
||||
}
|
||||
else if (evt.id === 104) {
|
||||
let indexOfNewAccount = addAccount(internalProjectData);
|
||||
let indexOfNewAccount = waitForAddAccountWindow(internalProjectData);
|
||||
if (indexOfNewAccount > -1) {
|
||||
currentAccountIndex = indexOfNewAccount;
|
||||
}
|
||||
|
|
@ -408,7 +168,7 @@ function mainWindow(projectData) {
|
|||
}
|
||||
else if (evt.id === 105) {
|
||||
if (internalProjectData.length > 1) {
|
||||
const rValue = closeAccount(internalProjectData, internalProjectData[currentAccountIndex]);
|
||||
const rValue = waitForCloseAccountWindow(internalProjectData, internalProjectData[currentAccountIndex]);
|
||||
if (rValue === -1) {
|
||||
internalProjectData.splice(currentAccountIndex, 1);
|
||||
updateView(0, internalProjectData);
|
||||
|
|
@ -416,7 +176,9 @@ function mainWindow(projectData) {
|
|||
} else {
|
||||
gui.alert("Cannot close last remaining Account");
|
||||
}
|
||||
|
||||
}
|
||||
else if (evt.id === 106) {
|
||||
waitForChartWindow(projectData[currentAccountIndex]);
|
||||
}
|
||||
else if (evt.id === 199) {
|
||||
invalidate = true;
|
||||
|
|
@ -430,12 +192,15 @@ function mainWindow(projectData) {
|
|||
currentAccountIndex = evt.code;
|
||||
updateView(null, internalProjectData);
|
||||
} else if (evt.id === listViewId) {
|
||||
const entry = subWindow(internalProjectData[currentAccountIndex].entries[evt.code]);
|
||||
let selectedEntry = evt.code;
|
||||
const entry = waitForDataEntryWindow(internalProjectData[currentAccountIndex].entries[evt.code], internalProjectData);
|
||||
if (entry != null) {
|
||||
console.log(entry);
|
||||
if (entry === -1) {
|
||||
internalProjectData[currentAccountIndex].entries.splice(evt.code, 1);
|
||||
console.log(selectedEntry);
|
||||
internalProjectData[currentAccountIndex].entries.splice(selectedEntry, 1);
|
||||
} else {
|
||||
internalProjectData[currentAccountIndex].entries[evt.code] = entry;
|
||||
internalProjectData[currentAccountIndex].entries[selectedEntry] = entry;
|
||||
}
|
||||
if (entry.targetAccount) {
|
||||
const targetAccount = internalProjectData.find(d => d.name === entry.targetAccount);
|
||||
|
|
@ -447,10 +212,11 @@ function mainWindow(projectData) {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
updateView(currentAccountIndex, internalProjectData);
|
||||
}
|
||||
} else if (evt.id === addButtonId) {
|
||||
const entry = subWindow();
|
||||
const entry = waitForDataEntryWindow(null, internalProjectData);
|
||||
if (entry != null) {
|
||||
internalProjectData[currentAccountIndex].entries.push(entry);
|
||||
|
||||
|
|
@ -475,45 +241,19 @@ function mainWindow(projectData) {
|
|||
}
|
||||
|
||||
|
||||
let projectData = [
|
||||
{
|
||||
name: "Current",
|
||||
entries: [
|
||||
{
|
||||
date: 1704067200000,
|
||||
subject: '(Savings) Initial Deposit',
|
||||
amount: -500,
|
||||
targetAccount: "Savings"
|
||||
let projectData = [
|
||||
{ "name": "Current", "entries": [
|
||||
{ "date": 1704067200000, "subject": "Salary", "amount": 2182.15000000000009 },
|
||||
{ "date": 1704153600000, "subject": "(Savings) Initial Deposit", "targetAccount": "Current", "amount": -500 },
|
||||
{ "date": 1704240000000, "subject": "Rent", "amount": -800 },
|
||||
{ "date": 1704326400000, "subject": "Groceries", "amount": -24.19 }]
|
||||
},
|
||||
{
|
||||
date: 1704067200000,
|
||||
subject: 'Salary',
|
||||
amount: 2182.15
|
||||
},
|
||||
{
|
||||
date: 1704153600000,
|
||||
subject: 'Rent',
|
||||
amount: -800
|
||||
},
|
||||
{
|
||||
date: 1704240000000,
|
||||
subject: 'Groceries',
|
||||
amount: -24.19
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Savings",
|
||||
entries: [
|
||||
{
|
||||
date: 1704067200000,
|
||||
subject: 'Initial Deposit',
|
||||
amount: 500
|
||||
}
|
||||
],
|
||||
{ "name": "Savings", "entries": [
|
||||
{ "date": 1704153600000, "subject": "Initial Deposit", "amount": 500 }]
|
||||
}
|
||||
];
|
||||
|
||||
];
|
||||
exports.projectData = projectData;
|
||||
|
||||
|
||||
mainWindow(projectData);
|
||||
48
project.json
48
project.json
|
|
@ -1,47 +1 @@
|
|||
[
|
||||
{
|
||||
"name": "Current",
|
||||
"entries": [
|
||||
{
|
||||
"date": 1704067200000,
|
||||
"subject": "(Savings) Initial Deposit",
|
||||
"targetAccount": "Savings",
|
||||
"amount": -500
|
||||
},
|
||||
{
|
||||
"date": 1704067200000,
|
||||
"subject": "Salary",
|
||||
"amount": 2182.15000000000009
|
||||
},
|
||||
{
|
||||
"date": 1704153600000,
|
||||
"subject": "Rent",
|
||||
"amount": -800
|
||||
},
|
||||
{
|
||||
"date": 1704240000000,
|
||||
"subject": "Groceries",
|
||||
"amount": -24.19
|
||||
},
|
||||
{
|
||||
"date": 1704240000000,
|
||||
"subject": "Toiletries",
|
||||
"amount": -12.95
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Savings",
|
||||
"entries": [
|
||||
{
|
||||
"date": 1704067200000,
|
||||
"subject": "Initial Deposit",
|
||||
"amount": 500
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Portfolio",
|
||||
"entries": []
|
||||
}
|
||||
]
|
||||
[{"name":"Current","entries":[{"date":1704067200000,"subject":"Salary","amount":2182.15000000000009},{"date":1704153600000,"subject":"(Savings) Initial Deposit","targetAccount":"Current","amount":-500},{"date":1704240000000,"subject":"Rent","amount":-800},{"date":1704326400000,"subject":"Groceries","amount":-24.19}]},{"name":"Savings","entries":[{"date":1704067200000,"subject":"Initial Deposit","amount":500}]}]
|
||||
|
|
@ -0,0 +1 @@
|
|||
----rwed 2026-05-10 20:58:03.64
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
var gui = require('gui');
|
||||
var gfx = gui.gfx;
|
||||
|
||||
var sp = 8;
|
||||
|
||||
// data
|
||||
const datapoints = [
|
||||
{ x: 0, v: 0 },
|
||||
{ x: 1, v: 100 },
|
||||
{ x: 2, v: -39 },
|
||||
{ x: 3, v: -24 },
|
||||
{ x: 4, v: 24 },
|
||||
{ x: 5, v: -12 },
|
||||
{ x: 6, v: 100 }
|
||||
];
|
||||
|
||||
// create window (initial size; drawing will use current window client area)
|
||||
let gadgets = [];
|
||||
let win = gui.createWindow({
|
||||
title: "Summary Chart",
|
||||
width: 400,
|
||||
height: 200,
|
||||
left: 30,
|
||||
top: 30,
|
||||
gadgets: gadgets
|
||||
});
|
||||
|
||||
// Compute cumulative series and min/max (include 0 to ensure Y=0 is visible)
|
||||
let cumulative = [];
|
||||
let cur = 0;
|
||||
cumulative.push({ x: datapoints[0].x, y: 0 }); // start at 0
|
||||
let lowest = 0;
|
||||
let highest = 0;
|
||||
|
||||
for (let i = 0; i < datapoints.length; ++i) {
|
||||
cur += datapoints[i].v;
|
||||
cumulative.push({ x: datapoints[i].x, y: cur });
|
||||
if (cur < lowest) lowest = cur;
|
||||
if (cur > highest) highest = cur;
|
||||
}
|
||||
if (0 < lowest) lowest = 0;
|
||||
if (0 > highest) highest = 0;
|
||||
|
||||
// Draw function using current window size
|
||||
function drawChart() {
|
||||
const totalW = Math.max(10, 400 - sp * 3);
|
||||
const totalH = Math.max(10, 200 - sp * 3);
|
||||
const left = sp;
|
||||
const top = sp;
|
||||
const right = left + totalW;
|
||||
const bottom = top + totalH;
|
||||
|
||||
// X and Y ranges
|
||||
const minX = cumulative[0].x;
|
||||
const maxX = cumulative[cumulative.length - 1].x;
|
||||
const xRange = (maxX === minX) ? 1 : (maxX - minX);
|
||||
let yRange = highest - lowest;
|
||||
if (yRange === 0) yRange = 1;
|
||||
|
||||
// mapping functions
|
||||
const mapX = x => left + ((x - minX) / xRange) * totalW;
|
||||
const mapY = y => bottom - ((y - lowest) / yRange) * totalH; // invert Y
|
||||
|
||||
// draw Y=0 axis
|
||||
const y0 = mapY(0);
|
||||
gfx.setColor(win, 1);
|
||||
gfx.drawLine(win, left, y0, right, y0);
|
||||
|
||||
gfx.setColor(win, 4);
|
||||
// draw polyline
|
||||
let last = cumulative[0];
|
||||
for (let i = 1; i < cumulative.length; ++i) {
|
||||
let p = cumulative[i];
|
||||
gfx.drawLine(win, mapX(last.x), mapY(last.y), mapX(p.x), mapY(p.y));
|
||||
last = p;
|
||||
}
|
||||
}
|
||||
|
||||
// initial draw
|
||||
drawChart();
|
||||
|
||||
while (true) {
|
||||
var evt = gui.waitEvent(win);
|
||||
if (!evt) continue;
|
||||
|
||||
if (evt.type === 'close') {
|
||||
gui.closeWindow(win);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("close");
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* Reduces the Data Structure to the account names.
|
||||
* @param {any[]} data
|
||||
* @returns
|
||||
*/
|
||||
function getAccounts(data) {
|
||||
const resultData = [];
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
resultData.push(data[i].name);
|
||||
}
|
||||
return resultData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sums up every entry and returns it.
|
||||
* @param {any[]} entries
|
||||
* @returns
|
||||
*/
|
||||
function getSummation(entries) {
|
||||
return entries.reduce((sum, e) => sum + parseFloat(e.amount), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the given String in dd-MM-yyyy into a Javascript Date Object
|
||||
* @param {string} s
|
||||
* @returns
|
||||
*/
|
||||
function toDateByComponents(s) {
|
||||
const parts = s.split("-");
|
||||
if (parts.length !== 3) return null;
|
||||
const day = parseInt(parts[0]);
|
||||
const month = parseInt(parts[1]) - 1;
|
||||
const year = parseInt(parts[2]);
|
||||
if (isNaN(day) || isNaN(month) || isNaN(year)) return null;
|
||||
return new Date(year, month, day).getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* formats the given date into a dd-MM-yyyy String
|
||||
* @param {Date} d
|
||||
* @returns
|
||||
*/
|
||||
function toStringDate(d) {
|
||||
console.log(d);
|
||||
return ("" + d.getDate()).padStart(2, "0") +
|
||||
"-" + ("" + (d.getMonth() + 1)).padStart(2, "0") +
|
||||
"-" + d.getFullYear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps each entry to a line in a ListView while adhering to the visible amount of char columns
|
||||
* @param {any[]} entries
|
||||
* @param {number} visibleCols
|
||||
* @returns
|
||||
*/
|
||||
function toListViewEntries(entries, visibleCols) {
|
||||
let cols = visibleCols;
|
||||
return entries.map(e => {
|
||||
const amount = parseFloat(e.amount);
|
||||
const subject = ("" + e.subject).substr(0, cols - 20).padEnd(cols - 20, ' ');
|
||||
const sum = ((amount >= 0 ? "+" : "") + amount.toFixed(2)).substr(0, 10).padStart(10, ' ');
|
||||
const d = new Date(e.date);
|
||||
const date = d.getDate().toString().padStart(2, '0') + "-" + (d.getMonth() + 1).toString().padStart(2, '0') + "-" + d.getFullYear();
|
||||
let s = (date.substr(0, 10)) + " " + subject + " " + sum;
|
||||
return s;
|
||||
});
|
||||
}
|
||||
|
||||
exports.getAccounts = getAccounts;
|
||||
exports.getSummation = getSummation;
|
||||
exports.toDateByComponents = toDateByComponents;
|
||||
exports.toListViewEntries = toListViewEntries;
|
||||
exports.toStringDate = toStringDate;
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
var gui = require('gui');
|
||||
|
||||
function waitForAddAccountWindow(data) {
|
||||
var rh = 14;
|
||||
var sp = 4;
|
||||
var y = sp;
|
||||
|
||||
let gadgets = [];
|
||||
|
||||
gadgets.push({
|
||||
kind: 'string', id: 201,
|
||||
label: "Name:",
|
||||
left: sp + 80,
|
||||
top: y,
|
||||
width: 300,
|
||||
height: rh
|
||||
});
|
||||
|
||||
gadgets.push({
|
||||
kind: 'button', id: 202,
|
||||
label: "Open Account",
|
||||
left: sp + 80,
|
||||
top: y + rh + sp,
|
||||
width: 100,
|
||||
height: rh
|
||||
});
|
||||
|
||||
let win = gui.createWindow({
|
||||
title: "New Account",
|
||||
width: sp + 80 + 300 + sp,
|
||||
height: y + rh + sp + rh + sp,
|
||||
left: 30,
|
||||
top: 30,
|
||||
gadgets: gadgets
|
||||
});
|
||||
|
||||
let indexOfNewAccount = -1;
|
||||
while (true) {
|
||||
var evt = gui.waitEvent(win);
|
||||
if (!evt) continue;
|
||||
|
||||
if (evt.type === 'close') {
|
||||
gui.closeWindow(win);
|
||||
return null;
|
||||
}
|
||||
if (evt.type === 'gadgetup') {
|
||||
if (evt.id === 202) {
|
||||
const newAccountName = gui.get(win, 201);
|
||||
|
||||
if (newAccountName.trim() != '') {
|
||||
data.push(
|
||||
{
|
||||
name: newAccountName,
|
||||
entries: []
|
||||
}
|
||||
);
|
||||
indexOfNewAccount = data.findIndex(p => p.name == newAccountName);
|
||||
gui.closeWindow(win);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return indexOfNewAccount;
|
||||
}
|
||||
exports.waitForAddAccountWindow = waitForAddAccountWindow;
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
var gui = require('gui');
|
||||
const { getSummation, toStringDate, toDateByComponents, getAccounts } = require('./utils');
|
||||
|
||||
function waitForPrefsChartWindow() {
|
||||
var rh = 14;
|
||||
var sp = 4;
|
||||
var y = sp;
|
||||
let gadgets = [];
|
||||
|
||||
gadgets.push({
|
||||
kind: "string",
|
||||
left: sp,
|
||||
width: 80,
|
||||
top: sp,
|
||||
height: rh,
|
||||
label: "from",
|
||||
value: "01-01-2026"
|
||||
});
|
||||
|
||||
gadgets.push({
|
||||
kind: "string",
|
||||
left: sp,
|
||||
width: 80,
|
||||
top: sp,
|
||||
height: rh,
|
||||
label: "to",
|
||||
value: toStringDate(new Date())
|
||||
});
|
||||
|
||||
let win = gui.createWindow({
|
||||
title: "Summary Chart Prefs",
|
||||
width: sp + 128 + sp,
|
||||
height: y + rh + sp + rh + sp,
|
||||
left: 30,
|
||||
top: 30,
|
||||
gadgets: gadgets
|
||||
});
|
||||
|
||||
while (true) {
|
||||
var evt = gui.waitEvent(win);
|
||||
if (!evt) continue;
|
||||
|
||||
if (evt.type === 'close') {
|
||||
gui.closeWindow(win);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef Account
|
||||
* @property {String} name;
|
||||
* @property {AccountEntry[]} entries;
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef AccountEntry
|
||||
* @property {Number} date
|
||||
* @property {String} subject;
|
||||
* @property {Number} amount;
|
||||
* @property {String?} targetAccount;
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef DataPoint
|
||||
* @property {Number} timestamp;
|
||||
* @property {Number} value;
|
||||
* @property {String} accountName;
|
||||
* @property {String} tooltip;
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} gui
|
||||
* @param {*} win
|
||||
* @param {Account[]} data
|
||||
* @param {*} rangeFrom
|
||||
* @param {*} rangeTo
|
||||
*/
|
||||
function renderChart(gui, win, data, /** @type {Date} */ rangeFrom, /** @type {Date} */ rangeTo) {
|
||||
var rh = 14;
|
||||
var sp = 4;
|
||||
var y = sp;
|
||||
|
||||
const gfx = gui.gfx;
|
||||
|
||||
let datapoints = [];
|
||||
for (let i = 0; i < data.entries.length;++i) {
|
||||
datapoints.push({
|
||||
x: data.entries[i].date,
|
||||
v: data.entries[i].amount
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Compute cumulative series and min/max (include 0 to ensure Y=0 is visible)
|
||||
let cumulative = [];
|
||||
let cur = 0;
|
||||
cumulative.push({ x: datapoints[0].x, y: 0 }); // start at 0
|
||||
let lowest = 0;
|
||||
let highest = 0;
|
||||
|
||||
for (let i = 0; i < datapoints.length; ++i) {
|
||||
cur += datapoints[i].v;
|
||||
cumulative.push({ x: datapoints[i].x, y: cur });
|
||||
if (cur < lowest) lowest = cur;
|
||||
if (cur > highest) highest = cur;
|
||||
}
|
||||
if (0 < lowest) lowest = 0;
|
||||
if (0 > highest) highest = 0;
|
||||
|
||||
const totalW = Math.max(10, 400 - sp * 3);
|
||||
const totalH = Math.max(10, 180 - sp * 3);
|
||||
const left = sp;
|
||||
const top = sp;
|
||||
const right = left + totalW;
|
||||
const bottom = top + totalH;
|
||||
|
||||
console.log(lowest, highest);
|
||||
|
||||
// X and Y ranges
|
||||
const minX = cumulative[0].x;
|
||||
const maxX = cumulative[cumulative.length - 1].x;
|
||||
const xRange = (maxX === minX) ? 1 : (maxX - minX);
|
||||
let yRange = highest - lowest;
|
||||
if (yRange === 0) yRange = 1;
|
||||
|
||||
// mapping functions
|
||||
const mapX = x => left + ((x - minX) / xRange) * totalW;
|
||||
const mapY = y => bottom - ((y - lowest) / yRange) * totalH; // invert Y
|
||||
|
||||
// draw Y=0 axis
|
||||
const y0 = mapY(0);
|
||||
gfx.setColor(win, 1);
|
||||
gfx.drawLine(win, left, y0, right, y0);
|
||||
|
||||
gfx.setColor(win, 4);
|
||||
// draw polyline
|
||||
let last = cumulative[0];
|
||||
for (let i = 1; i < cumulative.length; ++i) {
|
||||
let p = cumulative[i];
|
||||
gfx.drawLine(win, mapX(last.x), mapY(last.y), mapX(p.x), mapY(p.y));
|
||||
last = p;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function waitForChartWindow(data) {
|
||||
var rh = 14;
|
||||
var sp = 4;
|
||||
var y = sp;
|
||||
let gadgets = [];
|
||||
|
||||
let rangeTo = new Date(toDateByComponents("31-12-2024"));
|
||||
let rangeFrom = new Date(toDateByComponents("01-01-" + rangeTo.getFullYear()));
|
||||
|
||||
let win = gui.createWindow({
|
||||
title: "Summary Chart",
|
||||
width: sp + 400 + sp,
|
||||
height: y + 180 + sp,
|
||||
left: 30,
|
||||
top: 30,
|
||||
gadgets: gadgets,
|
||||
});
|
||||
|
||||
renderChart(gui, win, data, rangeFrom, rangeTo);
|
||||
|
||||
gui.setMenu(win, [
|
||||
{
|
||||
title: 'Chart',
|
||||
items: [
|
||||
{ label: 'Save', id: 401, key: 'S'},
|
||||
{ label: 'Close', id: 499, key: 'Q' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Prefs',
|
||||
items: [
|
||||
{ label: "Set Daterange", id: 404, key: 'D' },
|
||||
]
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
while (true) {
|
||||
var evt = gui.waitEvent(win);
|
||||
if (!evt) continue;
|
||||
|
||||
if (evt.type === 'menu') {
|
||||
|
||||
}
|
||||
|
||||
if (evt.type === 'close') {
|
||||
gui.closeWindow(win);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.waitForChartWindow = waitForChartWindow;
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
var gui = require('gui');
|
||||
const { getSummation } = require('./utils');
|
||||
|
||||
function waitForCloseAccountWindow(data, selectedAccount) {
|
||||
var rh = 14;
|
||||
var sp = 4;
|
||||
var y = sp;
|
||||
let gadgets = [];
|
||||
|
||||
const accountNameId = 301;
|
||||
const remainingId = 302;
|
||||
const transferCheckboxId = 303;
|
||||
const targetAccountId = 304;
|
||||
const executeButtonId = 305;
|
||||
|
||||
const openStanding = getSummation(selectedAccount.entries);
|
||||
|
||||
let accounts = [];
|
||||
|
||||
for (let i = 0; i < data.length; ++i) {
|
||||
if (data[i].name != selectedAccount.name) {
|
||||
accounts.push(data[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
gadgets.push({
|
||||
kind: 'text', id: accountNameId,
|
||||
label: "Account:",
|
||||
left: sp + 128,
|
||||
top: y,
|
||||
width: 200,
|
||||
height: rh,
|
||||
value: selectedAccount.name
|
||||
});
|
||||
|
||||
gadgets.push({
|
||||
kind: 'text', id: remainingId,
|
||||
label: "Remaining " + (openStanding > 0 ? "funds" : "debt"),
|
||||
left: sp + 128,
|
||||
top: y + rh + sp,
|
||||
width: 100,
|
||||
height: rh
|
||||
});
|
||||
|
||||
gadgets.push({
|
||||
kind: 'checkbox', id: transferCheckboxId,
|
||||
label: "Transfer to:",
|
||||
left: sp,
|
||||
top: y + rh + sp + rh + sp,
|
||||
height: rh,
|
||||
value: 0
|
||||
});
|
||||
|
||||
gadgets.push({
|
||||
kind: 'cycle', id: targetAccountId,
|
||||
left: sp + 128,
|
||||
top: y + rh + sp + rh + sp,
|
||||
width: 120,
|
||||
height: rh,
|
||||
items: accounts,
|
||||
value: 0
|
||||
});
|
||||
|
||||
gadgets.push({
|
||||
kind: 'button', id: executeButtonId,
|
||||
left: sp + 128,
|
||||
top: y + rh + sp + rh + sp + rh + sp,
|
||||
height: rh,
|
||||
width: 120,
|
||||
label: "Close Account"
|
||||
});
|
||||
|
||||
let win = gui.createWindow({
|
||||
title: "Close Account '" + selectedAccount.name + "'",
|
||||
width: sp + 128 + 240 + sp,
|
||||
height: y + rh + sp + rh + sp + rh + sp + rh + sp,
|
||||
left: 30,
|
||||
top: 30,
|
||||
gadgets: gadgets
|
||||
});
|
||||
|
||||
gui.setDisabled(win, targetAccountId, true);
|
||||
gui.set(win, remainingId, openStanding.toFixed(2));
|
||||
|
||||
while (true) {
|
||||
var evt = gui.waitEvent(win);
|
||||
if (!evt) continue;
|
||||
|
||||
if (evt.type === 'close') {
|
||||
gui.closeWindow(win);
|
||||
return null;
|
||||
}
|
||||
if (evt.type === 'gadgetup') {
|
||||
if (evt.id === transferCheckboxId) {
|
||||
gui.setDisabled(win, targetAccountId, !gui.get(win, transferCheckboxId));
|
||||
}
|
||||
if (evt.id === executeButtonId) {
|
||||
if (gui.get(win, transferCheckboxId)) {
|
||||
let otherAccount;
|
||||
let target = accounts[gui.get(win, targetAccountId)];
|
||||
for (let i = 0; data.length; ++i) {
|
||||
if (data[i].name === target) {
|
||||
otherAccount = data[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (otherAccount) {
|
||||
otherAccount.entries.push({
|
||||
date: Date.now(),
|
||||
subject: '(' + selectedAccount.name + ') Closing Statement',
|
||||
amount: -openStanding,
|
||||
targetAccount: null
|
||||
});
|
||||
}
|
||||
gui.closeWindow(win);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.waitForCloseAccountWindow = waitForCloseAccountWindow;
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
var gui = require('gui');
|
||||
const { getAccounts, toDateByComponents } = require('./utils');
|
||||
|
||||
function waitForDataEntryWindow(data, projectData) {
|
||||
var rh = 14;
|
||||
var sp = 4;
|
||||
var y = sp;
|
||||
let gadgets = [];
|
||||
let removable = false;
|
||||
|
||||
const subjectInputId = 401;
|
||||
const amountInputId = 402;
|
||||
const dateInputId = 403;
|
||||
const transferCheckboxId = 404;
|
||||
const transferAccountInputId = 405;
|
||||
const executeButtonId = 406;
|
||||
const deleteButtonId = 407;
|
||||
|
||||
const innerData = {
|
||||
date: Date.now(),
|
||||
subject: '',
|
||||
amount: 0,
|
||||
targetAccount: null
|
||||
};
|
||||
|
||||
if (data) {
|
||||
innerData.date = data.date;
|
||||
innerData.subject = data.subject;
|
||||
innerData.amount = data.amount;
|
||||
innerData.targetAccount = data.targetAccount;
|
||||
removable = true;
|
||||
}
|
||||
|
||||
let d = new Date(innerData.date);
|
||||
let formattedDate = ("" + d.getDate()).padStart(2, "0") + "-" + ("" + (d.getMonth() + 1)).padStart(2, "0") + "-" + d.getFullYear();
|
||||
|
||||
gadgets.push({
|
||||
kind: 'string', id: subjectInputId, label: 'Subject:',
|
||||
left: sp + 80, top: y, width: 400 - sp - 80 - sp, height: rh,
|
||||
value: innerData.subject
|
||||
});
|
||||
gadgets.push({
|
||||
kind: 'string', id: amountInputId, label: 'Amount:',
|
||||
left: sp + 80, top: sp + rh + sp, width: 100, height: rh,
|
||||
value: innerData.amount.toFixed(2)
|
||||
});
|
||||
gadgets.push({
|
||||
kind: 'string', id: dateInputId, label: 'Date:',
|
||||
left: sp + 80, top: sp + rh + sp + rh + sp, width: 150, height: rh,
|
||||
value: formattedDate
|
||||
});
|
||||
gadgets.push({ kind: 'checkbox', id: transferCheckboxId, label: "Account:", left: sp + 80, top: sp + rh + sp + rh + sp + rh + sp + 2, width: rh, height: rh, value: 0 });
|
||||
|
||||
const accounts = getAccounts(projectData);
|
||||
|
||||
gadgets.push({ kind: 'cycle', id: transferAccountInputId, left: sp + 160 + rh + sp, top: sp + rh + sp + rh + sp + rh + sp, width: 120, height: rh, items: accounts, value: 0 });
|
||||
|
||||
gadgets.push({ kind: 'button', id: executeButtonId, left: sp + 80, top: sp + rh + sp + rh + sp + rh + sp + rh + sp, width: 80, label: "Save", height: rh });
|
||||
gadgets.push({ kind: 'button', id: deleteButtonId, left: sp + 80 + sp + 80, top: sp + rh + sp + rh + sp + rh + sp + rh + sp, width: 80, label: "Remove", height: rh });
|
||||
|
||||
|
||||
let win = gui.createWindow({
|
||||
title: 'Entry Details',
|
||||
width: 400,
|
||||
height: sp + rh + sp + rh + sp + rh + sp + rh + sp + rh + sp,
|
||||
left: 30,
|
||||
top: 30,
|
||||
gadgets: gadgets
|
||||
});
|
||||
|
||||
if (innerData.targetAccount) {
|
||||
gui.set(win, transferCheckboxId, 1);
|
||||
let i = -1;
|
||||
for (i = 0; i < accounts.length; i++) {
|
||||
if (accounts[i] === innerData.targetAccount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
gui.set(win, 7, i);
|
||||
gui.setDisabled(win, transferAccountInputId, false);
|
||||
} else {
|
||||
gui.setDisabled(win, transferAccountInputId, true);
|
||||
}
|
||||
|
||||
gui.setDisabled(win, deleteButtonId, !removable);
|
||||
|
||||
|
||||
while (true) {
|
||||
var evt = gui.waitEvent(win);
|
||||
if (!evt) continue;
|
||||
|
||||
if (evt.type === 'close') {
|
||||
gui.closeWindow(win);
|
||||
return null;
|
||||
}
|
||||
if (evt.type === 'gadgetup') {
|
||||
if (evt.id === transferCheckboxId) {
|
||||
gui.setDisabled(win, transferAccountInputId, !gui.get(win, transferAccountInputId));
|
||||
}
|
||||
if (evt.id === executeButtonId) {
|
||||
innerData.subject = gui.get(win, subjectInputId);
|
||||
innerData.amount = parseFloat(gui.get(win, amountInputId));
|
||||
innerData.date = toDateByComponents(gui.get(win, dateInputId));
|
||||
|
||||
if (gui.get(win, transferCheckboxId)) {
|
||||
const targetAccountIndex = gui.get(win, transferAccountInputId);
|
||||
if (targetAccountIndex !== null && targetAccountIndex !== undefined) {
|
||||
innerData.targetAccount = projectData[targetAccountIndex].name;
|
||||
}
|
||||
}
|
||||
gui.closeWindow(win);
|
||||
return innerData;
|
||||
}
|
||||
if (evt.id === deleteButtonId) {
|
||||
gui.closeWindow(win);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.waitForDataEntryWindow = waitForDataEntryWindow;
|
||||
Loading…
Reference in New Issue