Compare commits
2 Commits
585bb26773
...
74585ad027
Author | SHA1 | Date | |
---|---|---|---|
74585ad027 | |||
9c46586b1e |
@ -16,6 +16,10 @@ import { Routes } from "./components/services/Routes";
|
||||
|
||||
import Transactions from "./components/transactions/Transactions";
|
||||
import CreateTransaction from "./components/transactions/CreateTransaction";
|
||||
import DeleteTransaction from "./components/transactions/DeleteTransaction";
|
||||
import AccountDashboard from "./components/accounts/AccountDashboard";
|
||||
import CreateEnvelope from "./components/envelope/CreateEnvelope";
|
||||
import Envelopes from "./components/envelope/Envelopes";
|
||||
|
||||
const AppRoutes = [
|
||||
{
|
||||
@ -51,15 +55,15 @@ const AppRoutes = [
|
||||
element: <Users />
|
||||
},
|
||||
{
|
||||
path: Routes.USER_CREATE,
|
||||
path: Routes.USERS_CREATE,
|
||||
element: <CreateUser />
|
||||
},
|
||||
{
|
||||
path: Routes.USER_EDIT,
|
||||
path: Routes.USERS_EDIT,
|
||||
element: <UpdateUser />
|
||||
},
|
||||
{
|
||||
path: Routes.USER_DELETE,
|
||||
path: Routes.USERS_DELETE,
|
||||
element: <DeleteUser />
|
||||
},
|
||||
{
|
||||
@ -67,15 +71,19 @@ const AppRoutes = [
|
||||
element: <Accounts />
|
||||
},
|
||||
{
|
||||
path: Routes.ACCOUNT_CREATE,
|
||||
path: Routes.ACCOUNTS_DASHBOARD,
|
||||
element: <AccountDashboard />
|
||||
},
|
||||
{
|
||||
path: Routes.ACCOUNTS_CREATE,
|
||||
element: <CreateAccount />
|
||||
},
|
||||
{
|
||||
path: Routes.ACCOUNT_EDIT,
|
||||
path: Routes.ACCOUNTS_EDIT,
|
||||
element: <UpdateAccount />
|
||||
},
|
||||
{
|
||||
path: Routes.ACCOUNT_DELETE,
|
||||
path: Routes.ACCOUNTS_DELETE,
|
||||
element: <DeleteAccount />
|
||||
},
|
||||
{
|
||||
@ -83,16 +91,32 @@ const AppRoutes = [
|
||||
element: <Transactions />
|
||||
},
|
||||
{
|
||||
path: Routes.TRANSACTION_CREATE,
|
||||
path: Routes.TRANSACTIONS_CREATE,
|
||||
element: <CreateTransaction />
|
||||
},
|
||||
{
|
||||
path: Routes.TRANSACTION_EDIT,
|
||||
path: Routes.TRANSACTIONS_EDIT,
|
||||
element: <UpdateAccount />
|
||||
},
|
||||
{
|
||||
path: Routes.TRANSACTION_DELETE,
|
||||
element: <DeleteAccount />
|
||||
path: Routes.TRANSACTIONS_DELETE,
|
||||
element: <DeleteTransaction />
|
||||
},
|
||||
{
|
||||
path: Routes.ENVELOPES,
|
||||
element: <Envelopes />
|
||||
},
|
||||
{
|
||||
path: Routes.ENVELOPES_CREATE,
|
||||
element: <CreateEnvelope />
|
||||
},
|
||||
{
|
||||
path: Routes.ENVELOPES_EDIT,
|
||||
element: <UpdateAccount />
|
||||
},
|
||||
{
|
||||
path: Routes.ENVELOPES_DELETE,
|
||||
element: <DeleteTransaction />
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -53,12 +53,12 @@ export class NavMenu extends Component {
|
||||
<NavItem>
|
||||
<NavLink tag={Link} className="text-dark" to={Routes.ACCOUNTS}>Accounts</NavLink>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink tag={Link} className="text-dark" to={Routes.ENVELOPES}>Envelopes</NavLink>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink tag={Link} className="text-dark" to={Routes.TRANSACTIONS}>Transactions</NavLink>
|
||||
</NavItem>
|
||||
{/*<NavItem>
|
||||
<NavLink tag={Link} className="text-dark" to={Routes.LOGIN}>{sessionStorage.getItem('firstName')}</NavLink>
|
||||
</NavItem>*/}
|
||||
<NavItem>
|
||||
<NavLink tag={Link} className="text-dark" to={Routes.LOGOUT}>Logout</NavLink>
|
||||
</NavItem>
|
||||
|
@ -0,0 +1,262 @@
|
||||
import { EndPoints, getData } from "../services/AccessAPI";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { Routes } from "../services/Routes";
|
||||
import RowButton from "../ui-elements/table/RowButton";
|
||||
import DataFormatter, { RenderType } from "../ui-elements/table/DataFormatter";
|
||||
|
||||
export default function AccountDashboard() {
|
||||
const search = useLocation().search;
|
||||
const id = new URLSearchParams(search).get('id')
|
||||
|
||||
useEffect(() => {
|
||||
getData(EndPoints.ACCOUNTS + "/" + id).then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
setAccount({
|
||||
name: result.name,
|
||||
lastActivity: result.lastActivity,
|
||||
createdOn: result.createdOn,
|
||||
balance: result.balance,
|
||||
initialBalance: result.initialBalance,
|
||||
currencyId: result.currencyId,
|
||||
externalAccountNumber: result.externalAccountNumber,
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
getAllTransactionsData();
|
||||
getAllAccountsData();
|
||||
getAccountEnvelopeData();
|
||||
}, [id])
|
||||
|
||||
let navigate = useNavigate();
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const [transactions, setTransactions] = useState([]);
|
||||
const [accounts, setAccounts] = useState([]);
|
||||
const [envelopes, setEnvelopes] = useState([]);
|
||||
|
||||
const [account, setAccount] = useState({
|
||||
name: '',
|
||||
lastActivity: null,
|
||||
createdOn: null,
|
||||
balance: 0,
|
||||
initialBalance: 0,
|
||||
currencyId: 0,
|
||||
externalAccountNumber: '',
|
||||
loading: true
|
||||
});
|
||||
|
||||
//const [users, setUsers] = useState(null);
|
||||
|
||||
function onTransactionEdit(id){
|
||||
let query = "?id=" + id
|
||||
navigate(Routes.TRANSACTIONS_EDIT + query);
|
||||
}
|
||||
|
||||
function onTransactionDelete(id){
|
||||
let query = "?id=" + id
|
||||
navigate(Routes.TRANSACTIONS_DELETE + query);
|
||||
}
|
||||
|
||||
function getAllTransactionsData() {
|
||||
getData(EndPoints.TRANSACTIONS).then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
console.log()
|
||||
setTransactions(result);
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/*function getAllUsersData() {
|
||||
getData(EndPoints.USERS).then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
setUsers(result);
|
||||
}
|
||||
}
|
||||
);
|
||||
}*/
|
||||
|
||||
function getAllAccountsData() {
|
||||
getData(EndPoints.ACCOUNTS).then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
setAccounts(result);
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getAccountEnvelopeData() {
|
||||
getData(EndPoints.ENVELOPES).then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
setEnvelopes(result);
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function findAccountName(id) {
|
||||
let name = accounts?.find(x => x.id === id)?.name;
|
||||
console.log("Id: " + id + ", Name: " + name);
|
||||
return name;
|
||||
}
|
||||
|
||||
/*function findUserName(id) {
|
||||
return users?.find(x => x.id)?.username;
|
||||
}*/
|
||||
|
||||
function renderTransactionsTable() {
|
||||
return (
|
||||
<table className="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Amount</th>
|
||||
<th>Description</th>
|
||||
<th>Date</th>
|
||||
<th>External ID</th>
|
||||
<th>Debit Acc</th>
|
||||
<th>Credit Acc</th>
|
||||
<th>Pending</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
transactions.map(transaction => (
|
||||
<tr key={transaction.id}>
|
||||
<td><DataFormatter data={transaction.amount} renderType={RenderType.MoneyUnsigned}/></td>
|
||||
<td><DataFormatter data={transaction.description} /></td>
|
||||
<td><DataFormatter data={transaction.date} /></td>
|
||||
<td><DataFormatter data={transaction.externalId} /></td>
|
||||
<td><DataFormatter data={findAccountName(transaction.debitAccountId)} /></td>
|
||||
<td><DataFormatter data={findAccountName(transaction.creditAccountId)} /></td>
|
||||
<td><DataFormatter data={transaction.isPending ? "True" : "False"} /></td>
|
||||
<td>
|
||||
<RowButton className="btn btn-sm btn-outline-primary" text="Edit" onClick={() => onTransactionEdit(transaction.id)} />
|
||||
|
||||
<RowButton className="btn btn-sm btn-outline-danger" text="Delete" onClick={() => onTransactionDelete(transaction.id)} />
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
function renderEnvelopesTable() {
|
||||
return (
|
||||
<table className="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Balance</th>
|
||||
<th>Status</th>
|
||||
<th>Persistant</th>
|
||||
<th>Priority</th>
|
||||
<th>Period</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
envelopes.map(env => (
|
||||
<tr key={env.id}>
|
||||
<td><DataFormatter data={env.name} /></td>
|
||||
<td><DataFormatter data={env.balance} renderType={RenderType.MoneyUnsigned}/></td>
|
||||
<td><DataFormatter data={env.enabled ? "Enabled" : "Disabled"} /></td>
|
||||
<td><DataFormatter data={env.isPersistant ? "True" : "False"} /></td>
|
||||
<td><DataFormatter data={env.priority} /></td>
|
||||
<td><DataFormatter data={env.period} /></td>
|
||||
<td>
|
||||
<RowButton
|
||||
className="btn btn-sm btn-outline-primary"
|
||||
text="Edit"
|
||||
onClick={() => navigate(Routes.ENVELOPES_EDIT + "?id=" + env.id)} />
|
||||
|
||||
<RowButton
|
||||
className="btn btn-sm btn-outline-danger"
|
||||
text="Delete"
|
||||
onClick={() => navigate(Routes.ENVELOPES_DELETE + "?id=" + env.id)} />
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
let transactionsContent = loading ? (
|
||||
<p>
|
||||
<em>Loading...</em>
|
||||
</p>
|
||||
) : (renderTransactionsTable())
|
||||
|
||||
let envelopesContent = loading ? (
|
||||
<p>
|
||||
<em>Loading...</em>
|
||||
</p>
|
||||
) : (renderEnvelopesTable())
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>{account.name + " "}
|
||||
<RowButton
|
||||
className="btn btn-sm btn-outline-primary"
|
||||
text="Edit"
|
||||
onClick={() => navigate(Routes.ACCOUNTS_EDIT + "?id=" + id)} />
|
||||
|
||||
<RowButton
|
||||
className="btn btn-sm btn-outline-danger"
|
||||
text="Delete"
|
||||
onClick={() => navigate(Routes.ACCOUNTS_DELETE + "?id=" + id)} />
|
||||
</h2>
|
||||
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-6">
|
||||
<h3><DataFormatter data={account.balance} renderType={RenderType.MoneyUnsigned} /></h3>
|
||||
<h5><DataFormatter data={"Last activity: " + account.lastActivity} /></h5>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<h4><DataFormatter data={account.externalAccountNumber} /></h4>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div className="row">
|
||||
<div className="col-md-6">
|
||||
<div className="row">
|
||||
<div className="text-center">
|
||||
<h3 className="">Envelopes <button onClick={() => navigate(Routes.ENVELOPES_CREATE + "?id=" + id)} className="btn btn-sm btn-outline-primary">+</button></h3>
|
||||
</div>
|
||||
</div>
|
||||
{envelopesContent}
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<div className="row">
|
||||
<div className="text-center">
|
||||
<h3 className="">Transactions <button onClick={() => navigate(Routes.TRANSACTIONS_CREATE)} className="btn btn-sm btn-outline-primary">+</button></h3>
|
||||
</div>
|
||||
</div>
|
||||
{transactionsContent}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { EndPoints, getData, putData } from "../services/AccessAPI";
|
||||
import { RouterProvider, useNavigate } from "react-router-dom";
|
||||
import { EndPoints, getData } from "../services/AccessAPI";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
import { Routes } from "../services/Routes";
|
||||
@ -22,17 +22,22 @@ export default function Accounts() {
|
||||
const [users, setUsers] = useState(null);
|
||||
|
||||
function onAccountCreate() {
|
||||
navigate(Routes.ACCOUNT_CREATE);
|
||||
navigate(Routes.ACCOUNTS_CREATE);
|
||||
}
|
||||
|
||||
function onAccountDashboard(id) {
|
||||
let query = "?id=" + id
|
||||
navigate(Routes.ACCOUNTS_DASHBOARD + query);
|
||||
}
|
||||
|
||||
function onAccountEdit(id) {
|
||||
let query = "?id=" + id
|
||||
navigate(Routes.ACCOUNT_EDIT + query);
|
||||
navigate(Routes.ACCOUNTS_EDIT + query);
|
||||
}
|
||||
|
||||
function onAccountDelete(id) {
|
||||
let query = "?id=" + id
|
||||
navigate(Routes.ACCOUNT_DELETE + query);
|
||||
navigate(Routes.ACCOUNTS_DELETE + query);
|
||||
}
|
||||
|
||||
function getAllAccountsData() {
|
||||
@ -91,7 +96,7 @@ export default function Accounts() {
|
||||
{
|
||||
accounts.map(account => (
|
||||
<tr key={account.id}>
|
||||
<td><DataFormatter data={account.name} /></td>
|
||||
<td><button onClick={() => onAccountDashboard(account.id)}><DataFormatter data={account.name} /></button></td>
|
||||
<td><DataFormatter data={findUserName(account.ownerId)} /></td>
|
||||
<td><DataFormatter data={account.balance} renderType={RenderType.MoneyUnsigned} /></td>
|
||||
<td><DataFormatter data={account.externalAccountNumber} /></td>
|
||||
|
@ -0,0 +1,147 @@
|
||||
import SessionManager from "../auth/SessionManager";
|
||||
import { EndPoints, postData, getData } from "../services/AccessAPI";
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Routes } from "../services/Routes";
|
||||
import Select from 'react-select'
|
||||
|
||||
export default function CreateEnvelope() {
|
||||
const search = useLocation().search;
|
||||
const id = new URLSearchParams(search).get('id')
|
||||
const [showAccounts, setShowAccounts] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
getAllAccountsData();
|
||||
if (id !== undefined && id !== null) {
|
||||
setShowAccounts();
|
||||
setAccount(Number(id));
|
||||
}
|
||||
|
||||
}, [id])
|
||||
|
||||
let navigate = useNavigate();
|
||||
|
||||
const [accounts, setAccounts] = useState([]);
|
||||
|
||||
const [name, setName] = useState("");
|
||||
const [account, setAccount] = useState(0);
|
||||
const [initBalance, setInitBalance] = useState(0);
|
||||
const [enabled, setEnabled] = useState(true);
|
||||
const [isPersistant, setIsPersistant] = useState(true);
|
||||
const [priority, setPriority] = useState(0);
|
||||
const [extNum, setExtNum] = useState("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
function onSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
let accountObj = {
|
||||
name: name,
|
||||
account: account,
|
||||
initialBalance: initBalance.toString(),
|
||||
enabled: enabled,
|
||||
isPersistant: isPersistant,
|
||||
priority: Number(priority),
|
||||
externalAccountNumber: extNum
|
||||
}
|
||||
|
||||
postData(EndPoints.ENVELOPES, accountObj).then((result) => {
|
||||
setLoading(false);
|
||||
let responseJson = result;
|
||||
if (responseJson) {
|
||||
navigate(Routes.ENVELOPES);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getAllAccountsData() {
|
||||
getData(EndPoints.ACCOUNTS).then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
setAccounts(result.map(a => {
|
||||
return {
|
||||
value: a.id,
|
||||
label: a.name
|
||||
}
|
||||
}));
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function onClickBack(e){
|
||||
e.preventDefault();
|
||||
|
||||
if(SessionManager.getToken()){
|
||||
navigate(Routes.ENVELOPES);
|
||||
}else{
|
||||
navigate(Routes.LOGIN);
|
||||
}
|
||||
}
|
||||
|
||||
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">Envelope Name: </label>
|
||||
<input className="form-control" type="text" name="name" value={name} onChange={(e) => setName(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
{showAccounts && <div className="form-group">
|
||||
<label className="control-label">Account: </label>
|
||||
<Select onChange={(e) => setAccount(e.value)} name="account" options={accounts} isSearchable="true" isLoading={loading} />
|
||||
</div>}
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Initial Balance: </label>
|
||||
<input className="form-control" type="text" name="initBalance" value={initBalance} onChange={(e) => setInitBalance(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">Priority: </label>
|
||||
<input className="form-control" type="text" name="priority" value={priority} onChange={(e) => setPriority(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-check">
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="enabled"
|
||||
checked={enabled}
|
||||
onChange={(e) => setEnabled(!enabled)}
|
||||
className="form-check-input"
|
||||
/>
|
||||
Enabled
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="form-check">
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="isPersistant"
|
||||
checked={isPersistant}
|
||||
onChange={(e) => setIsPersistant(!isPersistant)}
|
||||
className="form-check-input"
|
||||
/>
|
||||
Is Persistant
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="control-label">External Account Number: </label>
|
||||
<input className="form-control" type="text" name="extNum" value={extNum} onChange={(e) => setExtNum(e.target.value)}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<input type="submit" value="Create Envelope" className="btn btn-primary"></input>
|
||||
<input type="button" value="Back" onClick={onClickBack} className="btn btn-primary"></input>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
111
active-allocator/ClientApp/src/components/envelope/Envelopes.js
Normal file
111
active-allocator/ClientApp/src/components/envelope/Envelopes.js
Normal file
@ -0,0 +1,111 @@
|
||||
import { EndPoints, getData } from "../services/AccessAPI";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
import { Routes } from "../services/Routes";
|
||||
import RowButton from "../ui-elements/table/RowButton";
|
||||
import DataFormatter, { RenderType } from "../ui-elements/table/DataFormatter";
|
||||
|
||||
export default function Envelopes() {
|
||||
useEffect(() => {;
|
||||
getAllAccountsData();
|
||||
getAllEnvelopesData();
|
||||
setLoading(false);
|
||||
}, [])
|
||||
|
||||
let navigate = useNavigate();
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [envelopes, setEnvelopes] = useState([]);
|
||||
const [accounts, setAccounts] = useState([]);
|
||||
|
||||
function getAllEnvelopesData() {
|
||||
getData(EndPoints.ENVELOPES).then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
setEnvelopes(result);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getAllAccountsData() {
|
||||
getData(EndPoints.ACCOUNTS).then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
setAccounts(result);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function findAccountName(id) {
|
||||
let name = accounts?.find(x => x.id === id)?.name;
|
||||
console.log("Id: " + id + ", Name: " + name);
|
||||
return name;
|
||||
}
|
||||
|
||||
function renderAllEnvelopesTable() {
|
||||
return (
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
<table className="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Account</th>
|
||||
<th>Balance</th>
|
||||
<th>Initial Balance</th>
|
||||
<th>Status</th>
|
||||
<th>Persistant</th>
|
||||
<th>Priority</th>
|
||||
<th>Period</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
envelopes.map(env => (
|
||||
<tr key={env.id}>
|
||||
<td><DataFormatter data={env.name} /></td>
|
||||
<td><DataFormatter data={findAccountName(env.accountId)} /></td>
|
||||
<td><DataFormatter data={env.balance} renderType={RenderType.MoneyUnsigned}/></td>
|
||||
<td><DataFormatter data={env.initialBalance} renderType={RenderType.MoneyUnsigned}/></td>
|
||||
<td><DataFormatter data={env.enabled ? "Enabled" : "Disabled"} /></td>
|
||||
<td><DataFormatter data={env.isPersistant ? "True" : "False"} /></td>
|
||||
<td><DataFormatter data={env.priority} /></td>
|
||||
<td><DataFormatter data={env.period} /></td>
|
||||
<td>
|
||||
<RowButton className="btn btn-sm btn-outline-primary" text="Edit" onClick={() => navigate(Routes.ENVELOPES_EDIT)} />
|
||||
|
||||
<RowButton className="btn btn-sm btn-outline-danger" text="Delete" onClick={() => navigate(Routes.ENVELOPES_DELETE)} />
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let content = loading ? (
|
||||
<p>
|
||||
<em>Loading...</em>
|
||||
</p>
|
||||
) : (
|
||||
renderAllEnvelopesTable()
|
||||
)
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3>List of Envelopes</h3>
|
||||
<button onClick={() => navigate(Routes.ENVELOPES_CREATE)} className="btn btn-primary">Create new envelope</button>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -9,6 +9,7 @@ export const EndPoints = {
|
||||
ACCOUNTS_REFRESHBALANCE: "Accounts/RefreshBalance",
|
||||
CURRENCYTYPES: "CurrencyTypes",
|
||||
TRANSACTIONS: "Transactions",
|
||||
ENVELOPES: "Envelopes",
|
||||
}
|
||||
|
||||
export function getData(endPoint) {
|
||||
|
@ -6,15 +6,20 @@ export const Routes = {
|
||||
LOGOUT: "/logout",
|
||||
REGISTER: "/register",
|
||||
USERS: "/admin/users",
|
||||
USER_CREATE: "/admin/user/create",
|
||||
USER_EDIT: "/admin/user/edit",
|
||||
USER_DELETE: "/admin/user/delete",
|
||||
USERS_CREATE: "/admin/users/create",
|
||||
USERS_EDIT: "/admin/users/edit",
|
||||
USERS_DELETE: "/admin/users/delete",
|
||||
ACCOUNTS: "/admin/accounts",
|
||||
ACCOUNT_CREATE: "/admin/account/create",
|
||||
ACCOUNT_EDIT: "/admin/account/edit",
|
||||
ACCOUNT_DELETE: "/admin/account/delete",
|
||||
ACCOUNTS_DASHBOARD: "/admin/accounts/dashboard",
|
||||
ACCOUNTS_CREATE: "/admin/accounts/create",
|
||||
ACCOUNTS_EDIT: "/admin/accounts/edit",
|
||||
ACCOUNTS_DELETE: "/admin/accounts/delete",
|
||||
TRANSACTIONS: "/admin/transactions",
|
||||
TRANSACTION_CREATE: "/admin/transaction/create",
|
||||
TRANSACTION_EDIT: "/admin/transaction/edit",
|
||||
TRANSACTION_DELETE: "/admin/transaction/delete",
|
||||
TRANSACTIONS_CREATE: "/admin/transactions/create",
|
||||
TRANSACTIONS_EDIT: "/admin/transactions/edit",
|
||||
TRANSACTIONS_DELETE: "/admin/transactions/delete",
|
||||
ENVELOPES: "/admin/envelopes",
|
||||
ENVELOPES_CREATE: "/admin/envelopes/create",
|
||||
ENVELOPES_EDIT: "/admin/envelopes/edit",
|
||||
ENVELOPES_DELETE: "/admin/envelopes/delete",
|
||||
};
|
@ -90,18 +90,12 @@ export default function CreateTransaction() {
|
||||
navigate(Routes.LOGIN);
|
||||
}
|
||||
}
|
||||
const options = [
|
||||
{ value: 'chocolate', label: 'Chocolate' },
|
||||
{ value: 'strawberry', label: 'Strawberry' },
|
||||
{ value: 'vanilla', label: 'Vanilla' }
|
||||
]
|
||||
|
||||
/*
|
||||
{
|
||||
"date": "2023-12-23T21:44:31.930Z",
|
||||
"isPending": true
|
||||
}
|
||||
*/
|
||||
/*
|
||||
{
|
||||
"date": "2023-12-23T21:44:31.930Z",
|
||||
"isPending": true
|
||||
}
|
||||
*/
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-md-4">
|
||||
|
@ -0,0 +1,139 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { EndPoints, deleteData, getData } from "../services/AccessAPI";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { Routes } from "../services/Routes";
|
||||
import DataFormatter, { RenderType } from "../ui-elements/table/DataFormatter";
|
||||
|
||||
export default function DeleteTransaction() {
|
||||
const search = useLocation().search;
|
||||
const id = new URLSearchParams(search).get('id')
|
||||
|
||||
useEffect(() => {
|
||||
getData(EndPoints.TRANSACTIONS + "/" + id).then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
setState({
|
||||
amount: result.amount,
|
||||
description: result.description,
|
||||
date: result.date,
|
||||
externalId: result.externalId,
|
||||
debitAccountId: result.debitAccountId,
|
||||
creditAccountId: result.creditAccountId,
|
||||
isPending: result.isPending,
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}, [id])
|
||||
|
||||
let navigate = useNavigate();
|
||||
|
||||
const [state, setState] = useState({
|
||||
amount: 0,
|
||||
description: '',
|
||||
date: '',
|
||||
externalId: '',
|
||||
debitAccountId: 0,
|
||||
creditAccountId: 0,
|
||||
isPending: false,
|
||||
loading: true
|
||||
});
|
||||
|
||||
function onCancel() {
|
||||
navigate(Routes.TRANSACTIONS);
|
||||
}
|
||||
|
||||
function onConfirmation(e) {
|
||||
e.preventDefault();
|
||||
|
||||
deleteData(EndPoints.TRANSACTIONS + "/" + id).then((result) => {
|
||||
let responseJson = result;
|
||||
if (responseJson) {
|
||||
navigate(Routes.TRANSACTIONS);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>::Delete Transaction::</h2>
|
||||
<h3>Are you sure you want to delete this?</h3>
|
||||
<div>
|
||||
<h4>Transaction Information</h4>
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Transaction Description:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
{state.description}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Amount:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
<DataFormatter data={state.amount} renderType={RenderType.MoneyUnsigned}/>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Date:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
{state.date}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Debit Account:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
{state.debitAccountId}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Credit Account:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
{state.creditAccountId}
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
Is Pending:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
<DataFormatter data={state.isPending ? "True" : "False"} />
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl className="row">
|
||||
<dt className="col-sm-2">
|
||||
External Transaction Number:
|
||||
</dt>
|
||||
<dd className="col-sm-10">
|
||||
{state.externalId}
|
||||
</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>
|
||||
)
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { EndPoints, getData } from "../services/AccessAPI";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
import { Routes } from "../services/Routes";
|
||||
@ -21,17 +21,17 @@ export default function Transactions() {
|
||||
const [accounts, setAccounts] = useState([]);
|
||||
|
||||
function onTransactionCreate() {
|
||||
navigate(Routes.TRANSACTION_CREATE);
|
||||
navigate(Routes.TRANSACTIONS_CREATE);
|
||||
}
|
||||
|
||||
function onTransactionEdit(id){
|
||||
let query = "?id=" + id
|
||||
navigate(Routes.TRANSACTION_EDIT + query);
|
||||
navigate(Routes.TRANSACTIONS_EDIT + query);
|
||||
}
|
||||
|
||||
function onTransactionDelete(id){
|
||||
let query = "?id=" + id
|
||||
navigate(Routes.TRANSACTION_DELETE + query);
|
||||
navigate(Routes.TRANSACTIONS_DELETE + query);
|
||||
}
|
||||
|
||||
function getAllTransactionsData() {
|
||||
@ -63,7 +63,7 @@ export default function Transactions() {
|
||||
}
|
||||
|
||||
function findAccountName(id) {
|
||||
let name = accounts?.find(x => x.id == id)?.name;
|
||||
let name = accounts?.find(x => x.id === id)?.name;
|
||||
console.log("Id: " + id + ", Name: " + name);
|
||||
return name;
|
||||
}
|
||||
|
@ -18,17 +18,17 @@ export default function Users() {
|
||||
});
|
||||
|
||||
function onUserCreate() {
|
||||
navigate(Routes.USER_CREATE);
|
||||
navigate(Routes.USERS_CREATE);
|
||||
}
|
||||
|
||||
function onUserEdit(id){
|
||||
let query = "?id=" + id
|
||||
navigate(Routes.USER_EDIT + query);
|
||||
navigate(Routes.USERS_EDIT + query);
|
||||
}
|
||||
|
||||
function onUserDelete(id){
|
||||
let query = "?id=" + id
|
||||
navigate(Routes.USER_DELETE + query);
|
||||
navigate(Routes.USERS_DELETE + query);
|
||||
}
|
||||
|
||||
function getAllUsersData() {
|
||||
@ -45,7 +45,7 @@ export default function Users() {
|
||||
);
|
||||
}
|
||||
|
||||
function renderAllUsersTable(users) {
|
||||
/*function renderAllUsersTable(users) {
|
||||
return (
|
||||
<table className="table table-striped">
|
||||
<thead>
|
||||
@ -73,7 +73,7 @@ export default function Users() {
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
}*/
|
||||
|
||||
function renderBootstrapTable(users) {
|
||||
return (
|
||||
|
77
active-allocator/Controllers/EnvelopeController.cs
Normal file
77
active-allocator/Controllers/EnvelopeController.cs
Normal file
@ -0,0 +1,77 @@
|
||||
namespace active_allocator.Controllers;
|
||||
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using active_allocator.Models.Envelopes;
|
||||
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 EnvelopesController : ControllerBase
|
||||
{
|
||||
private IEnvelopeService _envelopeService;
|
||||
private IMapper _mapper;
|
||||
private readonly AppSettings _appSettings;
|
||||
|
||||
public EnvelopesController(
|
||||
IEnvelopeService envelopeService,
|
||||
IMapper mapper,
|
||||
IOptions<AppSettings> appSettings)
|
||||
{
|
||||
_envelopeService = envelopeService;
|
||||
_mapper = mapper;
|
||||
_appSettings = appSettings.Value;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult GetAll(int? accountId = null)
|
||||
{
|
||||
List<EnvelopeDTO> envelopeDtos = new List<EnvelopeDTO>();
|
||||
|
||||
foreach (Envelope env in _envelopeService.GetAll(accountId))
|
||||
envelopeDtos.Add(_mapper.Map<Envelope, EnvelopeDTO>(env));
|
||||
|
||||
return Ok(envelopeDtos);
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public IActionResult GetById(int id)
|
||||
{
|
||||
Envelope envelope = _envelopeService.GetById(id);
|
||||
return Ok(_mapper.Map<Envelope, EnvelopeDTO>(envelope));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Create([FromBody]EnvelopeCreateRequest model)
|
||||
{
|
||||
_envelopeService.Create(model);
|
||||
return Ok(new { message = "envelope created" });
|
||||
}
|
||||
|
||||
/*[HttpPut("{id}")]
|
||||
public IActionResult Update(int id, [FromBody]EnvelopeUpdateRequest model)
|
||||
{
|
||||
_envelopeService.Update(id, model);
|
||||
return Ok(new { message = "envelope updated" });
|
||||
}*/
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public IActionResult Delete(int id)
|
||||
{
|
||||
_envelopeService.Delete(id);
|
||||
return Ok(new { message = "envelope deleted" });
|
||||
}
|
||||
|
||||
/*[HttpGet("RefreshBalance/{id}")]
|
||||
public IActionResult RefreshBalance(int id)
|
||||
{
|
||||
Envelope envelope = _envelopeService.RefreshEnvelopeBalance(id);
|
||||
return Ok(_mapper.Map<Envelope, EnvelopeDTO>(envelope));
|
||||
}*/
|
||||
}
|
@ -15,7 +15,7 @@ public class Account
|
||||
public int CurrencyId { get; set; }
|
||||
public CurrencyType Currency { get; set; }
|
||||
public string ExternalAccountNumber { get; set; }
|
||||
public ICollection<Alloc> Allocs { get; set; }
|
||||
public ICollection<Envelope> Envelopes { get; set; }
|
||||
//public ICollection<Transaction> Transactions { get; set; }
|
||||
//public Institution institution { get; set; }
|
||||
}
|
@ -3,16 +3,16 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace active_allocator.Entities;
|
||||
|
||||
public class Alloc
|
||||
public class Envelope
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public Account Account { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public TimeSpan Period { get; set; }
|
||||
public Account Account { get; set; }
|
||||
public bool PersistanceEnabled { get; set; }
|
||||
public ICollection<Operation> Operations { get; set; }
|
||||
public decimal CurrentBalance { get; set; }
|
||||
public DateTime LastTriggeredOn { get; set; }
|
||||
public decimal LastBalanceAdded { get; set; }
|
||||
public bool IsPersistant { get; set; }
|
||||
public int Priority { get; set; }
|
||||
public decimal Balance { get; set; }
|
||||
public decimal InitialBalance { get; set; }
|
||||
public DateTime? LastTriggeredOn { get; set; }
|
||||
}
|
@ -4,6 +4,7 @@ using AutoMapper;
|
||||
using active_allocator.Entities;
|
||||
using active_allocator.Models.Users;
|
||||
using active_allocator.Models.Accounts;
|
||||
using active_allocator.Models.Envelopes;
|
||||
using active_allocator.Models.CurrencyType;
|
||||
using active_allocator.Services;
|
||||
using System.Runtime.Serialization;
|
||||
@ -76,6 +77,19 @@ public class AutoMapperProfile : Profile
|
||||
}
|
||||
));
|
||||
|
||||
// Envelope -> EnvelopeDTO
|
||||
CreateMap<Envelope, EnvelopeDTO>()
|
||||
.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))
|
||||
|
@ -60,7 +60,7 @@ public class DataContext : DbContext
|
||||
|
||||
public DbSet<User> Users { get; set; }
|
||||
public DbSet<Account> Accounts { get; set; }
|
||||
public DbSet<Alloc> Allocs { get; set; }
|
||||
public DbSet<Envelope> Envelopes { get; set; }
|
||||
public DbSet<CurrencyType> CurrencyTypes { get; set; }
|
||||
public DbSet<Operation> Operations { get; set; }
|
||||
public DbSet<Transaction> Transactions { get; set; }
|
||||
|
351
active-allocator/Migrations/20231226233044_EnvelopeEntity.Designer.cs
generated
Normal file
351
active-allocator/Migrations/20231226233044_EnvelopeEntity.Designer.cs
generated
Normal file
@ -0,0 +1,351 @@
|
||||
// <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("20231226233044_EnvelopeEntity")]
|
||||
partial class EnvelopeEntity
|
||||
{
|
||||
/// <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.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.Envelope", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Balance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal>("InitialBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<bool>("IsPersistant")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime?>("LastTriggeredOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<TimeSpan>("Period")
|
||||
.HasColumnType("interval");
|
||||
|
||||
b.Property<int>("Priority")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.ToTable("Envelopes");
|
||||
});
|
||||
|
||||
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<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.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.Envelope", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Account", "Account")
|
||||
.WithMany("Envelopes")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
});
|
||||
|
||||
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("Envelopes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.User", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
119
active-allocator/Migrations/20231226233044_EnvelopeEntity.cs
Normal file
119
active-allocator/Migrations/20231226233044_EnvelopeEntity.cs
Normal file
@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace active_allocator.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class EnvelopeEntity : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Operations_Allocs_AllocId",
|
||||
table: "Operations");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Allocs");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Operations_AllocId",
|
||||
table: "Operations");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AllocId",
|
||||
table: "Operations");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Envelopes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
AccountId = table.Column<int>(type: "integer", nullable: false),
|
||||
Enabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
Period = table.Column<TimeSpan>(type: "interval", nullable: false),
|
||||
IsPersistant = table.Column<bool>(type: "boolean", nullable: false),
|
||||
Priority = table.Column<int>(type: "integer", nullable: false),
|
||||
Balance = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
InitialBalance = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
LastTriggeredOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Envelopes", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Envelopes_Accounts_AccountId",
|
||||
column: x => x.AccountId,
|
||||
principalTable: "Accounts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Envelopes_AccountId",
|
||||
table: "Envelopes",
|
||||
column: "AccountId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Envelopes");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "AllocId",
|
||||
table: "Operations",
|
||||
type: "integer",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Allocs",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
AccountId = table.Column<int>(type: "integer", nullable: false),
|
||||
CurrentBalance = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
Enabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
LastBalanceAdded = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
LastTriggeredOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Period = table.Column<TimeSpan>(type: "interval", nullable: false),
|
||||
PersistanceEnabled = table.Column<bool>(type: "boolean", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Allocs", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Allocs_Accounts_AccountId",
|
||||
column: x => x.AccountId,
|
||||
principalTable: "Accounts",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Operations_AllocId",
|
||||
table: "Operations",
|
||||
column: "AllocId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Allocs_AccountId",
|
||||
table: "Allocs",
|
||||
column: "AccountId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Operations_Allocs_AllocId",
|
||||
table: "Operations",
|
||||
column: "AllocId",
|
||||
principalTable: "Allocs",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
}
|
||||
}
|
@ -65,46 +65,6 @@ namespace active_allocator.Migrations
|
||||
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")
|
||||
@ -129,6 +89,49 @@ namespace active_allocator.Migrations
|
||||
b.ToTable("CurrencyTypes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Envelope", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("AccountId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Balance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal>("InitialBalance")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<bool>("IsPersistant")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime?>("LastTriggeredOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<TimeSpan>("Period")
|
||||
.HasColumnType("interval");
|
||||
|
||||
b.Property<int>("Priority")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.ToTable("Envelopes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Operation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -140,9 +143,6 @@ namespace active_allocator.Migrations
|
||||
b.Property<decimal>("AbsoluteValue")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<int?>("AllocId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
@ -169,8 +169,6 @@ namespace active_allocator.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AllocId");
|
||||
|
||||
b.ToTable("Operations");
|
||||
});
|
||||
|
||||
@ -289,10 +287,10 @@ namespace active_allocator.Migrations
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
modelBuilder.Entity("active_allocator.Entities.Envelope", b =>
|
||||
{
|
||||
b.HasOne("active_allocator.Entities.Account", "Account")
|
||||
.WithMany("Allocs")
|
||||
.WithMany("Envelopes")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
@ -300,13 +298,6 @@ namespace active_allocator.Migrations
|
||||
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")
|
||||
@ -344,12 +335,7 @@ namespace active_allocator.Migrations
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Account", b =>
|
||||
{
|
||||
b.Navigation("Allocs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.Alloc", b =>
|
||||
{
|
||||
b.Navigation("Operations");
|
||||
b.Navigation("Envelopes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("active_allocator.Entities.User", b =>
|
||||
|
@ -1,4 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using active_allocator.Entities;
|
||||
|
||||
namespace active_allocator.Models.Accounts;
|
||||
|
||||
@ -13,4 +16,5 @@ public class AccountDTO
|
||||
public decimal InitialBalance { get; set; }
|
||||
public int CurrencyId { get; set; }
|
||||
public string ExternalAccountNumber { get; set; }
|
||||
public List<Envelope> Envelopes { get; set; }
|
||||
}
|
16
active-allocator/Models/Envelopes/EnvelopeCreateRequest.cs
Normal file
16
active-allocator/Models/Envelopes/EnvelopeCreateRequest.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace active_allocator.Models.Envelopes;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.InteropServices;
|
||||
using active_allocator.Entities;
|
||||
|
||||
public class EnvelopeCreateRequest
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Account { get; set; }
|
||||
public string InitialBalance { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool IsPersistant { get; set; }
|
||||
public int Priority { get; set; }
|
||||
public string ExternalAccountNumber { get; set; }
|
||||
}
|
20
active-allocator/Models/Envelopes/EnvelopeDTO.cs
Normal file
20
active-allocator/Models/Envelopes/EnvelopeDTO.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using active_allocator.Entities;
|
||||
|
||||
namespace active_allocator.Models.Envelopes;
|
||||
|
||||
public class EnvelopeDTO
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int AccountId { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public TimeSpan Period { get; set; }
|
||||
public bool IsPersistant { get; set; }
|
||||
public int Priority { get; set; }
|
||||
public decimal Balance { get; set; }
|
||||
public decimal InitialBalance { get; set; }
|
||||
public DateTime? LastTriggeredOn { get; set; }
|
||||
}
|
@ -52,6 +52,7 @@ internal class Program
|
||||
builder.Services.AddScoped<IAccountService, AccountService>();
|
||||
builder.Services.AddScoped<ICurrencyTypeService, CurrencyTypeService>();
|
||||
builder.Services.AddScoped<ITransactionService, TransactionService>();
|
||||
builder.Services.AddScoped<IEnvelopeService, EnvelopeService>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
150
active-allocator/Services/EnvelopeService.cs
Normal file
150
active-allocator/Services/EnvelopeService.cs
Normal file
@ -0,0 +1,150 @@
|
||||
namespace active_allocator.Services;
|
||||
|
||||
using AutoMapper;
|
||||
using BCrypt.Net;
|
||||
using active_allocator.Entities;
|
||||
using active_allocator.Helpers;
|
||||
using active_allocator.Models.Envelopes;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using Internal;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public interface IEnvelopeService
|
||||
{
|
||||
IEnumerable<Envelope> GetAll(int? accountId = null);
|
||||
Envelope GetById(int envelopeId);
|
||||
void Create(EnvelopeCreateRequest model);
|
||||
//void Update(int envelopeId, EnvelopeUpdateRequest model);
|
||||
//Envelope RefreshEnvelopeBalance(int envelopeId);
|
||||
void Delete(int envelopeId);
|
||||
}
|
||||
|
||||
public class EnvelopeService : IEnvelopeService
|
||||
{
|
||||
private DataContext _context;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public EnvelopeService(
|
||||
DataContext context,
|
||||
IMapper mapper)
|
||||
{
|
||||
_context = context;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public IEnumerable<Envelope> GetAll(int? accountId = null)
|
||||
{
|
||||
if (accountId != null)
|
||||
return _context.Envelopes
|
||||
.Include(e => e.Account)
|
||||
.Where(e => e.Account.Id == accountId.Value);
|
||||
|
||||
return _context.Envelopes
|
||||
.Include(e => e.Account);
|
||||
}
|
||||
|
||||
public Envelope GetById(int envelopeId)
|
||||
{
|
||||
return getEnvelope(envelopeId);
|
||||
}
|
||||
|
||||
public void Create(EnvelopeCreateRequest model)
|
||||
{
|
||||
Account account = _context.Accounts.Find(model.Account);
|
||||
if (account == null)
|
||||
throw new AppException("Could not create envelope. Account with id '" + model.Account + "' not found.");
|
||||
|
||||
// Check that envelope with same name or same external number doesn't exist
|
||||
IEnumerable<Envelope> envelopesWithSameName = _context.Envelopes
|
||||
.Include(e => e.Account)
|
||||
.Where(e =>
|
||||
e.Name.ToUpper() == model.Name.ToUpper()
|
||||
&& e.Account.Id == model.Account);
|
||||
|
||||
if (envelopesWithSameName.Count() > 0)
|
||||
throw new AppException("Envelope with name '" + model.Name + "' already exists for account '" + account.Name + "'.");
|
||||
|
||||
// map model to new envelope object
|
||||
//var envelope = _mapper.Map<Envelope>(model);
|
||||
|
||||
Envelope envelope = new Envelope {
|
||||
Name = model.Name,
|
||||
Account = account,
|
||||
InitialBalance = Convert.ToDecimal(model.InitialBalance),
|
||||
Balance = Convert.ToDecimal(model.InitialBalance),
|
||||
Enabled = model.Enabled,
|
||||
IsPersistant = model.IsPersistant,
|
||||
Priority = model.Priority,
|
||||
LastTriggeredOn = null
|
||||
};
|
||||
|
||||
_context.Envelopes.Add(envelope);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
/*
|
||||
public void Update(int envelopeId, EnvelopeUpdateRequest model)
|
||||
{
|
||||
Envelope envelope = getEnvelope(envelopeId);
|
||||
|
||||
// validate
|
||||
if (model.Name != envelope.Name && _context.Envelopes.Any(x => x.Name == model.Name))
|
||||
throw new AppException("Envelope with the name '" + model.Name + "' already exists");
|
||||
|
||||
// Name
|
||||
if (!string.IsNullOrWhiteSpace(model.Name))
|
||||
envelope.Name = model.Name;
|
||||
|
||||
// Owner
|
||||
if (model.Owner.HasValue)
|
||||
{
|
||||
envelope.OwnerId = model.Owner.Value;
|
||||
envelope.Owner = _userService.GetById(model.Owner.Value);
|
||||
}
|
||||
|
||||
// Initial Balance
|
||||
if (!string.IsNullOrWhiteSpace(model.InitialBalance))
|
||||
envelope.InitialBalance = Convert.ToDecimal(model.InitialBalance);
|
||||
|
||||
// CurrencyType
|
||||
if (model.Currency.HasValue)
|
||||
{
|
||||
envelope.CurrencyId = model.Currency.Value;
|
||||
envelope.Currency = _context.CurrencyTypes.Find(model.Currency.Value);
|
||||
}
|
||||
|
||||
// External Envelope Number
|
||||
if (!string.IsNullOrWhiteSpace(model.ExternalEnvelopeNumber))
|
||||
envelope.ExternalEnvelopeNumber = model.ExternalEnvelopeNumber;
|
||||
|
||||
// copy model to envelope and save
|
||||
//_mapper.Map(model, envelope);
|
||||
_context.Envelopes.Update(envelope);
|
||||
_context.SaveChanges();
|
||||
_context.RecalculateEnvelopeBalance(envelopeId);
|
||||
}*/
|
||||
/*
|
||||
public Envelope RefreshEnvelopeBalance(int envelopeId)
|
||||
{
|
||||
_context.RecalculateEnvelopeBalance(envelopeId);
|
||||
return _context.Envelopes.Find(envelopeId);
|
||||
}*/
|
||||
|
||||
public void Delete(int envelopeId)
|
||||
{
|
||||
var envelope = getEnvelope(envelopeId);
|
||||
_context.Envelopes.Remove(envelope);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
// helper methods
|
||||
|
||||
private Envelope getEnvelope(int id)
|
||||
{
|
||||
var envelope = _context.Envelopes.Find(id);
|
||||
if (envelope == null) throw new KeyNotFoundException("Envelope not found");
|
||||
return envelope;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user