127.0.0.1:8000 budget / master src / js / pages / transactions_and_credit_cards.js
master

Tree @master (Download .tar.gz)

transactions_and_credit_cards.js @masterraw · history · blame

const api = require('../utils/api');
const utils = require('../utils');
const chart = require('./chart_and_messages');
const list_row = require('../ui/list_row');
const ui = require('../ui/common');
const $ = require('jquery');
const modal = require('../utils/modal');

const one_hour = 3600000; // 1000 * 60 * 60
// Idk maybe I'll leave the page open for days at a time
// TODO: use same time logic as in service time util for daily actions
utils.setIntervalAndTriggerImmediate(function() {
    const today = new Date();
    let month = today.getMonth() + 1;
    let day = today.getDate();
    let year = today.getFullYear();
    if (month < 10)
        month = '0' + month;
    if (day < 10)
        day = '0' + day;
    $("#transaction-date").attr('max', year + '-' + month + '-' + day);
    $("#transaction-date").val(year + '-' + month + '-' + day);
}, one_hour);

api.on_submit("/budget/transaction", [
    $("#create-transaction"), $("#edit-transaction")
], {
    value: x => -Math.abs(utils.round(parseFloat(x), 2))
}, [
    ["value", "Money spent must be provided"], // value=0 will be accounted for here
    ["value", "Money spent must be a number", value => !isNaN(value)],
    ["credit_card", "Invalid Credit Card", credit_card => cached_credit_cards[credit_card]],
    ["date", "Transaction Date must be provided"],
    ["date", "Transaction Date must be in YYYY-MM-DD format", utils.validate.iso_date]
], async function() {
    modal.close();
    await chart.refresh();
    await populate_transaction_history_table();
});

$("#delete-transaction").on("click", async function() {
    const id = $("#edit-transaction").find('[name="id"]').val();
    await api.delete('/budget/transaction/' + id);
    ui.show_banner({
        message: `Transaction ${id} deleted`
    });
    modal.close();
    await chart.refresh();
    await populate_transaction_history_table();
});

api.on_submit("/budget/credit-card", [
    $("#create-credit-card"), $("#edit-credit-card")
], {
    billing_date: x => parseInt(x),
    statement_date: x => parseInt(x)
}, [
    ["name", "Credit Card must have a name"],
    ["billing_date", "Invalid billing date", utils.validate.date],
    ["statement_date", "Invalid statement date", utils.validate.date]
], async function() {
    modal.create();
    await chart.refresh();
    await get_credit_cards();
    await populate_transaction_history_table();
});

$("#delete-credit-card").on("click", async function() {
    const id = $("#edit-credit-card").find('[name="id"]').val();
    await api.delete('/budget/credit-card/' + id);
    ui.show_banner({
        message: `Credit Card ${id} deleted`
    });
    modal.close();
    await chart.refresh();
    await get_credit_cards();
    await populate_transaction_history_table();
});

const billing_date_fields = ui.get_inputs(["#create-credit-card", "#edit-credit-card"], "billing_date");
const statement_date_fields = ui.get_inputs(["#create-credit-card", "#edit-credit-card"], "statement_date");
billing_date_fields.forEach(function($billing_date_field) {
    ui.generate_date_options($billing_date_field);
});
statement_date_fields.forEach(function($statement_date_field) {
    ui.generate_date_options($statement_date_field);
});

let cached_credit_cards = {};

get_credit_cards().then(populate_transaction_history_table);

async function get_credit_cards() {
    $("#credit-cards-list").empty();

    const {
        credit_cards
    } = await api.get('/budget/credit_cards');

    const credit_card_fields = ui.get_inputs(
        ["#create-transaction", "#edit-transaction"],
        "credit_card"
    );

    for (const credit_card of credit_cards) {
        cached_credit_cards[credit_card.id] = {
            name: credit_card.name,
            date: credit_card.date
        };
        let text = `monthly on the ${utils.format_date(credit_card.billing_date)}`;
        list_row.create("credit-cards", {
            title: `${credit_card.name}:`,
            text
        }, function() {
            ui.prefill_inputs("#edit-credit-card", credit_card);
            modal.create('edit-credit-card-modal');
        });

        credit_card_fields.map(function($input) {
            $input.append($('<option>', {
                value: credit_card.id,
                text: credit_card.name
            }));
        })
    }

    credit_card_fields.map(function($input) {
        $input.append($('<option>', {
            value: 0,
            text: "Other"
        }));
    });
}

async function populate_transaction_history_table() {
    $("#transactions-list").empty();

    const {
        transactions
    } = await api.get("/budget/transactions");
    for (const transaction of transactions) {
        const action = transaction.value > 0 ? "credited" : "charged";
        let text = `$${Math.abs(transaction.value)} ${action}`
        if (transaction.credit_card) {
            text += ` to ${cached_credit_cards[transaction.credit_card].name}`
        }
        text += ` on ${transaction.date}`;
        if (transaction.description) {
            text += ` (${transaction.description})`;
        }
        list_row.create("transactions", {
            text
        }, function() {
            ui.prefill_inputs("#edit-transaction", transaction);
            modal.create('edit-transaction-modal');
        });
    }
}