2023.12.21.10.05
This commit is contained in:
parent
cafc808395
commit
489b05886b
Binary file not shown.
7
src/controller/helper/getFirstLastDayOfMonth.ts
Normal file
7
src/controller/helper/getFirstLastDayOfMonth.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import moment from "moment";
|
||||||
|
|
||||||
|
export const getFirstLastDayOfMonth = (date: moment.Moment) => {
|
||||||
|
let startDate = moment(date).startOf('month');
|
||||||
|
let endDate = moment(date).endOf('month');
|
||||||
|
return { startDate, endDate }
|
||||||
|
}
|
1
src/controller/helper/index.ts
Normal file
1
src/controller/helper/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { getFirstLastDayOfMonth } from "./getFirstLastDayOfMonth";
|
@ -3,6 +3,7 @@ import { Sequelize, DataTypes, Model, Optional, Op, fn, col } from 'sequelize';
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { Transaction } from './Transaction'; // Assuming you have a Transaction model
|
import { Transaction } from './Transaction'; // Assuming you have a Transaction model
|
||||||
import { Account } from './Account';
|
import { Account } from './Account';
|
||||||
|
import { getFirstLastDayOfMonth } from '../helper';
|
||||||
|
|
||||||
interface MonthlyReportAttributes {
|
interface MonthlyReportAttributes {
|
||||||
MonthlyReportID: number;
|
MonthlyReportID: number;
|
||||||
@ -66,10 +67,9 @@ class MonthlyReport extends Model<MonthlyReportAttributes, MonthlyReportCreation
|
|||||||
moment.locale("de")
|
moment.locale("de")
|
||||||
|
|
||||||
|
|
||||||
let m = moment();
|
let m = moment().set({year:year,month:month-1,date:15});
|
||||||
m.set({year:year,month:month-1,day:15});
|
let { startDate, endDate } = getFirstLastDayOfMonth(m);
|
||||||
let startDate = moment(m).startOf('month');
|
|
||||||
let endDate = moment(m).endOf('month');
|
|
||||||
// Fetch transaction data and calculate total amount
|
// Fetch transaction data and calculate total amount
|
||||||
let transactions = null;
|
let transactions = null;
|
||||||
if(AccountID==null){
|
if(AccountID==null){
|
||||||
@ -93,7 +93,7 @@ class MonthlyReport extends Model<MonthlyReportAttributes, MonthlyReportCreation
|
|||||||
console.log(transactions)
|
console.log(transactions)
|
||||||
|
|
||||||
const totalAmount = transactions.reduce((total, transaction) => total + transaction.Amount, 0);
|
const totalAmount = transactions.reduce((total, transaction) => total + transaction.Amount, 0);
|
||||||
console.log(totalAmount)
|
console.log(totalAmount)
|
||||||
// Create a MonthlyReport entry with the generated data
|
// Create a MonthlyReport entry with the generated data
|
||||||
await MonthlyReport.create({
|
await MonthlyReport.create({
|
||||||
Month: month,
|
Month: month,
|
||||||
|
0
src/controller/router/reports.ts
Normal file
0
src/controller/router/reports.ts
Normal file
@ -3,6 +3,10 @@ import { Account, Category, Transaction } from "../models";
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { convertDateArray } from '../helper/dateConversion';
|
import { convertDateArray } from '../helper/dateConversion';
|
||||||
|
|
||||||
|
|
||||||
|
import { addTransaction, addTransfer, listTransactions } from './transactions/index';
|
||||||
|
import { Op } from 'sequelize';
|
||||||
|
|
||||||
export class TransactionRouter {
|
export class TransactionRouter {
|
||||||
static routes() {
|
static routes() {
|
||||||
let router = express.Router();
|
let router = express.Router();
|
||||||
@ -12,149 +16,96 @@ export class TransactionRouter {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
router.post('/addTransaction', async (req, res, next) => {
|
router.post('/addTransaction', addTransaction.POST)
|
||||||
console.log(req.body)
|
router.get('/addTransaction', addTransaction.GET)
|
||||||
|
|
||||||
|
|
||||||
|
router.post('/addTransfer', addTransfer.POST)
|
||||||
|
router.get('/addTransfer', addTransfer.GET)
|
||||||
|
|
||||||
|
router.get('/modifyTransfer', async (req, res) => {
|
||||||
|
|
||||||
try {
|
|
||||||
/*
|
|
||||||
if(
|
|
||||||
req.body.date == undefined
|
|
||||||
|| req.body.Type == undefined
|
|
||||||
|| req.body.CategoryID == undefined
|
|
||||||
|| req.body.AccountID == undefined
|
|
||||||
){throw "ERROR"}
|
|
||||||
*/
|
|
||||||
let date = moment(req.body.date).set({
|
|
||||||
hour: req.body.time.split(":")[0],
|
|
||||||
minute:req.body.time.split(":")[1]
|
|
||||||
})
|
|
||||||
console.log(date.toDate())
|
|
||||||
await Transaction.create({
|
|
||||||
Amount: req.body.amount,
|
|
||||||
Date: date.toDate(),
|
|
||||||
Type: req.body.type,
|
|
||||||
//@ts-ignore
|
|
||||||
UserID: 1, // Associate the transaction with the user
|
|
||||||
//@ts-ignore
|
|
||||||
CategoryID: req.body.category,
|
|
||||||
AccountID: req.body.account
|
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
res.redirect("/transactions");
|
|
||||||
//next();
|
|
||||||
})
|
|
||||||
router.post('/addTransfer', async (req, res, next) => {
|
|
||||||
console.log(req.body)
|
|
||||||
|
|
||||||
try {
|
|
||||||
/*
|
|
||||||
if(
|
|
||||||
req.body.date == undefined
|
|
||||||
|| req.body.Type == undefined
|
|
||||||
|| req.body.CategoryID == undefined
|
|
||||||
|| req.body.AccountID == undefined
|
|
||||||
){throw "ERROR"}
|
|
||||||
*/
|
|
||||||
let date = moment(req.body.date).set({
|
|
||||||
hour: req.body.time.split(":")[0],
|
|
||||||
minute:req.body.time.split(":")[1]
|
|
||||||
})
|
|
||||||
console.log(date.toDate())
|
|
||||||
await Transaction.transferAmountFromTo(1,req.body.fromAccount,req.body.toAccount,req.body.amount,req.body.categoryID)
|
|
||||||
await Transaction.create({
|
|
||||||
Amount: req.body.amount,
|
|
||||||
Date: date.toDate(),
|
|
||||||
Type: req.body.type,
|
|
||||||
//@ts-ignore
|
|
||||||
UserID: 1, // Associate the transaction with the user
|
|
||||||
//@ts-ignore
|
|
||||||
CategoryID: req.body.category,
|
|
||||||
AccountID: req.body.account
|
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
res.redirect("/transactions");
|
|
||||||
//next();
|
|
||||||
})
|
})
|
||||||
router.get('/addTransaction', async (req, res) => {
|
|
||||||
|
router.get('/acc/:acc/_/:year/:month',async(req,res,next)=>{
|
||||||
try {
|
try {
|
||||||
const transactions = await Transaction.findAll({
|
let m = moment();
|
||||||
include: Account
|
m.set({
|
||||||
|
year: parseInt(req.params.year),
|
||||||
|
month: parseInt(req.params.month) - 1,
|
||||||
|
date: 1
|
||||||
});
|
});
|
||||||
const categories = await Category.findAll({order:[["Name","ASC"]]});
|
await listTransactions.GET(req, res, next, {
|
||||||
const accounts = await Account.findAll({order:[["Name","ASC"]]});
|
date: m.toDate(),
|
||||||
//console.log(transactions)
|
|
||||||
res.render('transactions/formTransaction', { title: 'Transactions', transactions, categories, accounts });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).send('Internal Server Error');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
router.get('/addTransfer', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const transactions = await Transaction.findAll({
|
|
||||||
include: Account
|
|
||||||
});
|
|
||||||
const categories = await Category.findAll({order:[["Name","ASC"]]});
|
|
||||||
const accounts = await Account.findAll({order:[["Name","ASC"]]});
|
|
||||||
//console.log(transactions)
|
|
||||||
res.render('transactions/formTransfer', { title: 'Transactions', transactions, categories, accounts });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).send('Internal Server Error');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
router.get('/acc/:acc', async (req: Request, res: Response) => {
|
|
||||||
try {
|
|
||||||
const transactions = await Transaction.findAll({
|
|
||||||
include: [Account,Category],
|
|
||||||
where: {
|
where: {
|
||||||
AccountID: req.params.acc
|
AccountID: req.params.acc
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
let arr = convertDateArray(transactions);
|
|
||||||
res.render('transactions/listTransactions', { title: 'Transactions', transactions:arr, cssClass:"" });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).send('Internal Server Error');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
router.get('/cat/:cat', async (req: Request, res: Response) => {
|
|
||||||
try {
|
|
||||||
const transactions = await Transaction.findAll({
|
|
||||||
include: [Account, Category],
|
|
||||||
where: {
|
|
||||||
//@ts-ignore
|
|
||||||
CategoryID: req.params.cat
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let arr = convertDateArray(transactions);
|
|
||||||
res.render('transactions/listTransactions', { title: 'Transactions', transactions:arr, cssClass:"" });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).send('Internal Server Error');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
router.all('/', async (req, res) => {
|
|
||||||
try {
|
|
||||||
let transactions:any = await Transaction.findAll({
|
|
||||||
include: [Account,Category]
|
|
||||||
});
|
|
||||||
const categories = await Category.findAll({});
|
|
||||||
const accounts = await Account.findAll({});
|
|
||||||
let arr = convertDateArray(transactions);
|
|
||||||
console.log(transactions)
|
|
||||||
res.render('transactions/listTransactions', { title: 'Transactions', transactions: arr, categories, accounts, cssClass:"fullList" });
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
res.status(500).send('Internal Server Error');
|
res.status(500).send('Internal Server Error');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
router.get('/acc/:acc', async (req: Request, res: Response,next) => {
|
||||||
|
try {
|
||||||
|
await listTransactions.GET(req, res, next, {
|
||||||
|
where: {
|
||||||
|
AccountID: req.params.acc
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send('Internal Server Error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
router.get('/cat/:cat/_/:year/:month', async (req: Request, res: Response, next) => {
|
||||||
|
try {
|
||||||
|
let m = moment();
|
||||||
|
m.set({
|
||||||
|
year: parseInt(req.params.year),
|
||||||
|
month: parseInt(req.params.month) - 1,
|
||||||
|
date: 1
|
||||||
|
});
|
||||||
|
await listTransactions.GET(req, res, next, {
|
||||||
|
date: m.toDate(),
|
||||||
|
where: {
|
||||||
|
CategoryID: req.params.cat
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send('Internal Server Error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
router.get('/cat/:cat', async (req: Request, res: Response, next) => {
|
||||||
|
try {
|
||||||
|
await listTransactions.GET(req, res, next, {
|
||||||
|
where: {
|
||||||
|
CategoryID: req.params.cat
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send('Internal Server Error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
router.get('/_/:year/:month', async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
let m = moment();
|
||||||
|
m.set({
|
||||||
|
year: parseInt(req.params.year),
|
||||||
|
month: parseInt(req.params.month) - 1,
|
||||||
|
date: 1
|
||||||
|
});
|
||||||
|
await listTransactions.GET(req, res, next, { date: m.toDate() })
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send('Internal Server Error');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
router.get('/', listTransactions.GET)
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
src/controller/router/transactions/addTransaction.ts
Normal file
43
src/controller/router/transactions/addTransaction.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { Request, NextFunction, Response } from "express";
|
||||||
|
import moment from "moment";
|
||||||
|
import { Category, Transaction, Account } from "../../models";
|
||||||
|
|
||||||
|
const POST = async (req: Request, res: Response, next: NextFunction, data = {}) => {
|
||||||
|
try {
|
||||||
|
let date = moment(req.body.date).set({
|
||||||
|
hour: req.body.time.split(":")[0],
|
||||||
|
minute: req.body.time.split(":")[1]
|
||||||
|
})
|
||||||
|
console.log(date.toDate())
|
||||||
|
await Transaction.create({
|
||||||
|
Amount: req.body.amount,
|
||||||
|
Date: date.toDate(),
|
||||||
|
Type: req.body.type,
|
||||||
|
//@ts-ignore
|
||||||
|
UserID: 1, // Associate the transaction with the user
|
||||||
|
//@ts-ignore
|
||||||
|
CategoryID: req.body.category,
|
||||||
|
AccountID: req.body.account
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
res.redirect("/transactions");
|
||||||
|
}
|
||||||
|
|
||||||
|
const GET = async (req: Request, res: Response, next: NextFunction, data = {}) => {
|
||||||
|
try {
|
||||||
|
const transactions = await Transaction.findAll({
|
||||||
|
include: Account
|
||||||
|
});
|
||||||
|
const categories = await Category.findAll({order:[["Name","ASC"]]});
|
||||||
|
const accounts = await Account.findAll({order:[["Name","ASC"]]});
|
||||||
|
//console.log(transactions)
|
||||||
|
res.render('transactions/formTransaction', { title: 'Transactions', transactions, categories, accounts });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send('Internal Server Error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { POST, GET };
|
57
src/controller/router/transactions/addTransfer.ts
Normal file
57
src/controller/router/transactions/addTransfer.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { Request, NextFunction, Response } from "express";
|
||||||
|
import moment from "moment";
|
||||||
|
import { Category, Transaction, Account } from "../../models";
|
||||||
|
|
||||||
|
const POST = async (req: Request, res: Response, next: NextFunction, data = {}) => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
/*
|
||||||
|
if(
|
||||||
|
req.body.date == undefined
|
||||||
|
|| req.body.Type == undefined
|
||||||
|
|| req.body.CategoryID == undefined
|
||||||
|
|| req.body.AccountID == undefined
|
||||||
|
){throw "ERROR"}
|
||||||
|
*/
|
||||||
|
let date = moment(req.body.date).set({
|
||||||
|
hour: req.body.time.split(":")[0],
|
||||||
|
minute: req.body.time.split(":")[1]
|
||||||
|
})
|
||||||
|
console.log(date.toDate())
|
||||||
|
await Transaction.transferAmountFromTo(1, req.body.fromAccount, req.body.toAccount, req.body.amount, req.body.categoryID)
|
||||||
|
await Transaction.create({
|
||||||
|
Amount: req.body.amount,
|
||||||
|
Date: date.toDate(),
|
||||||
|
Type: req.body.type,
|
||||||
|
//@ts-ignore
|
||||||
|
UserID: 1, // Associate the transaction with the user
|
||||||
|
//@ts-ignore
|
||||||
|
CategoryID: req.body.category,
|
||||||
|
AccountID: req.body.account
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
res.redirect("/transactions");
|
||||||
|
}
|
||||||
|
|
||||||
|
const GET = async (req: Request, res: Response, next: NextFunction, data = {}) => {
|
||||||
|
try {
|
||||||
|
const transactions = await Transaction.findAll({
|
||||||
|
include: Account
|
||||||
|
});
|
||||||
|
const categories = await Category.findAll({
|
||||||
|
order: [["Name", "ASC"]]
|
||||||
|
});
|
||||||
|
const accounts = await Account.findAll({
|
||||||
|
order: [["Name", "ASC"]]
|
||||||
|
});
|
||||||
|
|
||||||
|
res.render('transactions/formTransfer', { title: 'Transactions', transactions, categories, accounts });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send('Internal Server Error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { POST, GET };
|
5
src/controller/router/transactions/index.ts
Normal file
5
src/controller/router/transactions/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import addTransaction from "./addTransaction";
|
||||||
|
import addTransfer from "./addTransfer";
|
||||||
|
import listTransactions from "./listTransactions";
|
||||||
|
|
||||||
|
export { addTransaction, addTransfer, listTransactions }
|
34
src/controller/router/transactions/listTransactions.ts
Normal file
34
src/controller/router/transactions/listTransactions.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { Request, NextFunction, Response } from "express";
|
||||||
|
import moment from "moment";
|
||||||
|
import { Op } from "sequelize";
|
||||||
|
|
||||||
|
import { Category, Transaction, Account } from "../../models";
|
||||||
|
import { convertDateArray } from "../../helper/dateConversion";
|
||||||
|
import { getFirstLastDayOfMonth } from "../../helper";
|
||||||
|
|
||||||
|
const GET = async (req: Request, res: Response, next: NextFunction, data:any = {date:new Date(),where:{}}) => {
|
||||||
|
try {
|
||||||
|
moment.locale("de")
|
||||||
|
let m = moment(data.date);
|
||||||
|
let { startDate, endDate } = getFirstLastDayOfMonth(m);
|
||||||
|
let transactions:any = await Transaction.findAll({
|
||||||
|
include: [Account,Category],
|
||||||
|
where:{
|
||||||
|
Date:{
|
||||||
|
[Op.between]:[startDate.toDate(),endDate.toDate()]
|
||||||
|
},
|
||||||
|
...data.where
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const categories = await Category.findAll({});
|
||||||
|
const accounts = await Account.findAll({});
|
||||||
|
let arr = convertDateArray(transactions);
|
||||||
|
|
||||||
|
res.render('transactions/listTransactions', { title: 'Transactions', transactions: arr, categories, accounts, cssClass:"fullList" });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send('Internal Server Error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { GET };
|
@ -1,10 +1,14 @@
|
|||||||
doctype html
|
extends layout/base.pug
|
||||||
html
|
|
||||||
head
|
block nav
|
||||||
title= title
|
a(href="/transactions") Transactions
|
||||||
body
|
a(href="/transactions/addTransaction") + Transaction
|
||||||
h1 Welcome to our Web App!
|
a(href="/transactions/addTransfer") + Transfer
|
||||||
p This is a simple example using Express and Pug.
|
|
||||||
|
block headline
|
||||||
|
h1 Home
|
||||||
|
|
||||||
|
block content
|
||||||
a(href='/users') View Users
|
a(href='/users') View Users
|
||||||
|
|
||||||
div
|
div
|
||||||
|
39
views/transactions/modifyTransaction.pug
Normal file
39
views/transactions/modifyTransaction.pug
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
extends ./transactions.pug
|
||||||
|
block content
|
||||||
|
form(action="/transactions/addTransaction",method="POST")
|
||||||
|
div.form-group
|
||||||
|
.text Description
|
||||||
|
.input
|
||||||
|
textarea(name="description", cols="30", rows="5")
|
||||||
|
div.form-group.half
|
||||||
|
.text Date
|
||||||
|
.input
|
||||||
|
input(type="date",name="date")
|
||||||
|
div.form-group.half
|
||||||
|
.text Time
|
||||||
|
.input
|
||||||
|
input(type="time",name="time")
|
||||||
|
div.form-group.half
|
||||||
|
.text Type
|
||||||
|
.input
|
||||||
|
select(name="type")
|
||||||
|
option(value="income") Income
|
||||||
|
option(value="expense",select) Expense
|
||||||
|
option(value="transfer") Transfer
|
||||||
|
div.form-group.half
|
||||||
|
.text Account
|
||||||
|
.input
|
||||||
|
select(name="account")
|
||||||
|
each account in accounts
|
||||||
|
option(value=account.AccountID)=account.Name
|
||||||
|
div.form-group.half
|
||||||
|
.text Amount
|
||||||
|
.input
|
||||||
|
input(type="number",min="0",step="0.01",name="amount",required)
|
||||||
|
div.form-group.half
|
||||||
|
.text Category
|
||||||
|
.input
|
||||||
|
select(name="category")
|
||||||
|
each category in categories
|
||||||
|
option(value=category.CategoryID,title=category.Description)=category.Name
|
||||||
|
button(type="submit") Modify Transaction
|
Loading…
Reference in New Issue
Block a user