parent
bd35017f4a
commit
744bfa8114
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
@ -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>
|
||||
);
|
||||
}
|
@ -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" });
|
||||
}
|
||||
}
|
@ -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" });
|
||||
}
|
||||
}
|
@ -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" });
|
||||
}*/
|
||||
}
|
@ -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" });
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
namespace active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
public class Meta
|
||||
{
|
||||
public Pagination pagination { get; set; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
namespace active_allocator.Models.FireFlyTransactions;
|
||||
|
||||
public class _0
|
||||
{
|
||||
public string rel { get; set; }
|
||||
public string uri { get; set; }
|
||||
}
|
@ -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
|
||||
}
|
||||
]
|
||||
}*/
|
@ -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; }
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}*/
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in new issue