Added transactions and Accounts
This commit is contained in:
parent
bd35017f4a
commit
744bfa8114
33
.vscode/launch.json
vendored
Normal file
33
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": ".NET Core Launch (web)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/active-allocator/bin/Debug/net7.0/linux-x64/active-allocator.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/active-allocator",
|
||||
"stopAtEntry": false,
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||
},
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/Views": "${workspaceFolder}/Views"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach"
|
||||
}
|
||||
]
|
||||
}
|
76
.vscode/tasks.json
vendored
Normal file
76
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "dotnet build",
|
||||
"command": "dotnet",
|
||||
"type": "shell",
|
||||
"args": [
|
||||
"build",
|
||||
// Ask dotnet build to generate full paths for file names.
|
||||
"/property:GenerateFullPaths=true",
|
||||
// Do not generate summary otherwise it leads to duplicate errors in Problems panel
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
},
|
||||
"problemMatcher": "$msCompile",
|
||||
"options": {
|
||||
"cwd": "./active-allocator"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "build",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/active-allocator/active-allocator.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "publish",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"publish",
|
||||
"${workspaceFolder}/active-allocator/active-allocator.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "watch",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"watch",
|
||||
"run",
|
||||
"${workspaceFolder}/active-allocator/active-allocator.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "run",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"run",
|
||||
"${workspaceFolder}/active-allocator/active-allocator.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
22
.vscode/~launch.json
vendored
Normal file
22
.vscode/~launch.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": ".NET Core Attach (console)",
|
||||
"preLaunchTask": "dotnet build",
|
||||
"type": "coreclr",
|
||||
"processId": "${command:pickProcess}",
|
||||
"request": "attach",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceFolder}/active-allocator",
|
||||
"pipeProgram": "bash",
|
||||
"pipeArgs": ["-c"],
|
||||
"debuggerPath": "/home/william/.vscode-oss/extensions/muhammad-sammy.csharp-1.25.0/.debugger/netcoredbg/netcoredbg",
|
||||
"quoteArgs": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
8
ActiveAllocator.code-workspace
Normal file
8
ActiveAllocator.code-workspace
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
@ -1,7 +1,11 @@
|
||||
import { Counter } from "./components/Counter";
|
||||
import { FetchData } from "./components/FetchData";
|
||||
import { Home } from "./components/Home";
|
||||
import Login from "./components/auth/Login";
|
||||
import CreateAccount from "./components/accounts/CreateAccount";
|
||||
import DeleteAccount from "./components/accounts/DeleteAccount";
|
||||
import UpdateAccount from "./components/accounts/UpdateAccount";
|
||||
import Accounts from "./components/accounts/Accounts";
|
||||
import { Login } from "./components/auth/Login";
|
||||
import { Logout } from "./components/auth/Logout";
|
||||
import Register from "./components/auth/Register";
|
||||
import CreateUser from "./components/users/CreateUser";
|
||||
@ -54,6 +58,22 @@ const AppRoutes = [
|
||||
path: '/admin/user/delete',
|
||||
element: <DeleteUser />
|
||||
},
|
||||
{
|
||||
path: '/admin/accounts',
|
||||
element: <Accounts />
|
||||
},
|
||||
{
|
||||
path: '/admin/account/create',
|
||||
element: <CreateAccount />
|
||||
},
|
||||
{
|
||||
path: '/admin/account/edit',
|
||||
element: <UpdateAccount />
|
||||
},
|
||||
{
|
||||
path: '/admin/account/delete',
|
||||
element: <DeleteAccount />
|
||||
},
|
||||
];
|
||||
|
||||
export default AppRoutes;
|
||||
|
@ -48,6 +48,9 @@ export class NavMenu extends Component {
|
||||
<NavItem>
|
||||
<NavLink tag={Link} className="text-dark" to="/admin/users">Users</NavLink>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink tag={Link} className="text-dark" to="/admin/accounts">Accounts</NavLink>
|
||||
</NavItem>
|
||||
{/*<NavItem>
|
||||
<NavLink tag={Link} className="text-dark" to="/login">{sessionStorage.getItem('firstName')}</NavLink>
|
||||
</NavItem>*/}
|
||||
|
@ -0,0 +1,94 @@
|
||||
import { getData } from "../services/AccessAPI";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function Accounts() {
|
||||
useEffect(() => {
|
||||
getAllAccountsData();
|
||||
}, [])
|
||||
|
||||
let navigate = useNavigate();
|
||||
|
||||
const [state, setState] = useState({
|
||||
accounts: [],
|
||||
loading: false
|
||||
});
|
||||
|
||||
function onAccountCreate() {
|
||||
navigate('/admin/account/create');
|
||||
}
|
||||
|
||||
function onAccountEdit(id){
|
||||
let path = "/admin/account/edit"
|
||||
let query = "?id=" + id
|
||||
navigate(path + query);
|
||||
}
|
||||
|
||||
function onAccountDelete(id){
|
||||
let path = "/admin/account/delete"
|
||||
let query = "?id=" + id
|
||||
navigate(path + query);
|
||||
}
|
||||
|
||||
function getAllAccountsData() {
|
||||
getData('Accounts/').then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
console.log(result);
|
||||
setState({
|
||||
accounts: result,
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function renderAllAccountsTable(accounts) {
|
||||
return (
|
||||
<table className="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Owner</th>
|
||||
<th>Balance</th>
|
||||
<th>External Account Number</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
accounts.map(account => (
|
||||
<tr key={account.id}>
|
||||
<td>{account.name}</td>
|
||||
<td>{account.owner}</td>
|
||||
<td>{account.balance}</td>
|
||||
<td>{account.externalAccountNumber}</td>
|
||||
<td><button onClick={() => onAccountEdit(account.id)} className="btn btn-success">Edit</button> ||
|
||||
<button onClick={() => onAccountDelete(account.id)} className="btn btn-danger">Delete</button></td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
let content = state.loading ? (
|
||||
<p>
|
||||
<em>Loading...</em>
|
||||
</p>
|
||||
) : (
|
||||
renderAllAccountsTable(state.accounts)
|
||||
)
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3>List of Accounts</h3>
|
||||
<button onClick={() => onAccountCreate()} className="btn btn-primary">Create new account</button>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
import SessionManager from "../auth/SessionManager";
|
||||
import { postData } from "../services/AccessAPI";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function CreateAccount() {
|
||||
let navigate = useNavigate();
|
||||
|
||||
const [firstName, setFirstName] = useState("");
|
||||
const [lastName, setLastName] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [accountname, setAccountname] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmationPassword, setConfirmationPassword] = useState("");
|
||||
const [role, setRole] = useState("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
function onSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (password !== confirmationPassword) {
|
||||
alert("Password and confirm password are not same");
|
||||
return;
|
||||
}
|
||||
|
||||
let accountObj = {
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
email: email,
|
||||
accountname: accountname,
|
||||
password: password,
|
||||
role: role,
|
||||
}
|
||||
|
||||
postData('Accounts/register', accountObj).then((result) => {
|
||||
setLoading(false);
|
||||
let responseJson = result;
|
||||
if (responseJson) {
|
||||
navigate('/admin/accounts');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onClickBack(e){
|
||||
e.preventDefault();
|
||||
|
||||
if(SessionManager.getToken()){
|
||||
navigate('/admin/accounts');
|
||||
}else{
|
||||
navigate('/login');
|
||||
}
|
||||
}
|
||||
|
||||
/*function onChange(e) {
|
||||
//setState({ [e.target.name]: e.target.value });
|
||||
}*/
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-md-4">
|
||||
<h3>Create new account</h3>
|
||||
<form onSubmit={onSubmit}>
|
||||
<div className="form-group">
|
||||
<label className="control-label">First Name: </label>
|
||||
<input className="form-control" type="text" name="firstName" value={firstName} onChange={(e) => setFirstName(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Last Name: </label>
|
||||
<input className="form-control" type="text" name="lastName" value={lastName} onChange={(e) => setLastName(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Email: </label>
|
||||
<input className="form-control" type="text" name="email" value={email} onChange={(e) => setEmail(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Account Name: </label>
|
||||
<input className="form-control" type="text" name="accountname" value={accountname} onChange={(e) => setAccountname(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Role: </label>
|
||||
<input className="form-control" type="text" name="roles" value={role} onChange={(e) => setRole(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Password: </label>
|
||||
<input className="form-control" type="password" name="password" value={password} onChange={(e) => setPassword(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Confirm Password: </label>
|
||||
<input className="form-control" type="password" name="confirmationPassword" value={confirmationPassword} onChange={(e) => setConfirmationPassword(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<input type="submit" value="Create Account" className="btn btn-primary"></input>
|
||||
<input type="button" value="Back" onClick={onClickBack} className="btn btn-primary"></input>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { deleteData, getData } from "../services/AccessAPI";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
export default function DeleteAccount() {
|
||||
const search = useLocation().search;
|
||||
const id = new URLSearchParams(search).get('id')
|
||||
|
||||
useEffect(() => {
|
||||
//const { id } = this.props.match.params;
|
||||
|
||||
getData('Accounts/' + id).then(
|
||||
(result) => {
|
||||
console.log("Role for edit: ");
|
||||
console.log(result);
|
||||
if (result) {
|
||||
setState({
|
||||
firstName: result.firstName,
|
||||
lastName: result.lastName,
|
||||
accountname: result.accountname,
|
||||
email: result.email,
|
||||
roles: result.roles,
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}, [id])
|
||||
|
||||
let navigate = useNavigate();
|
||||
|
||||
const [state, setState] = useState({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
accountname: '',
|
||||
email: '',
|
||||
roles: [],
|
||||
loading: true
|
||||
});
|
||||
|
||||
function onCancel() {
|
||||
navigate('/admin/accounts');
|
||||
}
|
||||
|
||||
function onConfirmation(e) {
|
||||
e.preventDefault();
|
||||
|
||||
deleteData('Accounts/' + id).then((result) => {
|
||||
let responseJson = result;
|
||||
if (responseJson) {
|
||||
navigate('/admin/accounts');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>::Delete account::</h2>
|
||||
<h3>Are you sure you want to delete this?</h3>
|
||||
<div>
|
||||
<h4>Account Information</h4>
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
First Name:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
{state.firstName}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Last Name:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
{state.lastName}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Account Name:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
{state.accountname}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Email:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
{state.email}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<form onSubmit={onConfirmation}>
|
||||
<input type="hidden" asp-for="Id" />
|
||||
<button type="submit" className="btn btn-danger">Delete</button> |
|
||||
<button onClick={onCancel} className="btn btn-primary">Back to List</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
import { getData, putData } from "../services/AccessAPI";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function UpdateAccount() {
|
||||
let navigate = useNavigate();
|
||||
const search = useLocation().search;
|
||||
const id = new URLSearchParams(search).get('id')
|
||||
|
||||
const [firstName, setFirstName] = useState("");
|
||||
const [lastName, setLastName] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [accountname, setAccountname] = useState("");
|
||||
const [role, setRole] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
//const id = location.pathName.slice(location.pathName.lastIndexOf("/") , location.pathName.length);
|
||||
getData('Accounts/' + id).then(
|
||||
(result) => {
|
||||
//let responseJson = result;
|
||||
console.log("account for edit: ");
|
||||
console.log(result);
|
||||
console.log("Accountname: " + result.accountname)
|
||||
if (result) {
|
||||
setFirstName(result.firstName);
|
||||
setLastName(result.lastName);
|
||||
setEmail(result.email);
|
||||
setAccountname(result.accountname);
|
||||
setRole(result.roles);
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
}, [id])
|
||||
|
||||
function onKeyDown(e) {
|
||||
if (e.key === 'Enter') {
|
||||
this.update(false);
|
||||
}
|
||||
}
|
||||
|
||||
function onUpdateCancel() {
|
||||
navigate('/admin/accounts');
|
||||
}
|
||||
|
||||
function onSubmit(e){
|
||||
e.preventDefault();
|
||||
|
||||
//const id = location.pathName.slice(location.pathName.lastIndexOf("/") , location.pathName.length);
|
||||
|
||||
let accountProfile = {
|
||||
id: id,
|
||||
Accountname: accountname,
|
||||
FirstName: firstName,
|
||||
LastName: lastName,
|
||||
Email: email,
|
||||
}
|
||||
|
||||
putData('Accounts/' + id, accountProfile).then((result) => {
|
||||
console.log("Put Request body: ");
|
||||
console.log(accountProfile);
|
||||
|
||||
let responseJson = result;
|
||||
console.log("update response: ");
|
||||
|
||||
if(responseJson){
|
||||
console.log(responseJson);
|
||||
navigate('/admin/accounts');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="row">
|
||||
<div className="col-md-4">
|
||||
<h3>Edit Account</h3>
|
||||
<form onSubmit={onSubmit}>
|
||||
<div className="form-group">
|
||||
<label className="control-label">First Name: </label>
|
||||
<input className="form-control" type="text" value={firstName} onChange={(e) => setFirstName(e.target.value)} name="firstName"
|
||||
onKeyDown={onKeyDown} ></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Last Name: </label>
|
||||
<input className="form-control" type="text" value={lastName} onChange={(e) => setLastName(e.target.value)} name="lastName"
|
||||
onKeyDown={onKeyDown} ></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Account Name: </label>
|
||||
<input className="form-control" type="text" value={accountname} onChange={(e) => setAccountname(e.target.value)} name="accountname"
|
||||
onKeyDown={onKeyDown} ></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Email: </label>
|
||||
<input className="form-control" type="text" value={email} onChange={(e) => setEmail(e.target.value)} name="email"
|
||||
onKeyDown={onKeyDown}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<button onClick={onUpdateCancel} className="btn btn-default">Cancel</button>
|
||||
<input type="submit" value="Edit" className="btn btn-primary"></input>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -2,10 +2,14 @@ import { useNavigate } from "react-router-dom";
|
||||
import { deleteData, getData } from "../services/AccessAPI";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
export default function DeleteUser() {
|
||||
const search = useLocation().search;
|
||||
const id = new URLSearchParams(search).get('id')
|
||||
|
||||
useEffect(() => {
|
||||
const { id } = this.props.match.params;
|
||||
//const { id } = this.props.match.params;
|
||||
|
||||
getData('Users/' + id).then(
|
||||
(result) => {
|
||||
@ -23,7 +27,7 @@ export default function DeleteUser() {
|
||||
}
|
||||
}
|
||||
);
|
||||
}, [])
|
||||
}, [id])
|
||||
|
||||
let navigate = useNavigate();
|
||||
|
||||
@ -43,9 +47,7 @@ export default function DeleteUser() {
|
||||
function onConfirmation(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const { id } = this.props.match.params;
|
||||
|
||||
deleteData('/Users/' + id).then((result) => {
|
||||
deleteData('Users/' + id).then((result) => {
|
||||
let responseJson = result;
|
||||
if (responseJson) {
|
||||
navigate('/admin/users');
|
||||
@ -61,45 +63,45 @@ export default function DeleteUser() {
|
||||
<h3>Are you sure you want to delete this?</h3>
|
||||
<div>
|
||||
<h4>User Information</h4>
|
||||
<dl class="row">
|
||||
<dt class="col-sm-2">
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
First Name:
|
||||
</dt>
|
||||
<dd class="col-sm-10">
|
||||
<dd className="col-sm-10">
|
||||
{state.firstName}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl class="row">
|
||||
<dt class="col-sm-2">
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Last Name:
|
||||
</dt>
|
||||
<dd class="col-sm-10">
|
||||
<dd className="col-sm-10">
|
||||
{state.lastName}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl class="row">
|
||||
<dt class="col-sm-2">
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
User Name:
|
||||
</dt>
|
||||
<dd class="col-sm-10">
|
||||
<dd className="col-sm-10">
|
||||
{state.username}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl class="row">
|
||||
<dt class="col-sm-2">
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Email:
|
||||
</dt>
|
||||
<dd class="col-sm-10">
|
||||
<dd className="col-sm-10">
|
||||
{state.email}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<form onSubmit={onConfirmation}>
|
||||
<input type="hidden" asp-for="Id" />
|
||||
<button type="submit" class="btn btn-danger">Delete</button> |
|
||||
<button type="submit" className="btn btn-danger">Delete</button> |
|
||||
<button onClick={onCancel} className="btn btn-primary">Back to List</button>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -4,45 +4,37 @@ import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function UpdateUser() {
|
||||
const location = useLocation();
|
||||
let navigate = useNavigate();
|
||||
const search = useLocation().search;
|
||||
const id = new URLSearchParams(search).get('id')
|
||||
|
||||
const [firstName, setFirstName] = useState("");
|
||||
const [lastName, setLastName] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [username, setUsername] = useState("");
|
||||
const [role, setRole] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
const id = location.pathName.slice(location.pathName.lastIndexOf("/") , location.pathName.length);
|
||||
//const id = location.pathName.slice(location.pathName.lastIndexOf("/") , location.pathName.length);
|
||||
getData('Users/' + id).then(
|
||||
(result) => {
|
||||
//let responseJson = result;
|
||||
console.log("user for edit: ");
|
||||
console.log(result);
|
||||
console.log("Username: " + result.username)
|
||||
if (result) {
|
||||
setState({
|
||||
//users: result,
|
||||
id: result.id,
|
||||
firstName: result.firstName,
|
||||
lastName: result.lastName,
|
||||
userName: result.userName,
|
||||
email: result.email,
|
||||
loading: false
|
||||
});
|
||||
setFirstName(result.firstName);
|
||||
setLastName(result.lastName);
|
||||
setEmail(result.email);
|
||||
setUsername(result.username);
|
||||
setRole(result.roles);
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
}, [location])
|
||||
|
||||
let navigate = useNavigate();
|
||||
|
||||
const [state, setState] = useState({
|
||||
id: '',
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
userName: '',
|
||||
email: '',
|
||||
roles: []
|
||||
});
|
||||
|
||||
function onChange(e) {
|
||||
this.setState({ [e.target.name]: e.target.value });
|
||||
}
|
||||
}, [id])
|
||||
|
||||
function onKeyDown(e) {
|
||||
if (e.key === 'Enter') {
|
||||
@ -57,26 +49,28 @@ export default function UpdateUser() {
|
||||
function onSubmit(e){
|
||||
e.preventDefault();
|
||||
|
||||
const id = location.pathName.slice(location.pathName.lastIndexOf("/") , location.pathName.length);
|
||||
//const id = location.pathName.slice(location.pathName.lastIndexOf("/") , location.pathName.length);
|
||||
|
||||
let userProfile = {
|
||||
id: state.id,
|
||||
firstName: state.firstName,
|
||||
lastName: state.lastName,
|
||||
email: state.email,
|
||||
roles: state.roles
|
||||
id: id,
|
||||
Username: username,
|
||||
FirstName: firstName,
|
||||
LastName: lastName,
|
||||
Email: email,
|
||||
}
|
||||
|
||||
putData('Users/' + id, userProfile).then((result) => {
|
||||
let responseJson = result;
|
||||
console.log("update response: ");
|
||||
|
||||
if(responseJson){
|
||||
console.log(responseJson);
|
||||
navigate('/admin/users');
|
||||
}
|
||||
}
|
||||
console.log("Put Request body: ");
|
||||
console.log(userProfile);
|
||||
|
||||
let responseJson = result;
|
||||
console.log("update response: ");
|
||||
|
||||
if(responseJson){
|
||||
console.log(responseJson);
|
||||
navigate('/admin/users');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -87,24 +81,25 @@ export default function UpdateUser() {
|
||||
<form onSubmit={onSubmit}>
|
||||
<div className="form-group">
|
||||
<label className="control-label">First Name: </label>
|
||||
<input className="form-control" type="text" value={state.firstName} onChange={onChange} name="firstName"
|
||||
<input className="form-control" type="text" value={firstName} onChange={(e) => setFirstName(e.target.value)} name="firstName"
|
||||
onKeyDown={onKeyDown} ></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Last Name: </label>
|
||||
<input className="form-control" type="text" value={state.lastName} onChange={onChange} name="lastName"
|
||||
<input className="form-control" type="text" value={lastName} onChange={(e) => setLastName(e.target.value)} name="lastName"
|
||||
onKeyDown={onKeyDown} ></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">User Name: </label>
|
||||
<input className="form-control" type="text" value={state.userName} disabled = {true} readOnly = {true}></input>
|
||||
<input className="form-control" type="text" value={username} onChange={(e) => setUsername(e.target.value)} name="username"
|
||||
onKeyDown={onKeyDown} ></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Email: </label>
|
||||
<input className="form-control" type="text" value={state.email} onChange={onChange} name="email"
|
||||
<input className="form-control" type="text" value={email} onChange={(e) => setEmail(e.target.value)} name="email"
|
||||
onKeyDown={onKeyDown}></input>
|
||||
</div>
|
||||
|
||||
|
@ -20,11 +20,15 @@ export default function Users() {
|
||||
}
|
||||
|
||||
function onUserEdit(id){
|
||||
navigate('/admin/user/edit/' + id);
|
||||
let path = "/admin/user/edit"
|
||||
let query = "?id=" + id
|
||||
navigate(path + query);
|
||||
}
|
||||
|
||||
function onUserDelete(id){
|
||||
navigate('/admin/user/delete/' + id);
|
||||
let path = "/admin/user/delete"
|
||||
let query = "?id=" + id
|
||||
navigate(path + query);
|
||||
}
|
||||
|
||||
function getAllUsersData() {
|
||||
|
70
active-allocator/Controllers/AccountController.cs
Normal file
70
active-allocator/Controllers/AccountController.cs
Normal file
@ -0,0 +1,70 @@
|
||||
namespace active_allocator.Controllers;
|
||||
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using active_allocator.Models.Accounts;
|
||||
using active_allocator.Services;
|
||||
using active_allocator.Authorization;
|
||||
using active_allocator.Helpers;
|
||||
using System.Collections.Generic;
|
||||
using active_allocator.Entities;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class AccountsController : ControllerBase
|
||||
{
|
||||
private IAccountService _accountService;
|
||||
private IMapper _mapper;
|
||||
private readonly AppSettings _appSettings;
|
||||
|
||||
public AccountsController(
|
||||
IAccountService accountService,
|
||||
IMapper mapper,
|
||||
IOptions<AppSettings> appSettings)
|
||||
{
|
||||
_accountService = accountService;
|
||||
_mapper = mapper;
|
||||
_appSettings = appSettings.Value;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult GetAll()
|
||||
{
|
||||
List<AccountDTO> accountDtos = new List<AccountDTO>();
|
||||
|
||||
foreach (Account acc in _accountService.GetAll())
|
||||
accountDtos.Add(_mapper.Map<Account, AccountDTO>(acc));
|
||||
|
||||
return Ok(accountDtos);
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public IActionResult GetById(int id)
|
||||
{
|
||||
Account account = _accountService.GetById(id);
|
||||
return Ok(_mapper.Map<Account, AccountDTO>(account));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Create([FromBody]AccountCreateRequest model)
|
||||
{
|
||||
_accountService.Create(model);
|
||||
return Ok(new { message = "account created" });
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
public IActionResult Update(int id, [FromBody]AccountUpdateRequest model)
|
||||
{
|
||||
_accountService.Update(id, model);
|
||||
return Ok(new { message = "account updated" });
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(int id)
|
||||
{
|
||||
_accountService.Delete(id);
|
||||
return Ok(new { message = "account deleted" });
|
||||
}
|
||||
}
|
64
active-allocator/Controllers/CurrencyTypeController.cs
Normal file
64
active-allocator/Controllers/CurrencyTypeController.cs
Normal file
@ -0,0 +1,64 @@
|
||||
namespace active_allocator.Controllers;
|
||||
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using active_allocator.Models.CurrencyType;
|
||||
using active_allocator.Services;
|
||||
using active_allocator.Authorization;
|
||||
using active_allocator.Helpers;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class CurrencyTypesController : ControllerBase
|
||||
{
|
||||
private ICurrencyTypeService _currencyTypeService;
|
||||
private IMapper _mapper;
|
||||
private readonly AppSettings _appSettings;
|
||||
|
||||
public CurrencyTypesController(
|
||||
ICurrencyTypeService currencyTypeService,
|
||||
IMapper mapper,
|
||||
IOptions<AppSettings> appSettings)
|
||||
{
|
||||
_currencyTypeService = currencyTypeService;
|
||||
_mapper = mapper;
|
||||
_appSettings = appSettings.Value;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult GetAll()
|
||||
{
|
||||
var currencyTypes = _currencyTypeService.GetAll();
|
||||
return Ok(currencyTypes);
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public IActionResult GetById(int id)
|
||||
{
|
||||
var currencyType = _currencyTypeService.GetById(id);
|
||||
return Ok(currencyType);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Create([FromBody]CurrencyTypeCreateRequest model)
|
||||
{
|
||||
_currencyTypeService.Create(model);
|
||||
return Ok(new { message = "currencyType created" });
|
||||
}
|
||||
|
||||
/*[HttpPut("{id}")]
|
||||
public IActionResult Update(int id, [FromBody]AccountUpdateRequest model)
|
||||
{
|
||||
_accountService.Update(id, model);
|
||||
return Ok(new { message = "account updated" });
|
||||
}*/
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(int id)
|
||||
{
|
||||
_currencyTypeService.Delete(id);
|
||||
return Ok(new { message = "currencyType deleted" });
|
||||
}
|
||||
}
|
64
active-allocator/Controllers/FireFlyController.cs
Normal file
64
active-allocator/Controllers/FireFlyController.cs
Normal file
@ -0,0 +1,64 @@
|
||||
namespace active_allocator.Controllers;
|
||||
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using active_allocator.Models.Accounts;
|
||||
using active_allocator.Services;
|
||||
using active_allocator.Authorization;
|
||||
using active_allocator.Helpers;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class FireFlyController : ControllerBase
|
||||
{
|
||||
private IFireFlyService _fireFlyService;
|
||||
private IMapper _mapper;
|
||||
private readonly AppSettings _appSettings;
|
||||
|
||||
public FireFlyController(
|
||||
IFireFlyService fireFlyService,
|
||||
IMapper mapper,
|
||||
IOptions<AppSettings> appSettings)
|
||||
{
|
||||
_fireFlyService = fireFlyService;
|
||||
_mapper = mapper;
|
||||
_appSettings = appSettings.Value;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetAll()
|
||||
{
|
||||
var transactions = await _fireFlyService.GetAll();
|
||||
return Ok(transactions);
|
||||
}
|
||||
/*
|
||||
[HttpGet("{id}")]
|
||||
public IActionResult GetById(int id)
|
||||
{
|
||||
var account = _accountService.GetById(id);
|
||||
return Ok(account);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Create([FromBody]AccountCreateRequest model)
|
||||
{
|
||||
_accountService.Create(model);
|
||||
return Ok(new { message = "account created" });
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
public IActionResult Update(int id, [FromBody]AccountUpdateRequest model)
|
||||
{
|
||||
_accountService.Update(id, model);
|
||||
return Ok(new { message = "account updated" });
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(int id)
|
||||
{
|
||||
_accountService.Delete(id);
|
||||
return Ok(new { message = "account deleted" });
|
||||
}*/
|
||||
}
|
70
active-allocator/Controllers/TransactionController.cs
Normal file
70
active-allocator/Controllers/TransactionController.cs
Normal file
@ -0,0 +1,70 @@
|
||||
namespace active_allocator.Controllers;
|
||||
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using active_allocator.Models.Transactions;
|
||||
using active_allocator.Services;
|
||||
using active_allocator.Authorization;
|
||||
using active_allocator.Helpers;
|
||||
using System.Runtime.InteropServices;
|
||||
using active_allocator.Entities;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class TransactionsController : ControllerBase
|
||||
{
|
||||
private ITransactionService _transactionService;
|
||||
private IMapper _mapper;
|
||||
private readonly AppSettings _appSettings;
|
||||
|
||||
public TransactionsController(
|
||||
ITransactionService transactionService,
|
||||
IMapper mapper,
|
||||
IOptions<AppSettings> appSettings)
|
||||
{
|
||||
_transactionService = transactionService;
|
||||
_mapper = mapper;
|
||||
_appSettings = appSettings.Value;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult GetAll()
|
||||
{
|
||||
List<TransactionDto> transactionDtos = new List<TransactionDto>();
|
||||
|
||||
foreach (Transaction tran in _transactionService.GetAll())
|
||||
transactionDtos.Add(_mapper.Map<Transaction, TransactionDto>(tran));
|
||||
|
||||
return Ok(transactionDtos);
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public IActionResult GetById(int id)
|
||||
{
|
||||
Transaction tran = _transactionService.GetById(id);
|
||||
return Ok(_mapper.Map<Transaction, TransactionDto>(tran));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Create([FromBody]TransactionCreate model)
|
||||
{
|
||||
_transactionService.Create(model);
|
||||
return Ok(new { message = "transaction created" });
|
||||
}
|
||||
|
||||
/*[HttpPut("{id}")]
|
||||
public IActionResult Update(int id, [FromBody]TransactionUpdateRequest model)
|
||||
{
|
||||
_transactionService.Update(id, model);
|
||||
return Ok(new { message = "transaction updated" });
|
||||
}*/
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(int id)
|
||||
{
|
||||
_transactionService.Delete(id);
|
||||
return Ok(new { message = "transaction deleted" });
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ using active_allocator.Models.Users;
|
||||
using active_allocator.Services;
|
||||
using active_allocator.Authorization;
|
||||
using active_allocator.Helpers;
|
||||
using System;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
@ -58,11 +59,27 @@ public class UsersController : ControllerBase
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
public IActionResult Update(int id, [FromBody]UpdateRequest model)
|
||||
public IActionResult Update(int id, [FromBody]UserUpdateRequest model)
|
||||
{
|
||||
_userService.Update(id, model);
|
||||
return Ok(new { message = "User updated" });
|
||||
}
|
||||
/*
|
||||
[HttpPut("{id}")]
|
||||
public IActionResult Update(int id, string Email = null, string FirstName = null, string LastName = null, string Username = null, string Role = null, string Password = null)
|
||||
{
|
||||
UserUpdateRequest model = new UserUpdateRequest() {
|
||||
Email = Email,
|
||||
FirstName = FirstName,
|
||||
LastName = LastName,
|
||||
Username = Username,
|
||||
Role = Role,
|
||||
Password = Password
|
||||
};
|
||||
|
||||
_userService.Update(id, model);
|
||||
return Ok(new { message = "User updated" });
|
||||
}*/
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(int id)
|
||||
|
@ -6,13 +6,16 @@ public class Account
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int OwnerId { get; set; }
|
||||
public User Owner { get; set; }
|
||||
public DateTime LastActivity { get; set; }
|
||||
public decimal Balance { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public decimal InitialBalance { get; set; }
|
||||
public int CurrencyId { get; set; }
|
||||
public CurrencyType Currency { get; set; }
|
||||
public string ExternalAccountNumber { get; set; }
|
||||
public ICollection<Alloc> Allocs { get; set; }
|
||||
//public ICollection<Transaction> Transactions { get; set; }
|
||||
//public Institution institution { get; set; }
|
||||
}
|
21
active-allocator/Entities/Transaction.cs
Normal file
21
active-allocator/Entities/Transaction.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using active_allocator.Services;
|
||||
|
||||
namespace active_allocator.Entities;
|
||||
|
||||
public class Transaction
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public User Owner { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public DateTime UpdatedOn { get; set; }
|
||||
public string ExternalId { get; set; }
|
||||
public string Description { get; set; }
|
||||
public Account DebitAccount { get; set; }
|
||||
public Account CreditAccount { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public CurrencyType CurrencyType { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public bool IsPending { get; set; }
|
||||
}
|
@ -3,9 +3,15 @@ namespace active_allocator.Helpers;
|
||||
using AutoMapper;
|
||||
using active_allocator.Entities;
|
||||
using active_allocator.Models.Users;
|
||||
using active_allocator.Models.Accounts;
|
||||
using active_allocator.Models.CurrencyType;
|
||||
using active_allocator.Services;
|
||||
using System.Runtime.Serialization;
|
||||
using active_allocator.Models.Transactions;
|
||||
|
||||
public class AutoMapperProfile : Profile
|
||||
{
|
||||
|
||||
public AutoMapperProfile()
|
||||
{
|
||||
// User -> AuthenticateResponse
|
||||
@ -14,8 +20,8 @@ public class AutoMapperProfile : Profile
|
||||
// RegisterRequest -> User
|
||||
CreateMap<RegisterRequest, User>();
|
||||
|
||||
// UpdateRequest -> User
|
||||
CreateMap<UpdateRequest, User>()
|
||||
// UserUpdateRequest -> User
|
||||
CreateMap<UserUpdateRequest, User>()
|
||||
.ForAllMembers(x => x.Condition(
|
||||
(src, dest, prop) =>
|
||||
{
|
||||
@ -26,8 +32,83 @@ public class AutoMapperProfile : Profile
|
||||
// ignore null role
|
||||
if (x.DestinationMember.Name == "Role" && src.Role == null) return false;
|
||||
|
||||
// ignore null password
|
||||
if (x.DestinationMember.Name == "Password" && src.Password == null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
));
|
||||
|
||||
// AccountUpdateRequest -> Account
|
||||
CreateMap<AccountUpdateRequest, Account>()
|
||||
.ForAllMembers(x => x.Condition(
|
||||
(src, dest, prop) =>
|
||||
{
|
||||
// ignore both null & empty string properties
|
||||
if (prop == null) return false;
|
||||
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
));
|
||||
|
||||
// AccountCreateRequest -> Account
|
||||
CreateMap<AccountCreateRequest, Account>()
|
||||
.ForMember(
|
||||
dest => dest.OwnerId,
|
||||
opt => opt.MapFrom(src => src.Owner)
|
||||
);
|
||||
/*.ForAllMembers(x => x.Condition(
|
||||
(src, dest, prop) =>
|
||||
{
|
||||
// ignore both null & empty string properties
|
||||
if (prop == null) return false;
|
||||
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
))*/
|
||||
|
||||
// Account -> AccountGet
|
||||
CreateMap<Account, AccountDTO>()
|
||||
.ForAllMembers(x => x.Condition(
|
||||
(src, dest, prop) =>
|
||||
{
|
||||
// ignore both null & empty string properties
|
||||
if (prop == null) return false;
|
||||
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
));
|
||||
|
||||
// Transaction -> TransactionDto
|
||||
CreateMap<Transaction, TransactionDto>()
|
||||
.ForMember(dest => dest.DebitAccountId, opt => opt.MapFrom(src => src.DebitAccount.Id))
|
||||
.ForMember(dest => dest.CreditAccountId, opt => opt.MapFrom(src => src.CreditAccount.Id))
|
||||
.ForAllMembers(x => x.Condition(
|
||||
(src, dest, prop) =>
|
||||
{
|
||||
// ignore both null & empty string properties
|
||||
if (prop == null) return false;
|
||||
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
));
|
||||
|
||||
// CurrencyTypeCreateRequest -> CurrencyType
|
||||
CreateMap<CurrencyTypeCreateRequest, CurrencyType>()
|
||||
.ForAllMembers(x => x.Condition(
|
||||
(src, dest, prop) =>
|
||||
{
|
||||
// ignore both null & empty string properties
|
||||
if (prop == null) return false;
|
||||
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
));
|
||||
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ namespace active_allocator.Helpers;
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using active_allocator.Entities;
|
||||
using System.Diagnostics;
|
||||
|
||||
public class DataContext : DbContext
|
||||
{
|
||||
@ -23,4 +24,5 @@ public class DataContext : DbContext
|
||||
public DbSet<Alloc> Allocs { get; set; }
|
||||
public DbSet<CurrencyType> CurrencyTypes { get; set; }
|
||||
public DbSet<Operation> Operations { get; set; }
|
||||
public DbSet<Transaction> Transactions { get; set; }
|
||||
}
|
420
active-allocator/Migrations/20231219215509_AddedTransactionEntity.Designer.cs
generated
Normal file
420
active-allocator/Migrations/20231219215509_AddedTransactionEntity.Designer.cs
generated
Normal file
@ -0,0 +1,420 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using active_allocator.Helpers;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace active_allocator.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20231219215509_AddedTransactionEntity")]
|
||||
partial class AddedTransactionEntity
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.9")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("Balance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("CurrencyId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ExternalAccountNumber")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<decimal>("InitialBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("LastActivity")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("CurrentBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal>("LastBalanceAdded")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("LastTriggeredOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<TimeSpan>("Period")
|
||||
.HasColumnType("interval");
|
||||
|
||||
b.Property<bool>("PersistanceEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.ToTable("Allocs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.CurrencyType", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("DecimalPlaces")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTypes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.InnerTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("CreditAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("CurrencyTypeId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("DebitAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("InnerTransactionId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("IsPending")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("OuterTransactionId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreditAccountId");
|
||||
|
||||
b.HasIndex("CurrencyTypeId");
|
||||
|
||||
b.HasIndex("DebitAccountId");
|
||||
|
||||
b.HasIndex("InnerTransactionId");
|
||||
|
||||
b.HasIndex("OuterTransactionId");
|
||||
|
||||
b.ToTable("InnerTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Operation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("AbsoluteValue")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<int?>("AllocId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("HistoricLookbackDepth")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<TimeSpan>("HistoricPeriod")
|
||||
.HasColumnType("interval");
|
||||
|
||||
b.Property<int>("HistoricStatistic")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Mode")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Negative")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Percentage")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AllocId");
|
||||
|
||||
b.ToTable("Operations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.OuterTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("SplitDescription")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("OuterTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Role")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.CurrencyType", "Currency")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.User", "Owner")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Account", "Account")
|
||||
.WithMany("Allocs")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.InnerTransaction", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Account", "CreditAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreditAccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.CurrencyType", "CurrencyType")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyTypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.Account", "DebitAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("DebitAccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.InnerTransaction", null)
|
||||
.WithMany("Transactions")
|
||||
.HasForeignKey("InnerTransactionId");
|
||||
|
||||
b.HasOne("active_allocator.Entities.OuterTransaction", null)
|
||||
.WithMany("Transactions")
|
||||
.HasForeignKey("OuterTransactionId");
|
||||
|
||||
b.Navigation("CreditAccount");
|
||||
|
||||
b.Navigation("CurrencyType");
|
||||
|
||||
b.Navigation("DebitAccount");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Operation", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Alloc", null)
|
||||
.WithMany("Operations")
|
||||
.HasForeignKey("AllocId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.OuterTransaction", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.User", "Owner")
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.Navigation("Allocs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
{
|
||||
b.Navigation("Operations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.InnerTransaction", b =>
|
||||
{
|
||||
b.Navigation("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.OuterTransaction", b =>
|
||||
{
|
||||
b.Navigation("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.User", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace active_allocator.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedTransactionEntity : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "OuterTransactions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
OwnerId = table.Column<int>(type: "integer", nullable: false),
|
||||
SplitDescription = table.Column<string>(type: "text", nullable: false),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
ExternalId = table.Column<string>(type: "text", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_OuterTransactions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_OuterTransactions_Users_OwnerId",
|
||||
column: x => x.OwnerId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "InnerTransactions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Description = table.Column<string>(type: "text", nullable: false),
|
||||
DebitAccountId = table.Column<int>(type: "integer", nullable: false),
|
||||
CreditAccountId = table.Column<int>(type: "integer", nullable: false),
|
||||
Amount = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
ExternalId = table.Column<string>(type: "text", nullable: false),
|
||||
CurrencyTypeId = table.Column<int>(type: "integer", nullable: false),
|
||||
Notes = table.Column<string>(type: "text", nullable: false),
|
||||
IsPending = table.Column<bool>(type: "boolean", nullable: false),
|
||||
InnerTransactionId = table.Column<int>(type: "integer", nullable: true),
|
||||
OuterTransactionId = table.Column<int>(type: "integer", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_InnerTransactions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_InnerTransactions_Accounts_CreditAccountId",
|
||||
column: x => x.CreditAccountId,
|
||||
principalTable: "Accounts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_InnerTransactions_Accounts_DebitAccountId",
|
||||
column: x => x.DebitAccountId,
|
||||
principalTable: "Accounts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_InnerTransactions_CurrencyTypes_CurrencyTypeId",
|
||||
column: x => x.CurrencyTypeId,
|
||||
principalTable: "CurrencyTypes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_InnerTransactions_InnerTransactions_InnerTransactionId",
|
||||
column: x => x.InnerTransactionId,
|
||||
principalTable: "InnerTransactions",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_InnerTransactions_OuterTransactions_OuterTransactionId",
|
||||
column: x => x.OuterTransactionId,
|
||||
principalTable: "OuterTransactions",
|
||||
principalColumn: "Id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InnerTransactions_CreditAccountId",
|
||||
table: "InnerTransactions",
|
||||
column: "CreditAccountId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InnerTransactions_CurrencyTypeId",
|
||||
table: "InnerTransactions",
|
||||
column: "CurrencyTypeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InnerTransactions_DebitAccountId",
|
||||
table: "InnerTransactions",
|
||||
column: "DebitAccountId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InnerTransactions_InnerTransactionId",
|
||||
table: "InnerTransactions",
|
||||
column: "InnerTransactionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InnerTransactions_OuterTransactionId",
|
||||
table: "InnerTransactions",
|
||||
column: "OuterTransactionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OuterTransactions_OwnerId",
|
||||
table: "OuterTransactions",
|
||||
column: "OwnerId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "InnerTransactions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "OuterTransactions");
|
||||
}
|
||||
}
|
||||
}
|
399
active-allocator/Migrations/20231221130142_ModifiedTranscationEntity.Designer.cs
generated
Normal file
399
active-allocator/Migrations/20231221130142_ModifiedTranscationEntity.Designer.cs
generated
Normal file
@ -0,0 +1,399 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using active_allocator.Helpers;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace active_allocator.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20231221130142_ModifiedTranscationEntity")]
|
||||
partial class ModifiedTranscationEntity
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.9")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("Balance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("CurrencyId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ExternalAccountNumber")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<decimal>("InitialBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("LastActivity")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("CurrentBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal>("LastBalanceAdded")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("LastTriggeredOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<TimeSpan>("Period")
|
||||
.HasColumnType("interval");
|
||||
|
||||
b.Property<bool>("PersistanceEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.ToTable("Allocs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.CurrencyType", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("DecimalPlaces")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTypes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.InnerTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<int>("CreditAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("CurrencyTypeId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("DebitAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsPending")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("OuterTransactionId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreditAccountId");
|
||||
|
||||
b.HasIndex("CurrencyTypeId");
|
||||
|
||||
b.HasIndex("DebitAccountId");
|
||||
|
||||
b.HasIndex("OuterTransactionId");
|
||||
|
||||
b.ToTable("InnerTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Operation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("AbsoluteValue")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<int?>("AllocId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("HistoricLookbackDepth")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<TimeSpan>("HistoricPeriod")
|
||||
.HasColumnType("interval");
|
||||
|
||||
b.Property<int>("HistoricStatistic")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Mode")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Negative")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Percentage")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AllocId");
|
||||
|
||||
b.ToTable("Operations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.OuterTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("SplitDescription")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("OuterTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Role")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.CurrencyType", "Currency")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.User", "Owner")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Account", "Account")
|
||||
.WithMany("Allocs")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.InnerTransaction", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Account", "CreditAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreditAccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.CurrencyType", "CurrencyType")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyTypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.Account", "DebitAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("DebitAccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.OuterTransaction", null)
|
||||
.WithMany("Transactions")
|
||||
.HasForeignKey("OuterTransactionId");
|
||||
|
||||
b.Navigation("CreditAccount");
|
||||
|
||||
b.Navigation("CurrencyType");
|
||||
|
||||
b.Navigation("DebitAccount");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Operation", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Alloc", null)
|
||||
.WithMany("Operations")
|
||||
.HasForeignKey("AllocId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.OuterTransaction", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.User", "Owner")
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.Navigation("Allocs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
{
|
||||
b.Navigation("Operations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.OuterTransaction", b =>
|
||||
{
|
||||
b.Navigation("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.User", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace active_allocator.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ModifiedTranscationEntity : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_InnerTransactions_InnerTransactions_InnerTransactionId",
|
||||
table: "InnerTransactions");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_InnerTransactions_InnerTransactionId",
|
||||
table: "InnerTransactions");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "CreatedOn",
|
||||
table: "InnerTransactions");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ExternalId",
|
||||
table: "InnerTransactions");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "InnerTransactionId",
|
||||
table: "InnerTransactions");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "UpdatedOn",
|
||||
table: "InnerTransactions");
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "Date",
|
||||
table: "OuterTransactions",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Date",
|
||||
table: "OuterTransactions");
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "CreatedOn",
|
||||
table: "InnerTransactions",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "ExternalId",
|
||||
table: "InnerTransactions",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "InnerTransactionId",
|
||||
table: "InnerTransactions",
|
||||
type: "integer",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "UpdatedOn",
|
||||
table: "InnerTransactions",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InnerTransactions_InnerTransactionId",
|
||||
table: "InnerTransactions",
|
||||
column: "InnerTransactionId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_InnerTransactions_InnerTransactions_InnerTransactionId",
|
||||
table: "InnerTransactions",
|
||||
column: "InnerTransactionId",
|
||||
principalTable: "InnerTransactions",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
}
|
||||
}
|
365
active-allocator/Migrations/20231221150634_SimplifiedTransaction.Designer.cs
generated
Normal file
365
active-allocator/Migrations/20231221150634_SimplifiedTransaction.Designer.cs
generated
Normal file
@ -0,0 +1,365 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using active_allocator.Helpers;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace active_allocator.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20231221150634_SimplifiedTransaction")]
|
||||
partial class SimplifiedTransaction
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.9")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("Balance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("CurrencyId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ExternalAccountNumber")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<decimal>("InitialBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("LastActivity")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("CurrentBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal>("LastBalanceAdded")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("LastTriggeredOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<TimeSpan>("Period")
|
||||
.HasColumnType("interval");
|
||||
|
||||
b.Property<bool>("PersistanceEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.ToTable("Allocs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.CurrencyType", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("DecimalPlaces")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTypes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Operation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("AbsoluteValue")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<int?>("AllocId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("HistoricLookbackDepth")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<TimeSpan>("HistoricPeriod")
|
||||
.HasColumnType("interval");
|
||||
|
||||
b.Property<int>("HistoricStatistic")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Mode")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Negative")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Percentage")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AllocId");
|
||||
|
||||
b.ToTable("Operations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Transaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("CreditAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("CurrencyTypeId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("DebitAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsPending")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreditAccountId");
|
||||
|
||||
b.HasIndex("CurrencyTypeId");
|
||||
|
||||
b.HasIndex("DebitAccountId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("Role")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.CurrencyType", "Currency")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.User", "Owner")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Account", "Account")
|
||||
.WithMany("Allocs")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Operation", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Alloc", null)
|
||||
.WithMany("Operations")
|
||||
.HasForeignKey("AllocId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Transaction", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Account", "CreditAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreditAccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.CurrencyType", "CurrencyType")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyTypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.Account", "DebitAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("DebitAccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.User", "Owner")
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CreditAccount");
|
||||
|
||||
b.Navigation("CurrencyType");
|
||||
|
||||
b.Navigation("DebitAccount");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.Navigation("Allocs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
{
|
||||
b.Navigation("Operations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.User", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,189 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace active_allocator.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class SimplifiedTransaction : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "InnerTransactions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "OuterTransactions");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Transactions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
OwnerId = table.Column<int>(type: "integer", nullable: false),
|
||||
Date = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
ExternalId = table.Column<string>(type: "text", nullable: false),
|
||||
Description = table.Column<string>(type: "text", nullable: false),
|
||||
DebitAccountId = table.Column<int>(type: "integer", nullable: false),
|
||||
CreditAccountId = table.Column<int>(type: "integer", nullable: false),
|
||||
Amount = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
CurrencyTypeId = table.Column<int>(type: "integer", nullable: false),
|
||||
Notes = table.Column<string>(type: "text", nullable: false),
|
||||
IsPending = table.Column<bool>(type: "boolean", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Transactions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Transactions_Accounts_CreditAccountId",
|
||||
column: x => x.CreditAccountId,
|
||||
principalTable: "Accounts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Transactions_Accounts_DebitAccountId",
|
||||
column: x => x.DebitAccountId,
|
||||
principalTable: "Accounts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Transactions_CurrencyTypes_CurrencyTypeId",
|
||||
column: x => x.CurrencyTypeId,
|
||||
principalTable: "CurrencyTypes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Transactions_Users_OwnerId",
|
||||
column: x => x.OwnerId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Transactions_CreditAccountId",
|
||||
table: "Transactions",
|
||||
column: "CreditAccountId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Transactions_CurrencyTypeId",
|
||||
table: "Transactions",
|
||||
column: "CurrencyTypeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Transactions_DebitAccountId",
|
||||
table: "Transactions",
|
||||
column: "DebitAccountId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Transactions_OwnerId",
|
||||
table: "Transactions",
|
||||
column: "OwnerId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Transactions");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "OuterTransactions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
OwnerId = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
Date = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
ExternalId = table.Column<string>(type: "text", nullable: false),
|
||||
SplitDescription = table.Column<string>(type: "text", nullable: false),
|
||||
UpdatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_OuterTransactions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_OuterTransactions_Users_OwnerId",
|
||||
column: x => x.OwnerId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "InnerTransactions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
CreditAccountId = table.Column<int>(type: "integer", nullable: false),
|
||||
CurrencyTypeId = table.Column<int>(type: "integer", nullable: false),
|
||||
DebitAccountId = table.Column<int>(type: "integer", nullable: false),
|
||||
Amount = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
Description = table.Column<string>(type: "text", nullable: false),
|
||||
IsPending = table.Column<bool>(type: "boolean", nullable: false),
|
||||
Notes = table.Column<string>(type: "text", nullable: false),
|
||||
OuterTransactionId = table.Column<int>(type: "integer", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_InnerTransactions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_InnerTransactions_Accounts_CreditAccountId",
|
||||
column: x => x.CreditAccountId,
|
||||
principalTable: "Accounts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_InnerTransactions_Accounts_DebitAccountId",
|
||||
column: x => x.DebitAccountId,
|
||||
principalTable: "Accounts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_InnerTransactions_CurrencyTypes_CurrencyTypeId",
|
||||
column: x => x.CurrencyTypeId,
|
||||
principalTable: "CurrencyTypes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_InnerTransactions_OuterTransactions_OuterTransactionId",
|
||||
column: x => x.OuterTransactionId,
|
||||
principalTable: "OuterTransactions",
|
||||
principalColumn: "Id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InnerTransactions_CreditAccountId",
|
||||
table: "InnerTransactions",
|
||||
column: "CreditAccountId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InnerTransactions_CurrencyTypeId",
|
||||
table: "InnerTransactions",
|
||||
column: "CurrencyTypeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InnerTransactions_DebitAccountId",
|
||||
table: "InnerTransactions",
|
||||
column: "DebitAccountId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_InnerTransactions_OuterTransactionId",
|
||||
table: "InnerTransactions",
|
||||
column: "OuterTransactionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_OuterTransactions_OwnerId",
|
||||
table: "OuterTransactions",
|
||||
column: "OwnerId");
|
||||
}
|
||||
}
|
||||
}
|
@ -174,6 +174,66 @@ namespace active_allocator.Migrations
|
||||
b.ToTable("Operations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Transaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("CreditAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("CurrencyTypeId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("DebitAccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsPending")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime>("UpdatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreditAccountId");
|
||||
|
||||
b.HasIndex("CurrencyTypeId");
|
||||
|
||||
b.HasIndex("DebitAccountId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -247,6 +307,41 @@ namespace active_allocator.Migrations
|
||||
.HasForeignKey("AllocId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Transaction", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Account", "CreditAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreditAccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.CurrencyType", "CurrencyType")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyTypeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.Account", "DebitAccount")
|
||||
.WithMany()
|
||||
.HasForeignKey("DebitAccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("active_allocator.Entities.User", "Owner")
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CreditAccount");
|
||||
|
||||
b.Navigation("CurrencyType");
|
||||
|
||||
b.Navigation("DebitAccount");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.Navigation("Allocs");
|
||||
|
14
active-allocator/Models/Accounts/AccountCreateRequest.cs
Normal file
14
active-allocator/Models/Accounts/AccountCreateRequest.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace active_allocator.Models.Accounts;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.InteropServices;
|
||||
using active_allocator.Entities;
|
||||
|
||||
public class AccountCreateRequest
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Owner { get; set; }
|
||||
public string InitialBalance { get; set; }
|
||||
public int Currency { get; set; }
|
||||
public string ExternalAccountNumber { get; set; }
|
||||
}
|
16
active-allocator/Models/Accounts/AccountDTO.cs
Normal file
16
active-allocator/Models/Accounts/AccountDTO.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace active_allocator.Models.Accounts;
|
||||
|
||||
public class AccountDTO
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int OwnerId { get; set; }
|
||||
public DateTime LastActivity { get; set; }
|
||||
public decimal Balance { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public decimal InitialBalance { get; set; }
|
||||
public int CurrencyId { get; set; }
|
||||
public string ExternalAccountNumber { get; set; }
|
||||
}
|
15
active-allocator/Models/Accounts/AccountUpdateRequest.cs
Normal file
15
active-allocator/Models/Accounts/AccountUpdateRequest.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace active_allocator.Models.Accounts;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using active_allocator.Entities;
|
||||
|
||||
public class AccountUpdateRequest
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int OwnerId { get; set; }
|
||||
public string InitialBalance { get; set; }
|
||||
public int CurrencyId { get; set; }
|
||||
public string ExternalAccountNumber { get; set; }
|
||||
public ICollection<int> Allocs { get; set; }
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
namespace active_allocator.Models.CurrencyType;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.InteropServices;
|
||||
using active_allocator.Entities;
|
||||
|
||||
public class CurrencyTypeCreateRequest
|
||||
{
|
||||
public string Code { get; set; } // USD
|
||||
public string Symbol { get; set; } // $
|
||||
public int DecimalPlaces { get; set; } // 2
|
||||
}
|
10
active-allocator/Models/FireFlyTransactions/Attributes.cs
Normal file
10
active-allocator/Models/FireFlyTransactions/Attributes.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
public class Attributes
|
||||
{
|
||||
public DateTime created_at { get; set; }
|
||||
public DateTime updated_at { get; set; }
|
||||
public string user { get; set; }
|
||||
public string group_title { get; set; }
|
||||
public List<Transaction> transactions { get; set; }
|
||||
}
|
9
active-allocator/Models/FireFlyTransactions/Datum.cs
Normal file
9
active-allocator/Models/FireFlyTransactions/Datum.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
public class Datum
|
||||
{
|
||||
public string type { get; set; }
|
||||
public string id { get; set; }
|
||||
public Attributes attributes { get; set; }
|
||||
public Links links { get; set; }
|
||||
}
|
14
active-allocator/Models/FireFlyTransactions/Links.cs
Normal file
14
active-allocator/Models/FireFlyTransactions/Links.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
public class Links
|
||||
{
|
||||
[JsonProperty("0")]
|
||||
public _0 _0 { get; set; }
|
||||
public string self { get; set; }
|
||||
public string first { get; set; }
|
||||
public string next { get; set; }
|
||||
public string prev { get; set; }
|
||||
public string last { get; set; }
|
||||
}
|
6
active-allocator/Models/FireFlyTransactions/Meta.cs
Normal file
6
active-allocator/Models/FireFlyTransactions/Meta.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
public class Meta
|
||||
{
|
||||
public Pagination pagination { get; set; }
|
||||
}
|
10
active-allocator/Models/FireFlyTransactions/Pagination.cs
Normal file
10
active-allocator/Models/FireFlyTransactions/Pagination.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
public class Pagination
|
||||
{
|
||||
public int total { get; set; }
|
||||
public int count { get; set; }
|
||||
public int per_page { get; set; }
|
||||
public int current_page { get; set; }
|
||||
public int total_pages { get; set; }
|
||||
}
|
10
active-allocator/Models/FireFlyTransactions/Root.cs
Normal file
10
active-allocator/Models/FireFlyTransactions/Root.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
|
||||
|
||||
public class Root
|
||||
{
|
||||
public List<Datum> data { get; set; }
|
||||
public Meta meta { get; set; }
|
||||
public Links links { get; set; }
|
||||
}
|
66
active-allocator/Models/FireFlyTransactions/Transaction.cs
Normal file
66
active-allocator/Models/FireFlyTransactions/Transaction.cs
Normal file
@ -0,0 +1,66 @@
|
||||
namespace active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
public class Transaction
|
||||
{
|
||||
public string user { get; set; }
|
||||
public string transaction_journal_id { get; set; }
|
||||
public string type { get; set; }
|
||||
public DateTime date { get; set; }
|
||||
public int? order { get; set; }
|
||||
public string currency_id { get; set; }
|
||||
public string currency_code { get; set; }
|
||||
public string currency_symbol { get; set; }
|
||||
public string currency_name { get; set; }
|
||||
public int? currency_decimal_places { get; set; }
|
||||
public string foreign_currency_id { get; set; }
|
||||
public string foreign_currency_code { get; set; }
|
||||
public string foreign_currency_symbol { get; set; }
|
||||
public int? foreign_currency_decimal_places { get; set; }
|
||||
public string amount { get; set; }
|
||||
public string foreign_amount { get; set; }
|
||||
public string description { get; set; }
|
||||
public string source_id { get; set; }
|
||||
public string source_name { get; set; }
|
||||
public string source_iban { get; set; }
|
||||
public string source_type { get; set; }
|
||||
public string destination_id { get; set; }
|
||||
public string destination_name { get; set; }
|
||||
public string destination_iban { get; set; }
|
||||
public string destination_type { get; set; }
|
||||
public string budget_id { get; set; }
|
||||
public string budget_name { get; set; }
|
||||
public string category_id { get; set; }
|
||||
public string category_name { get; set; }
|
||||
public string bill_id { get; set; }
|
||||
public string bill_name { get; set; }
|
||||
public bool reconciled { get; set; }
|
||||
public string notes { get; set; }
|
||||
public object tags { get; set; }
|
||||
public string internal_reference { get; set; }
|
||||
public string external_id { get; set; }
|
||||
public string external_url { get; set; }
|
||||
public string original_source { get; set; }
|
||||
public int? recurrence_id { get; set; }
|
||||
public int? recurrence_total { get; set; }
|
||||
public int? recurrence_count { get; set; }
|
||||
public string bunq_payment_id { get; set; }
|
||||
public string import_hash_v2 { get; set; }
|
||||
public string sepa_cc { get; set; }
|
||||
public string sepa_ct_op { get; set; }
|
||||
public string sepa_ct_id { get; set; }
|
||||
public string sepa_db { get; set; }
|
||||
public string sepa_country { get; set; }
|
||||
public string sepa_ep { get; set; }
|
||||
public string sepa_ci { get; set; }
|
||||
public string sepa_batch_id { get; set; }
|
||||
public DateTime? interest_date { get; set; }
|
||||
public DateTime? book_date { get; set; }
|
||||
public DateTime? process_date { get; set; }
|
||||
public DateTime? due_date { get; set; }
|
||||
public DateTime? payment_date { get; set; }
|
||||
public DateTime? invoice_date { get; set; }
|
||||
public double? latitude { get; set; }
|
||||
public double? longitude { get; set; }
|
||||
public int? zoom_level { get; set; }
|
||||
public bool has_attachments { get; set; }
|
||||
}
|
7
active-allocator/Models/FireFlyTransactions/_0.cs
Normal file
7
active-allocator/Models/FireFlyTransactions/_0.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
public class _0
|
||||
{
|
||||
public string rel { get; set; }
|
||||
public string uri { get; set; }
|
||||
}
|
43
active-allocator/Models/Transactions/TransactionCreate.cs
Normal file
43
active-allocator/Models/Transactions/TransactionCreate.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime;
|
||||
using active_allocator.Services;
|
||||
|
||||
namespace active_allocator.Models.Transactions;
|
||||
|
||||
public class TransactionCreate
|
||||
{
|
||||
public int Owner { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public string ExternalId { get; set; }
|
||||
public string Description { get; set; }
|
||||
public int? DebitAccount { get; set; }
|
||||
public int? CreditAccount { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public int CurrencyType { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public bool IsPending { get; set; }
|
||||
}
|
||||
|
||||
/*
|
||||
// TransactionCreate myDeserializedClass = JsonConvert.DeserializeObject<TransactionCreate>(myJsonResponse);
|
||||
{
|
||||
"Owner":1,
|
||||
"SplitDescription":"string",
|
||||
"UreatedOn":"2018-09-17T12:46:47+01:00",
|
||||
"UpdatedOn":"2018-09-17T12:46:47+01:00",
|
||||
"ExternalId":"string",
|
||||
"Transactions":[
|
||||
{
|
||||
"Description":"string",
|
||||
"DebitAccount":1,
|
||||
"CreditAccount":1,
|
||||
"Amount":"string",
|
||||
"CreatedOn":"2018-09-17T12:46:47+01:00",
|
||||
"UpdatedOn":"2018-09-17T12:46:47+01:00",
|
||||
"ExternalId":"string",
|
||||
"CreditAccount":1,
|
||||
"Notes":"string",
|
||||
"IsPending":true
|
||||
}
|
||||
]
|
||||
}*/
|
22
active-allocator/Models/Transactions/TransactionDto.cs
Normal file
22
active-allocator/Models/Transactions/TransactionDto.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime;
|
||||
using active_allocator.Services;
|
||||
|
||||
namespace active_allocator.Models.Transactions;
|
||||
|
||||
public class TransactionDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int OwnerId { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public DateTime UpdatedOn { get; set; }
|
||||
public string ExternalId { get; set; }
|
||||
public string Description { get; set; }
|
||||
public int DebitAccountId { get; set; }
|
||||
public int CreditAccountId { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public active_allocator.Entities.CurrencyType CurrencyType { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public bool IsPending { get; set; }
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
namespace active_allocator.Models.Users;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using active_allocator.Entities;
|
||||
|
||||
public class UpdateRequest
|
||||
public class UserUpdateRequest
|
||||
{
|
||||
public string Username { get; set; }
|
||||
public string FirstName { get; set; }
|
||||
@ -18,6 +20,7 @@ public class UpdateRequest
|
||||
// treat empty string as null for password fields to
|
||||
// make them optional in front end apps
|
||||
private string _password;
|
||||
|
||||
[MinLength(6)]
|
||||
public string Password
|
||||
{
|
@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using active_allocator.Services;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
@ -24,7 +25,15 @@ internal class Program
|
||||
});
|
||||
});
|
||||
|
||||
builder.Services.AddControllersWithViews();
|
||||
builder.Services.AddControllersWithViews().AddJsonOptions(x =>
|
||||
{
|
||||
// serialize enums as strings in api responses (e.g. Role)
|
||||
x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
||||
|
||||
// ignore omitted parameters on models to enable optional params (e.g. User update)
|
||||
x.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
|
||||
});
|
||||
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen(c =>
|
||||
{
|
||||
@ -40,6 +49,10 @@ internal class Program
|
||||
|
||||
builder.Services.AddScoped<IUserService, UserService>();
|
||||
builder.Services.AddScoped<IJwtUtils, JwtUtils>();
|
||||
builder.Services.AddScoped<IAccountService, AccountService>();
|
||||
builder.Services.AddScoped<ICurrencyTypeService, CurrencyTypeService>();
|
||||
builder.Services.AddScoped<IFireFlyService, FireFlyService>();
|
||||
builder.Services.AddScoped<ITransactionService, TransactionService>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
117
active-allocator/Services/AccountService.cs
Normal file
117
active-allocator/Services/AccountService.cs
Normal file
@ -0,0 +1,117 @@
|
||||
namespace active_allocator.Services;
|
||||
|
||||
using AutoMapper;
|
||||
using BCrypt.Net;
|
||||
using active_allocator.Entities;
|
||||
using active_allocator.Helpers;
|
||||
using active_allocator.Models.Accounts;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using Internal;
|
||||
|
||||
public interface IAccountService
|
||||
{
|
||||
IEnumerable<Account> GetAll();
|
||||
Account GetById(int id);
|
||||
void Create(AccountCreateRequest model);
|
||||
void Update(int id, AccountUpdateRequest model);
|
||||
void Delete(int id);
|
||||
}
|
||||
|
||||
public class AccountService : IAccountService
|
||||
{
|
||||
private DataContext _context;
|
||||
private readonly IMapper _mapper;
|
||||
private IUserService _userService;
|
||||
private ICurrencyTypeService _currencyTypeService;
|
||||
|
||||
public AccountService(
|
||||
DataContext context,
|
||||
IMapper mapper,
|
||||
IUserService userService,
|
||||
ICurrencyTypeService currencyTypeService)
|
||||
{
|
||||
_context = context;
|
||||
_mapper = mapper;
|
||||
_userService = userService;
|
||||
_currencyTypeService = currencyTypeService;
|
||||
}
|
||||
|
||||
public IEnumerable<Account> GetAll()
|
||||
{
|
||||
return _context.Accounts;
|
||||
}
|
||||
|
||||
public Account GetById(int id)
|
||||
{
|
||||
return getAccount(id);
|
||||
}
|
||||
|
||||
public void Create(AccountCreateRequest model)
|
||||
{
|
||||
// Check that account with same name or same external number doesn't exist
|
||||
IEnumerable<Account> accountsWithSameName = _context.Accounts.Where(a => a.Name.ToUpper() == model.Name.ToUpper());
|
||||
|
||||
if (accountsWithSameName.Count() > 0)
|
||||
throw new AppException("Account with name '" + model.Name + "' already exists");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(model.ExternalAccountNumber))
|
||||
{
|
||||
IEnumerable<Account> matches = _context.Accounts.Where(a => a.ExternalAccountNumber == model.ExternalAccountNumber);
|
||||
|
||||
if (matches.Count() > 0)
|
||||
throw new AppException("Account with external account number '" + model.ExternalAccountNumber + "' already exists under account named '" + matches.First().Name + "'");
|
||||
}
|
||||
|
||||
// map model to new account object
|
||||
//var account = _mapper.Map<Account>(model);
|
||||
|
||||
Account account = new Account {
|
||||
Name = model.Name,
|
||||
OwnerId = model.Owner,
|
||||
Owner = _userService.GetById(model.Owner),
|
||||
InitialBalance = Convert.ToDecimal(model.InitialBalance),
|
||||
Balance = Convert.ToDecimal(model.InitialBalance),
|
||||
LastActivity = DateTime.UtcNow,
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
CurrencyId = model.Currency,
|
||||
Currency = _currencyTypeService.GetById(model.Currency),
|
||||
ExternalAccountNumber = model.ExternalAccountNumber
|
||||
};
|
||||
|
||||
_context.Accounts.Add(account);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void Update(int id, AccountUpdateRequest model)
|
||||
{
|
||||
var account = getAccount(id);
|
||||
|
||||
// validate
|
||||
if (model.Name != account.Name && _context.Accounts.Any(x => x.Name == model.Name))
|
||||
throw new AppException("Account with the name '" + model.Name + "' already exists");
|
||||
|
||||
// copy model to account and save
|
||||
_mapper.Map(model, account);
|
||||
_context.Accounts.Update(account);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(int id)
|
||||
{
|
||||
var account = getAccount(id);
|
||||
_context.Accounts.Remove(account);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
// helper methods
|
||||
|
||||
private Account getAccount(int id)
|
||||
{
|
||||
var account = _context.Accounts.Find(id);
|
||||
if (account == null) throw new KeyNotFoundException("Account not found");
|
||||
return account;
|
||||
}
|
||||
}
|
94
active-allocator/Services/CurrencyTypeService.cs
Normal file
94
active-allocator/Services/CurrencyTypeService.cs
Normal file
@ -0,0 +1,94 @@
|
||||
namespace active_allocator.Services;
|
||||
|
||||
using AutoMapper;
|
||||
using BCrypt.Net;
|
||||
using active_allocator.Entities;
|
||||
using active_allocator.Helpers;
|
||||
using active_allocator.Models.CurrencyType;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public interface ICurrencyTypeService
|
||||
{
|
||||
IEnumerable<CurrencyType> GetAll();
|
||||
CurrencyType GetById(int id);
|
||||
void Create(CurrencyTypeCreateRequest model);
|
||||
//void Update(int id, AccountUpdateRequest model);
|
||||
void Delete(int id);
|
||||
}
|
||||
|
||||
public class CurrencyTypeService : ICurrencyTypeService
|
||||
{
|
||||
private DataContext _context;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public CurrencyTypeService(
|
||||
DataContext context,
|
||||
IMapper mapper)
|
||||
{
|
||||
_context = context;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public IEnumerable<CurrencyType> GetAll()
|
||||
{
|
||||
return _context.CurrencyTypes;
|
||||
}
|
||||
|
||||
public CurrencyType GetById(int id)
|
||||
{
|
||||
return getCurrencyType(id);
|
||||
}
|
||||
|
||||
public void Create(CurrencyTypeCreateRequest model)
|
||||
{
|
||||
// Check that CurrencyType with same code doesn't exist
|
||||
IEnumerable<CurrencyType> sameCode = _context.CurrencyTypes.Where(a => a.Code.ToUpper() == model.Code.ToUpper());
|
||||
|
||||
if (sameCode.Count() > 0)
|
||||
throw new AppException("CurrencyType with code '" + model.Code + "' already exists");
|
||||
|
||||
// Check that CurrencyType with same symbol doesn't exist
|
||||
IEnumerable<CurrencyType> sameSymbol = _context.CurrencyTypes.Where(a => a.Symbol.ToUpper() == model.Symbol.ToUpper());
|
||||
|
||||
if (sameSymbol.Count() > 0)
|
||||
throw new AppException("CurrencyType with symbol '" + model.Symbol + "' already exists");
|
||||
|
||||
// map model to new account object
|
||||
var currencyType = _mapper.Map<CurrencyType>(model);
|
||||
|
||||
_context.CurrencyTypes.Add(currencyType);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
/*public void Update(int id, AccountUpdateRequest model)
|
||||
{
|
||||
var account = getAccount(id);
|
||||
|
||||
// validate
|
||||
if (model.Name != account.Name && _context.Accounts.Any(x => x.Name == model.Name))
|
||||
throw new AppException("Account with the name '" + model.Name + "' already exists");
|
||||
|
||||
// copy model to account and save
|
||||
_mapper.Map(model, account);
|
||||
_context.Accounts.Update(account);
|
||||
_context.SaveChanges();
|
||||
}*/
|
||||
|
||||
public void Delete(int id)
|
||||
{
|
||||
var currencyType = getCurrencyType(id);
|
||||
_context.CurrencyTypes.Remove(currencyType);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
// helper methods
|
||||
|
||||
private CurrencyType getCurrencyType(int id)
|
||||
{
|
||||
var currencyType = _context.CurrencyTypes.Find(id);
|
||||
if (currencyType == null) throw new KeyNotFoundException("CurrencyType not found");
|
||||
return currencyType;
|
||||
}
|
||||
}
|
139
active-allocator/Services/FireFlyService.cs
Normal file
139
active-allocator/Services/FireFlyService.cs
Normal file
@ -0,0 +1,139 @@
|
||||
namespace active_allocator.Services;
|
||||
|
||||
using AutoMapper;
|
||||
using BCrypt.Net;
|
||||
using active_allocator.Entities;
|
||||
using active_allocator.Helpers;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using Newtonsoft.Json;
|
||||
using Internal;
|
||||
using active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
public interface IFireFlyService
|
||||
{
|
||||
Task<IEnumerable<Datum>> GetAll();/*
|
||||
Account GetById(int id);
|
||||
void Create(AccountCreateRequest model);
|
||||
void Update(int id, AccountUpdateRequest model);
|
||||
void Delete(int id);*/
|
||||
}
|
||||
|
||||
public class FireFlyService : IFireFlyService
|
||||
{
|
||||
private DataContext _context;
|
||||
private readonly IMapper _mapper;
|
||||
private string baseUrl = "http://10.0.10.21:8080/api/v1/";
|
||||
private string bearerToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiODc3ZTVlNzYyMDBiMTJiMDk2ZTQ5NjM2NWQyY2EwZjk5MmVjMzZkNGVjNmVjYjUzYTk4YzZjZTg2Y2I5N2JhMjNjODZjMDNlMDJiNDk3OWYiLCJpYXQiOjE2ODQ4NTgwODYuNjk0OTY4LCJuYmYiOjE2ODQ4NTgwODYuNjk0OTcxLCJleHAiOjE3MTY0ODA0ODYuNjI1MTA3LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.QbKdlv8h0Wqz-zd_hinX288SUWgiyEqDijHmO-6-JN2YN79GungzCddR169mjp9G-AIUykhQ3tOYKiQWSnreOLXZoWJDs6RX6MxqTZIvIFx-Fjt_5qaFt8D6pqm-LVs0j-c0xlW1BvGoZy-tHNnNbaH15vWuLN4sxsekbsfdcIq1JKsR5pYlI59SUdQzkISFjDCKqJaSCQM_lPAaYv9EEmf54yOy8hGHLQHdJmPyv-ngCar0KB5DKMimAof40FuQVMvYUueWxSej-NYp26ZXMRlRAU3A7qL2qVZA6R-Hh9wKkO8evyCrRoh3cQB1XaPMpJMN6E7m_7tsxHnOUNZ2fj0vW7LR4QKbgePhhpW6aXIrkH1_FkeMZn2MNrwoo1FuhEd3ij73K0-rbkikrKhW0G2hyqh0Lvf1HtU0kzWmOCNV9oqjHLm8fPAkcB1g8ngPcoc5ZdcEe1MF9ngJqwNvdQgqIsYr3SmWoY2G2ZVa7Fr3hn7-4D91DV5Pk_R52IfCPWqUvyPIoZfM6vGKuv4F9aGzcTotU69IJUr0-k780elzm1k7K2otYmskJe_xa4sW7E2-OYuFqD2TMBVp6j3rB6ZR5LCGZP9jETJsFis23JSzZpe0XAFf6SVi8BBOOoJxqyefZr-gdOdrZ6_5ffVKmVUbXzXQMEIC-GDz-2Vkbrs";
|
||||
|
||||
public FireFlyService(
|
||||
DataContext context,
|
||||
IMapper mapper)
|
||||
{
|
||||
_context = context;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Datum>> GetAll()
|
||||
{
|
||||
string endpointUrl = "transactions?page=";
|
||||
int totalPages = 1;
|
||||
List<Datum> transactions = new List<Datum>();
|
||||
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken);
|
||||
|
||||
for (int i = 1; i <= totalPages; i++)
|
||||
{
|
||||
using (var response = await httpClient.GetAsync(baseUrl + endpointUrl + i.ToString()))
|
||||
{
|
||||
string apiResponse = await response.Content.ReadAsStringAsync();
|
||||
Root payload = JsonConvert.DeserializeObject<Root>(apiResponse);
|
||||
|
||||
if (payload?.meta?.pagination != null)
|
||||
totalPages = payload.meta.pagination.total_pages;
|
||||
|
||||
transactions.AddRange(payload.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return transactions;
|
||||
}
|
||||
/*
|
||||
public Account GetById(int id)
|
||||
{
|
||||
return getAccount(id);
|
||||
}
|
||||
|
||||
public void Create(AccountCreateRequest model)
|
||||
{
|
||||
// Check that account with same name or same external number doesn't exist
|
||||
IEnumerable<Account> accountsWithSameName = _context.Accounts.Where(a => a.Name.ToUpper() == model.Name.ToUpper());
|
||||
|
||||
if (accountsWithSameName.Count() > 0)
|
||||
throw new AppException("Account with name '" + model.Name + "' already exists");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(model.ExternalAccountNumber))
|
||||
{
|
||||
IEnumerable<Account> matches = _context.Accounts.Where(a => a.ExternalAccountNumber == model.ExternalAccountNumber);
|
||||
|
||||
if (matches.Count() > 0)
|
||||
throw new AppException("Account with external account number '" + model.ExternalAccountNumber + "' already exists under account named '" + matches.First().Name + "'");
|
||||
}
|
||||
|
||||
// map model to new account object
|
||||
//var account = _mapper.Map<Account>(model);
|
||||
|
||||
Account account = new Account {
|
||||
Name = model.Name,
|
||||
OwnerId = model.Owner,
|
||||
Owner = _userService.GetById(model.Owner),
|
||||
InitialBalance = Convert.ToDecimal(model.InitialBalance),
|
||||
Balance = Convert.ToDecimal(model.InitialBalance),
|
||||
LastActivity = DateTime.UtcNow,
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
CurrencyId = model.Currency,
|
||||
Currency = _currencyTypeService.GetById(model.Currency),
|
||||
ExternalAccountNumber = model.ExternalAccountNumber
|
||||
};
|
||||
|
||||
_context.Accounts.Add(account);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void Update(int id, AccountUpdateRequest model)
|
||||
{
|
||||
var account = getAccount(id);
|
||||
|
||||
// validate
|
||||
if (model.Name != account.Name && _context.Accounts.Any(x => x.Name == model.Name))
|
||||
throw new AppException("Account with the name '" + model.Name + "' already exists");
|
||||
|
||||
// copy model to account and save
|
||||
_mapper.Map(model, account);
|
||||
_context.Accounts.Update(account);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(int id)
|
||||
{
|
||||
var account = getAccount(id);
|
||||
_context.Accounts.Remove(account);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
// helper methods
|
||||
|
||||
private Account getAccount(int id)
|
||||
{
|
||||
var account = _context.Accounts.Find(id);
|
||||
if (account == null) throw new KeyNotFoundException("Account not found");
|
||||
return account;
|
||||
}*/
|
||||
}
|
121
active-allocator/Services/TransactionService.cs
Normal file
121
active-allocator/Services/TransactionService.cs
Normal file
@ -0,0 +1,121 @@
|
||||
namespace active_allocator.Services;
|
||||
|
||||
using AutoMapper;
|
||||
using BCrypt.Net;
|
||||
using active_allocator.Entities;
|
||||
using active_allocator.Helpers;
|
||||
using active_allocator.Models.Transactions;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public interface ITransactionService
|
||||
{
|
||||
IEnumerable<Transaction> GetAll();
|
||||
Transaction GetById(int id);
|
||||
void Create(TransactionCreate model);
|
||||
//void Update(int id, AccountUpdateRequest model);
|
||||
void Delete(int id);
|
||||
}
|
||||
|
||||
public class TransactionService : ITransactionService
|
||||
{
|
||||
private DataContext _context;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public TransactionService(
|
||||
DataContext context,
|
||||
IMapper mapper)
|
||||
{
|
||||
_context = context;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public IEnumerable<Transaction> GetAll()
|
||||
{
|
||||
return _context.Transactions
|
||||
.Include(t => t.CurrencyType)
|
||||
.Include(t => t.DebitAccount)
|
||||
.Include(t => t.CreditAccount)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public Transaction GetById(int id)
|
||||
{
|
||||
return getTransaction(id);
|
||||
}
|
||||
|
||||
public void Create(TransactionCreate model)
|
||||
{
|
||||
Transaction transaction = new Transaction {
|
||||
Owner = _context.Users.Find(model.Owner),
|
||||
Description = model.Description,
|
||||
Date = model.Date,
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
UpdatedOn = DateTime.UtcNow,
|
||||
ExternalId = model.ExternalId,
|
||||
DebitAccount = model.DebitAccount == null ? null : _context.Accounts.Find(model.DebitAccount.Value),
|
||||
CreditAccount = model.CreditAccount == null ? null : _context.Accounts.Find(model.CreditAccount.Value),
|
||||
Amount = Convert.ToDecimal(model.Amount),
|
||||
CurrencyType = _context.CurrencyTypes.Find(model.CurrencyType),
|
||||
Notes = model.Notes,
|
||||
IsPending = model.IsPending,
|
||||
};
|
||||
|
||||
// Transaction Duplication Check
|
||||
if (transaction.ExternalId != null && _context.Transactions.Any(x => x.ExternalId == transaction.ExternalId))
|
||||
throw new AppException("Transaction with the external ID '" + transaction.ExternalId + "' already exists");
|
||||
|
||||
if (_context.Transactions.Any(x =>
|
||||
x.Owner == transaction.Owner
|
||||
&& x.Description == transaction.Description
|
||||
&& x.Date == transaction.Date
|
||||
&& x.DebitAccount == transaction.DebitAccount
|
||||
&& x.CreditAccount == transaction.CreditAccount
|
||||
&& x.Amount == transaction.Amount))
|
||||
{
|
||||
throw new AppException("Transaction with the same fields already exists");
|
||||
}
|
||||
|
||||
// map model to new account object
|
||||
//var account = _mapper.Map<Account>(model);
|
||||
|
||||
_context.Transactions.Add(transaction);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
/*public void Update(int id, AccountUpdateRequest model)
|
||||
{
|
||||
var account = getOuterTransaction(id);
|
||||
|
||||
// validate
|
||||
if (model.Name != account.Name && _context.Accounts.Any(x => x.Name == model.Name))
|
||||
throw new AppException("Account with the name '" + model.Name + "' already exists");
|
||||
|
||||
// copy model to account and save
|
||||
_mapper.Map(model, account);
|
||||
_context.Accounts.Update(account);
|
||||
_context.SaveChanges();
|
||||
}*/
|
||||
|
||||
public void Delete(int id)
|
||||
{
|
||||
var transaction = getTransaction(id);
|
||||
_context.Transactions.Remove(transaction);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
private Transaction getTransaction(int id)
|
||||
{
|
||||
var transaction = _context.Transactions.Find(id);
|
||||
|
||||
_context.Entry(transaction).Reference(t => t.CurrencyType).Load();
|
||||
_context.Entry(transaction).Reference(t => t.DebitAccount).Load();
|
||||
_context.Entry(transaction).Reference(t => t.CreditAccount).Load();
|
||||
|
||||
if (transaction == null) throw new KeyNotFoundException("Transaction not found");
|
||||
return transaction;
|
||||
}
|
||||
}
|
@ -6,6 +6,9 @@ using active_allocator.Authorization;
|
||||
using active_allocator.Entities;
|
||||
using active_allocator.Helpers;
|
||||
using active_allocator.Models.Users;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public interface IUserService
|
||||
{
|
||||
@ -13,7 +16,7 @@ public interface IUserService
|
||||
void Register(RegisterRequest model);
|
||||
IEnumerable<User> GetAll();
|
||||
User GetById(int id);
|
||||
void Update(int id, UpdateRequest model);
|
||||
void Update(int id, UserUpdateRequest model);
|
||||
void Delete(int id);
|
||||
}
|
||||
|
||||
@ -22,15 +25,18 @@ public class UserService : IUserService
|
||||
private DataContext _context;
|
||||
private IJwtUtils _jwtUtils;
|
||||
private readonly IMapper _mapper;
|
||||
private IFireFlyService _fireFlyService;
|
||||
|
||||
public UserService(
|
||||
DataContext context,
|
||||
IMapper mapper,
|
||||
IJwtUtils jwtUtils)
|
||||
IJwtUtils jwtUtils,
|
||||
IFireFlyService fireFlyService)
|
||||
{
|
||||
_context = context;
|
||||
_mapper = mapper;
|
||||
_jwtUtils = jwtUtils;
|
||||
_fireFlyService = fireFlyService;
|
||||
}
|
||||
|
||||
public AuthenticateResponse Authenticate(AuthenticateRequest model)
|
||||
@ -70,6 +76,18 @@ public class UserService : IUserService
|
||||
|
||||
public IEnumerable<User> GetAll()
|
||||
{
|
||||
/*foreach (Models.FireFlyTransactions.Datum item in _fireFlyService.GetAll())
|
||||
{
|
||||
Console.WriteLine($"Id: {item.id}");
|
||||
|
||||
foreach (Models.FireFlyTransactions.Transaction tr in item.attributes.transactions)
|
||||
{
|
||||
Console.WriteLine($"\t{Convert.ToDecimal(tr.amount)} Description: {tr.description}");
|
||||
}
|
||||
|
||||
Console.WriteLine("");
|
||||
}
|
||||
*/
|
||||
return _context.Users;
|
||||
}
|
||||
|
||||
@ -78,7 +96,7 @@ public class UserService : IUserService
|
||||
return getUser(id);
|
||||
}
|
||||
|
||||
public void Update(int id, UpdateRequest model)
|
||||
public void Update(int id, UserUpdateRequest model)
|
||||
{
|
||||
var user = getUser(id);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user