This commit is contained in:
2023-07-31 08:50:05 +03:00
parent cca943f37d
commit c5d9ae7b93
49 changed files with 546 additions and 398 deletions
@@ -18,4 +18,9 @@ public class AccountAccountCategoryRepository : AppRepository<AccountAccountCate
{ {
return RemoveBase(accountAccountCategory) > 0; return RemoveBase(accountAccountCategory) > 0;
} }
public bool Add(AccountAccountCategory accountAccountCategory)
{
return AddBase(accountAccountCategory) > 0;
}
} }
@@ -94,7 +94,7 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
.ThenInclude(x => x.Category) .ThenInclude(x => x.Category)
.Include(x => x.AccessRights)! .Include(x => x.AccessRights)!
.ThenInclude(x => x.User) .ThenInclude(x => x.User)
.Include(x => x.Motions)! //.Include(x => x.Motions)!
.FirstOrDefault(x => x.Id == id && x.AccessRights!.Any(r => r.UserId == userId)); .FirstOrDefault(x => x.Id == id && x.AccessRights!.Any(r => r.UserId == userId));
} }
@@ -6,4 +6,5 @@ public interface IAccountAccountCategoryRepository
{ {
List<AccountAccountCategory> Get(Guid userId, Guid accountId, Guid categoryId); List<AccountAccountCategory> Get(Guid userId, Guid accountId, Guid categoryId);
bool Remove(AccountAccountCategory accountAccountCategory); bool Remove(AccountAccountCategory accountAccountCategory);
bool Add(AccountAccountCategory accountAccountCategory);
} }
+17 -20
View File
@@ -5,6 +5,7 @@ using DbContext;
public class RepositoryBase<TEntity> where TEntity : class public class RepositoryBase<TEntity> where TEntity : class
{ {
//TODO: Rename
protected readonly AppDbContext _context; protected readonly AppDbContext _context;
protected RepositoryBase( protected RepositoryBase(
@@ -49,41 +50,37 @@ public class RepositoryBase<TEntity> where TEntity : class
return _context.Set<TEntity>().Find(id); return _context.Set<TEntity>().Find(id);
} }
protected async Task<int> AddBaseAsync(TEntity entity)
{
//await _context.Set<TEntity>().AddAsync(entity);
await _context.AddAsync(entity);
return await SaveChangesAsync();
}
protected int AddBase(TEntity entity) protected int AddBase(TEntity entity)
{ {
//_context.Set<TEntity>().Add(entity); //_context.Add(entity);
_context.Add(entity); _context.Entry(entity).State = EntityState.Added;
return SaveChanges();
var result = SaveChanges();
_context.Entry(entity).State = EntityState.Detached;
return result;
} }
protected int RemoveBase(TEntity entity) protected int RemoveBase(TEntity entity)
{ {
_context.Set<TEntity>().Remove(entity); _context.Set<TEntity>().Remove(entity);
_context.Entry(entity).State = EntityState.Deleted; _context.Entry(entity).State = EntityState.Deleted;
return SaveChanges(); var result = SaveChanges();
}
protected async Task<int> UpdateBaseAsync(TEntity entity) _context.Entry(entity).State = EntityState.Detached;
{ return result;
_context.Attach(entity);
_context.Entry(entity).State = EntityState.Modified;
return await SaveChangesAsync();
} }
protected int UpdateBase(TEntity entity) protected int UpdateBase(TEntity entity)
{ {
_context.Attach(entity); //_context.Attach(entity);
_context.Entry(entity).State = EntityState.Modified; _context.Entry(entity).State = EntityState.Modified;
return SaveChanges(); var result = SaveChanges();
_context.Entry(entity).State = EntityState.Detached;
return result;
} }
} }
@@ -4,9 +4,7 @@ using Models.Users;
public interface IUserExternalRepository public interface IUserExternalRepository
{ {
Task<int> AddUserExternalAsync(UserExternal external);
int AddUserExternal(UserExternal external); int AddUserExternal(UserExternal external);
Task<int> AddUserExternalsAsync(IEnumerable<UserExternal> claims);
Task<List<UserExternal>> GetUserExternalsByUserIdAsync(Guid userId); Task<List<UserExternal>> GetUserExternalsByUserIdAsync(Guid userId);
@@ -10,6 +10,6 @@ public interface IUserRepository
Task<User?> GetByUserUserNameAsync(string userName); Task<User?> GetByUserUserNameAsync(string userName);
User? GetByUserUserName(string userName); User? GetByUserUserName(string userName);
Task<int> AddUserAsync(User user); int AddUser(User user);
Task<int> UpdateUserAsync(User user); int UpdateUser(User user);
} }
@@ -6,11 +6,6 @@ using Microsoft.EntityFrameworkCore;
public class UserExternalRepository : AppRepository<UserExternal>, IUserExternalRepository public class UserExternalRepository : AppRepository<UserExternal>, IUserExternalRepository
{ {
public async Task<int> AddUserExternalAsync(UserExternal userExternal)
{
return await AddBaseAsync(userExternal);
}
public int AddUserExternal(UserExternal userExternal) public int AddUserExternal(UserExternal userExternal)
{ {
return AddBase(userExternal); return AddBase(userExternal);
@@ -26,13 +26,13 @@ public class UserRepository : AppRepository<User>, IUserRepository
return _context.Users.FirstOrDefault(x => x.UserName == userName); return _context.Users.FirstOrDefault(x => x.UserName == userName);
} }
public async Task<int> AddUserAsync(User user) public int AddUser(User user)
{ {
return await AddBaseAsync(user); return AddBase(user);
} }
public async Task<int> UpdateUserAsync(User user) public int UpdateUser(User user)
{ {
return await UpdateBaseAsync(user); return UpdateBase(user);
} }
} }
@@ -37,6 +37,13 @@ public class AppDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
throw new NotSupportedException($"No such provider: [{provider}]"); throw new NotSupportedException($"No such provider: [{provider}]");
} }
#if DEBUG
builder.EnableSensitiveDataLogging(true);
builder.EnableDetailedErrors(true);
#endif
var db = new AppDbContext(providerEnum, builder.Options); var db = new AppDbContext(providerEnum, builder.Options);
db.ChangeTracker.AutoDetectChangesEnabled = false; db.ChangeTracker.AutoDetectChangesEnabled = false;
db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
+2 -2
View File
@@ -60,7 +60,7 @@ public class RepositoryInitializer
/// </summary> /// </summary>
private static void UpdateCurrentRates(AppDbContext dbContext) private static void UpdateCurrentRates(AppDbContext dbContext)
{ {
var lastrates = dbContext.CurrencyRates var lastRates = dbContext.CurrencyRates
.Include(x => x.Currency) .Include(x => x.Currency)
.GroupBy(x => new .GroupBy(x => new
{ {
@@ -71,7 +71,7 @@ public class RepositoryInitializer
var currencies = dbContext.Currencies.ToList(); var currencies = dbContext.Currencies.ToList();
foreach (var currency in currencies) foreach (var currency in currencies)
{ {
var rate = lastrates.FirstOrDefault(x => x.CurrencyId == currency.Id); var rate = lastRates.FirstOrDefault(x => x.CurrencyId == currency.Id);
if (rate != null) if (rate != null)
{ {
currency.CurrentRateId = rate.Id; currency.CurrentRateId = rate.Id;
@@ -2,5 +2,5 @@ export interface ItemCategoryModel {
id?: string, id?: string,
name?: string, name?: string,
allowDelete: boolean, allowDelete: boolean,
isInternal: boolean, internal: boolean,
} }
@@ -15,7 +15,7 @@
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="text-inside"> <div class="text-inside">
<mat-checkbox class="example-margin" formControlName="isInternal">Is internal motion</mat-checkbox> <mat-checkbox class="example-margin" formControlName="internal">Is internal motion</mat-checkbox>
</div> </div>
</div> </div>
</div> </div>
@@ -39,11 +39,10 @@ export class SettingsItemCategoryEditComponent {
this.category.name, this.category.name,
[Validators.required], [Validators.required],
], ],
isInternal: [ internal: [
this.category.isInternal, this.category?.internal ?? false,
], ],
}); });
console.log(this.editForm.value);
} }
closeDialog(): void { closeDialog(): void {
@@ -59,6 +59,8 @@ export class SettingsItemEditComponent {
} }
onSubmitClick() { onSubmitClick() {
console.log(this.item);
console.log(this.editForm.value);
if (this.editForm.valid) { if (this.editForm.valid) {
this.errorMessage = undefined; this.errorMessage = undefined;
this.httpClient this.httpClient
@@ -27,7 +27,7 @@
<tr *ngFor="let item of categories"> <tr *ngFor="let item of categories">
<td>{{item.name}}</td> <td>{{item.name}}</td>
<td> <td>
<mat-icon *ngIf="item.isInternal">done</mat-icon> <mat-icon *ngIf="item.internal">done</mat-icon>
</td> </td>
<td> <td>
<button class="btn-space" (click)="edit(item)" mat-raised-button color="primary"> <button class="btn-space" (click)="edit(item)" mat-raised-button color="primary">
+30 -30
View File
@@ -1,20 +1,19 @@
namespace MyOffice.Services.Account namespace MyOffice.Services.Account
{ {
using AutoMapper; using AutoMapper;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using Identity;
using Core; using Core;
using Core.Extensions; using Core.Extensions;
using Core.Helpers;
using Data.Models.Accounts; using Data.Models.Accounts;
using Data.Models.Items;
using Data.Repositories.Account; using Data.Repositories.Account;
using Data.Repositories.Currency; using Data.Repositories.Currency;
using Data.Repositories.Item; using Data.Repositories.Item;
using Domain;
using Item; using Item;
using Item.Domain; using Item.Domain;
using Microsoft.Extensions.Logging;
using MyOffice.Services.Account.Domain;
using System.Collections.Generic;
using Identity;
public class AccountService public class AccountService
{ {
@@ -84,15 +83,19 @@
return result.Set(_mapper.Map<AccountCategoryDto>(category)); return result.Set(_mapper.Map<AccountCategoryDto>(category));
} }
public Exec<AccountCategoryDto, GeneralExecStatus> CategoryAdd(Guid userId, AccountCategory category) public Exec<AccountCategoryDto, GeneralExecStatus> CategoryAdd(Guid userId, AccountCategoryDto input)
{ {
if (category == null) if (input == null)
throw new ArgumentNullException(nameof(category)); throw new ArgumentNullException(nameof(input));
var result = new Exec<AccountCategoryDto, GeneralExecStatus>(GeneralExecStatus.success); var result = new Exec<AccountCategoryDto, GeneralExecStatus>(GeneralExecStatus.success);
category.Id = Guid.NewGuid(); var category = new AccountCategory
category.UserId = userId; {
Id = Guid.NewGuid(),
UserId = userId,
Name = input.Name,
};
if (!_accountCategoryRepository.Add(category)) if (!_accountCategoryRepository.Add(category))
{ {
@@ -102,10 +105,10 @@
return result.Set(_mapper.Map<AccountCategoryDto>(category)); return result.Set(_mapper.Map<AccountCategoryDto>(category));
} }
public Exec<AccountCategoryDto, GeneralExecStatus> CategoryUpdate(Guid userId, Guid id, AccountCategory category) public Exec<AccountCategoryDto, GeneralExecStatus> CategoryUpdate(Guid userId, Guid id, AccountCategoryDto input)
{ {
if (category == null) if (input == null)
throw new ArgumentNullException(nameof(category)); throw new ArgumentNullException(nameof(input));
var result = new Exec<AccountCategoryDto, GeneralExecStatus>(GeneralExecStatus.success); var result = new Exec<AccountCategoryDto, GeneralExecStatus>(GeneralExecStatus.success);
@@ -115,7 +118,7 @@
return result.Set(GeneralExecStatus.not_found); return result.Set(GeneralExecStatus.not_found);
} }
exists.Name = category.Name; exists.Name = input.Name;
if (!_accountCategoryRepository.Update(exists)) if (!_accountCategoryRepository.Update(exists))
{ {
@@ -300,14 +303,11 @@
if (category != null && account.Categories!.All(x => x.CategoryId != category.Id)) if (category != null && account.Categories!.All(x => x.CategoryId != category.Id))
{ {
account.Categories = new List<AccountAccountCategory> _accountAccountCategoryRepository.Add(new AccountAccountCategory
{ {
new() AccountId = account.Id,
{ CategoryId = category.Id,
AccountId = account.Id, });
CategoryId = category.Id,
}
};
} }
if (!_accountRepository.Update(account)) if (!_accountRepository.Update(account))
@@ -346,7 +346,7 @@
return result.Set(categories); return result.Set(categories);
} }
public Exec<List<Motion>, MotionAddStatus> MotionAdd( public Exec<List<MotionDto>, MotionAddStatus> MotionAdd(
Guid userId, Guid userId,
Guid accountId, Guid accountId,
MotionAddUpdate motion MotionAddUpdate motion
@@ -357,7 +357,7 @@
if (motion.Item == null) if (motion.Item == null)
throw new ArgumentNullException(nameof(motion.Item)); throw new ArgumentNullException(nameof(motion.Item));
var result = new Exec<List<Motion>, MotionAddStatus>(MotionAddStatus.success); var result = new Exec<List<MotionDto>, MotionAddStatus>(MotionAddStatus.success);
var account = _accountRepository.Get(userId, accountId); var account = _accountRepository.Get(userId, accountId);
if (account == null) if (account == null)
@@ -388,8 +388,8 @@
return result.Set(MotionAddStatus.failure); return result.Set(MotionAddStatus.failure);
} }
result.Set(new List<Motion>()); result.Set(new List<MotionDto>());
result.Result!.Add(motionDb); result.Result!.Add(_mapper.Map<MotionDto>(motionDb));
if (motion.AccountId.IsPresent() && motion.AmountBalancing != 0) if (motion.AccountId.IsPresent() && motion.AmountBalancing != 0)
{ {
@@ -419,7 +419,7 @@
if (_motionRepository.Add(motionBalancing)) if (_motionRepository.Add(motionBalancing))
{ {
result.Result!.Add(motionBalancing); result.Result!.Add(_mapper.Map<MotionDto>(motionBalancing));
} }
} }
} }
@@ -429,7 +429,7 @@
return result; return result;
} }
public Exec<Motion, MotionUpdateStatus> MotionUpdate( public Exec<MotionDto, MotionUpdateStatus> MotionUpdate(
Guid userId, Guid userId,
Guid accountId, Guid accountId,
Guid motionId, Guid motionId,
@@ -441,7 +441,7 @@
if (motion.Item == null) if (motion.Item == null)
throw new ArgumentNullException(nameof(motion.Item)); throw new ArgumentNullException(nameof(motion.Item));
var result = new Exec<Motion, MotionUpdateStatus>(MotionUpdateStatus.success); var result = new Exec<MotionDto, MotionUpdateStatus>(MotionUpdateStatus.success);
var exists = _motionRepository.Get(userId, motionId); var exists = _motionRepository.Get(userId, motionId);
if (exists == null || exists.AccountId != accountId) if (exists == null || exists.AccountId != accountId)
@@ -467,7 +467,7 @@
} }
return result.Set(exists); return result.Set(_mapper.Map<MotionDto>(exists));
} }
public Exec<List<Motion>, GeneralExecStatus> GetMotions( public Exec<List<Motion>, GeneralExecStatus> GetMotions(
@@ -0,0 +1,14 @@
namespace MyOffice.Services.Account.Domain;
using MyOffice.Data.Models.Users;
public class ItemCategoryDto
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public User User { get; set; } = null!;
public string Name { get; set; } = null!;
public List<ItemDto> Items { get; set; } = null!;
public bool IsInternal { get; set; }
}
@@ -0,0 +1,13 @@
namespace MyOffice.Services.Account.Domain;
using MyOffice.Data.Models.Items;
public class ItemDto
{
public Guid Id { get; set; }
public string? Name { get; set; }
public bool AllowDelete { get; set; }
public Guid CategoryId { get; set; }
public ItemCategoryDto? Category { get; set; }
}
@@ -0,0 +1,16 @@
namespace MyOffice.Services.Account.Domain;
public class MotionDto
{
public Guid Id { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime DateTime { get; set; }
public Guid AccountId { get; set; }
public AccountDto Account { get; set; } = null!;
public int ItemId { get; set; }
public ItemDto Item { get; set; } = null!;
public string? Description { get; set; }
public decimal AmountPlus { get; set; }
public decimal AmountMinus { get; set; }
public DateTime? DeletedOn { get; set; }
}
+54 -34
View File
@@ -1,71 +1,85 @@
namespace MyOffice.Services.Currency; namespace MyOffice.Services.Currency;
using AutoMapper;
using Core; using Core;
using Core.Extensions; using Core.Extensions;
using Data.Models.Currencies; using Data.Models.Currencies;
using Data.Repositories.Currency; using Data.Repositories.Currency;
using MyOffice.Services.Currency.Domain; using Domain;
public class CurrencyService public class CurrencyService
{ {
private readonly ICurrencyGlobalRepository _currencyGlobalRepository; private readonly ICurrencyGlobalRepository _currencyGlobalRepository;
private readonly ICurrencyRepository _currencyRepository; private readonly ICurrencyRepository _currencyRepository;
private readonly ICurrencyRateRepository _currencyRateRepository; private readonly ICurrencyRateRepository _currencyRateRepository;
private readonly IMapper _mapper;
public CurrencyService( public CurrencyService(
ICurrencyGlobalRepository currencyGlobalRepository, ICurrencyGlobalRepository currencyGlobalRepository,
ICurrencyRepository currencyRepository, ICurrencyRepository currencyRepository,
ICurrencyRateRepository currencyRateRepository ICurrencyRateRepository currencyRateRepository,
IMapper mapper
) )
{ {
_currencyGlobalRepository = currencyGlobalRepository; _currencyGlobalRepository = currencyGlobalRepository;
_currencyRepository = currencyRepository; _currencyRepository = currencyRepository;
_currencyRateRepository = currencyRateRepository; _currencyRateRepository = currencyRateRepository;
_mapper = mapper;
} }
public List<CurrencyGlobal> GetGlobalAll() public List<CurrencyGlobalDto> GetGlobalAll()
{ {
return _currencyGlobalRepository.GetAll(); return _mapper.Map<List<CurrencyGlobalDto>>(_currencyGlobalRepository.GetAll());
} }
public List<Currency> GetAll(Guid userId) public List<CurrencyDto> GetAll(Guid userId)
{ {
return _currencyRepository.GetAll(userId); return _mapper.Map<List<CurrencyDto>>(_currencyRepository.GetAll(userId));
} }
public Dictionary<Currency, CurrencyRate?> GetAllWithRates(Guid userId) public List<CurrencyWithRateDto> GetAllWithRates(Guid userId)
{ {
var list = _currencyRepository.GetAll(userId); var list = _currencyRepository.GetAll(userId);
return list.ToDictionary(
x => x, return list.Select(x => new CurrencyWithRateDto
x => _currencyRateRepository.GetLastRates(x.Id).FirstOrDefault() {
); Currency = _mapper.Map<CurrencyDto>(x),
Rate = _mapper.Map<CurrencyRateDto>(_currencyRateRepository.GetLastRates(x.Id).FirstOrDefault()),
}).ToList();
} }
public Exec<Currency, CurrencyAddStatus> CurrencyAdd(Guid userId, Currency currency) public Exec<CurrencyDto, CurrencyAddStatus> CurrencyAdd(Guid userId, CurrencyDto input)
{ {
if (currency == null) if (input == null)
throw new ArgumentNullException(nameof(currency)); throw new ArgumentNullException(nameof(input));
var result = new Exec<Currency, CurrencyAddStatus>(CurrencyAddStatus.success); var result = new Exec<CurrencyDto, CurrencyAddStatus>(CurrencyAddStatus.success);
var exists = _currencyRepository.GetByGlobalCurrency(userId, currency.CurrencyGlobalId); var exists = _currencyRepository.GetByGlobalCurrency(userId, input.CurrencyGlobalId);
if (exists != null) if (exists != null)
{ {
return result.Set(exists, CurrencyAddStatus.exists); return result.Set(_mapper.Map<CurrencyDto>(exists), CurrencyAddStatus.exists);
} }
currency.Id = Guid.NewGuid(); var currency = new Currency
currency.UserId = userId; {
Id = Guid.NewGuid(),
UserId = userId,
CurrencyGlobalId = input.CurrencyGlobalId,
Name = input.Name,
ShortName = input.ShortName,
};
if (!_currencyRepository.Add(currency)) if (!_currencyRepository.Add(currency))
{ {
return result.Set(CurrencyAddStatus.failed); return result.Set(CurrencyAddStatus.failed);
} }
return result.Set(currency); return result.Set(_mapper.Map<CurrencyDto>(currency));
} }
public Exec<Currency, CurrencyEditStatus> CurrencyUpdate( public Exec<CurrencyDto, CurrencyEditStatus> CurrencyUpdate(
Guid userId, Guid userId,
Guid currencyId, Guid currencyId,
CurrencyEdit currency CurrencyEdit currency
@@ -74,7 +88,7 @@ public class CurrencyService
if (currency == null) if (currency == null)
throw new ArgumentNullException(nameof(currency)); throw new ArgumentNullException(nameof(currency));
var result = new Exec<Currency, CurrencyEditStatus>(CurrencyEditStatus.success); var result = new Exec<CurrencyDto, CurrencyEditStatus>(CurrencyEditStatus.success);
var exists = _currencyRepository.Get(userId, currencyId); var exists = _currencyRepository.Get(userId, currencyId);
if (exists == null) if (exists == null)
@@ -104,15 +118,15 @@ public class CurrencyService
} }
} }
return result.Set(exists); return result.Set(_mapper.Map<CurrencyDto>(exists));
} }
public Exec<CurrencyRate, CurrencyAddRateStatus> CurrencyRateAdd(Guid userId, Guid currencyId, CurrencyRate currencyRate) public Exec<CurrencyRateDto, CurrencyAddRateStatus> CurrencyRateAdd(Guid userId, Guid currencyId, CurrencyRateDto input)
{ {
if (currencyRate == null) if (input == null)
throw new ArgumentNullException(nameof(currencyRate)); throw new ArgumentNullException(nameof(input));
var result = new Exec<CurrencyRate, CurrencyAddRateStatus>(CurrencyAddRateStatus.success); var result = new Exec<CurrencyRateDto, CurrencyAddRateStatus>(CurrencyAddRateStatus.success);
var currency = _currencyRepository.Get(userId, currencyId); var currency = _currencyRepository.Get(userId, currencyId);
if (currency == null) if (currency == null)
@@ -120,11 +134,17 @@ public class CurrencyService
return result.Set(CurrencyAddRateStatus.not_found); return result.Set(CurrencyAddRateStatus.not_found);
} }
currencyRate.CurrencyId = currency.Id; var currencyRate = new CurrencyRate
currencyRate.DateTime = currencyRate.DateTime.Date; {
CurrencyId = currency.Id,
DateTime = input.DateTime.Date,
Rate = input.Rate,
Quantity = input.Quantity,
};
var rates = _currencyRateRepository.GetAtDate(currencyRate.CurrencyId, currencyRate.DateTime); var rates = _currencyRateRepository.GetAtDate(currencyRate.CurrencyId, currencyRate.DateTime);
var rate = rates.Find(x => x.Rate == currencyRate.Rate); var rate = rates.Find(x => x.Rate == currencyRate.Rate);
if (rate == null) if (rate == null)
{ {
if (!_currencyRateRepository.AddRate(currencyRate)) if (!_currencyRateRepository.AddRate(currencyRate))
@@ -132,15 +152,15 @@ public class CurrencyService
return result.Set(CurrencyAddRateStatus.failed); return result.Set(CurrencyAddRateStatus.failed);
} }
rate = currencyRate; // TODO: more logic to fix current rate
if (currencyRate.DateTime.Date == DateTime.UtcNow.Date || !currency.CurrentRateId.HasValue)
if (rate.DateTime.EndOfDay() <= DateTime.UtcNow.EndOfDay())
{ {
currency.CurrentRateId = rate.Id; currency.CurrencyGlobal = null;
currency.CurrentRateId = currencyRate.Id;
_currencyRepository.Update(currency); _currencyRepository.Update(currency);
} }
} }
return result.Set(rate); return result.Set(_mapper.Map<CurrencyRateDto>(rate));
} }
} }
@@ -0,0 +1,22 @@
namespace MyOffice.Services.Currency.Domain;
using MyOffice.Data.Models.Currencies;
using MyOffice.Data.Models.Users;
public class CurrencyDto
{
public Guid Id { get; set; }
public string CurrencyGlobalId { get; set; } = null!;
public CurrencyGlobal? CurrencyGlobal { get; set; }
public Guid UserId { get; set; }
public User? User { get; set; }
public string Name { get; set; } = null!;
public string ShortName { get; set; } = null!;
public IEnumerable<CurrencyRate>? Rates { get; set; }
public int? CurrentRateId { get; set; }
public CurrencyRate? CurrentRate { get; set; }
public bool IsPrimary { get; set; }
}
@@ -0,0 +1,9 @@
namespace MyOffice.Services.Currency.Domain;
public class CurrencyGlobalDto
{
public string Id { get; set; } = null!;
public string Name { get; set; } = null!;
public string Symbol { get; set; } = null!;
public int DefaultQuantity { get; set; }
}
@@ -0,0 +1,12 @@
namespace MyOffice.Services.Currency.Domain;
public class CurrencyRateDto
{
public int Id { get; set; }
public Guid CurrencyId { get; set; }
public CurrencyDto? Currency { get; set; }
public DateTime DateTime { get; set; }
public int Quantity { get; set; }
public decimal Rate { get; set; }
public IEnumerable<CurrencyDto>? Currencies { get; set; }
}
@@ -0,0 +1,7 @@
namespace MyOffice.Services.Currency.Domain;
public class CurrencyWithRateDto
{
public CurrencyDto Currency { get; set; } = null!;
public CurrencyRateDto? Rate { get; set; }
}
+38 -32
View File
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Xml.Linq; using System.Xml.Linq;
using AutoMapper;
using Domain; using Domain;
using MyOffice.Core; using MyOffice.Core;
using MyOffice.Data.Models.Accounts; using MyOffice.Data.Models.Accounts;
@@ -16,20 +17,23 @@ public class ItemService
private readonly IItemCategoryRepository _itemCategoryRepository; private readonly IItemCategoryRepository _itemCategoryRepository;
private readonly IItemRepository _itemRepository; private readonly IItemRepository _itemRepository;
private readonly IItemGlobalRepository _itemGlobalRepository; private readonly IItemGlobalRepository _itemGlobalRepository;
private readonly IMapper _mapper;
public ItemService( public ItemService(
IItemCategoryRepository itemCategoryRepository, IItemCategoryRepository itemCategoryRepository,
IItemRepository itemRepository, IItemRepository itemRepository,
IItemGlobalRepository itemGlobalRepository IItemGlobalRepository itemGlobalRepository,
IMapper mapper
) )
{ {
_itemCategoryRepository = itemCategoryRepository; _itemCategoryRepository = itemCategoryRepository;
_itemRepository = itemRepository; _itemRepository = itemRepository;
_itemGlobalRepository = itemGlobalRepository; _itemGlobalRepository = itemGlobalRepository;
_mapper = mapper;
} }
public List<ItemCategory> GetAllCategories(Guid userId) public List<ItemCategoryDto> GetAllCategories(Guid userId)
{ {
var result = _itemCategoryRepository.GetAll(userId); var result = _itemCategoryRepository.GetAll(userId);
if (result.All(x => x.Id != userId)) if (result.All(x => x.Id != userId))
@@ -44,35 +48,38 @@ public class ItemService
result.Add(_itemCategoryRepository.Get(userId, userId)!); result.Add(_itemCategoryRepository.Get(userId, userId)!);
} }
return result; return _mapper.Map<List<ItemCategoryDto>>(result);
} }
public Exec<ItemCategory, GeneralExecStatus> CategoryAdd(Guid userId, ItemCategory category) public Exec<ItemCategoryDto, GeneralExecStatus> CategoryAdd(Guid userId, ItemCategoryDto input)
{ {
if (category == null) if (input == null)
throw new ArgumentNullException(nameof(category)); throw new ArgumentNullException(nameof(input));
var result = new Exec<ItemCategory, GeneralExecStatus>(GeneralExecStatus.success); var result = new Exec<ItemCategoryDto, GeneralExecStatus>(GeneralExecStatus.success);
category.Id = Guid.NewGuid(); var category = new ItemCategory
category.UserId = userId; {
category.IsInternal = category.IsInternal; Id = Guid.NewGuid(),
category.Items = new List<Item>(); UserId = userId,
Name = input.Name,
IsInternal = input.IsInternal,
};
if (!_itemCategoryRepository.Add(category)) if (!_itemCategoryRepository.Add(category))
{ {
return result.Set(GeneralExecStatus.failure); return result.Set(GeneralExecStatus.failure);
} }
return result.Set(category); return result.Set(_mapper.Map<ItemCategoryDto>(category));
} }
public Exec<ItemCategory, GeneralExecStatus> CategoryUpdate(Guid userId, Guid id, ItemCategory category) public Exec<ItemCategoryDto, GeneralExecStatus> CategoryUpdate(Guid userId, Guid id, ItemCategoryDto category)
{ {
if (category == null) if (category == null)
throw new ArgumentNullException(nameof(category)); throw new ArgumentNullException(nameof(category));
var result = new Exec<ItemCategory, GeneralExecStatus>(GeneralExecStatus.success); var result = new Exec<ItemCategoryDto, GeneralExecStatus>(GeneralExecStatus.success);
var exists = _itemCategoryRepository.Get(userId, id); var exists = _itemCategoryRepository.Get(userId, id);
if (exists == null) if (exists == null)
@@ -82,19 +89,18 @@ public class ItemService
exists.Name = category.Name; exists.Name = category.Name;
exists.IsInternal = category.IsInternal; exists.IsInternal = category.IsInternal;
exists.Items = new List<Item>();
if (!_itemCategoryRepository.Update(exists)) if (!_itemCategoryRepository.Update(exists))
{ {
return result.Set(GeneralExecStatus.failure); return result.Set(GeneralExecStatus.failure);
} }
return result.Set(exists); return result.Set(_mapper.Map<ItemCategoryDto>(exists));
} }
public Exec<ItemCategory, ItemCategoryRemoveResult> CategoryRemove(Guid userId, Guid id) public Exec<ItemCategoryDto, ItemCategoryRemoveResult> CategoryRemove(Guid userId, Guid id)
{ {
var result = new Exec<ItemCategory, ItemCategoryRemoveResult>(ItemCategoryRemoveResult.success); var result = new Exec<ItemCategoryDto, ItemCategoryRemoveResult>(ItemCategoryRemoveResult.success);
var exists = _itemCategoryRepository.Get(userId, id); var exists = _itemCategoryRepository.Get(userId, id);
if (exists == null) if (exists == null)
@@ -111,33 +117,33 @@ public class ItemService
return result.Set(ItemCategoryRemoveResult.failure); return result.Set(ItemCategoryRemoveResult.failure);
} }
return result.Set(exists); return result.Set(_mapper.Map<ItemCategoryDto>(exists));
} }
public List<Item> GetAll(Guid userId) public List<ItemDto> GetAll(Guid userId)
{ {
return _itemRepository.GetAll(userId); return _mapper.Map<List<ItemDto>>(_itemRepository.GetAll(userId));
} }
public List<Item> GetByCategory(Guid userId, Guid categoryId) public List<ItemDto> GetByCategory(Guid userId, Guid categoryId)
{ {
return _itemRepository.GetByCategory(userId, categoryId); return _mapper.Map<List<ItemDto>>(_itemRepository.GetByCategory(userId, categoryId));
} }
public Exec<Item, GeneralExecStatus> Update(Guid userId, Guid motionId, Guid categoryId) public Exec<ItemDto, GeneralExecStatus> Update(Guid userId, Guid motionId, Guid categoryId)
{ {
var result = new Exec<Item, GeneralExecStatus>(GeneralExecStatus.success); var result = new Exec<ItemDto, GeneralExecStatus>(GeneralExecStatus.success);
var motion = _itemRepository.GetByGlobal(userId, motionId); var item = _itemRepository.GetByGlobal(userId, motionId);
if (motion == null) if (item == null)
{ {
return result.Set(GeneralExecStatus.not_found); return result.Set(GeneralExecStatus.not_found);
} }
motion.Category!.Id = categoryId; item.CategoryId = categoryId;
_itemRepository.Update(motion); _itemRepository.Update(item);
return result.Set(motion); return result.Set(_mapper.Map<ItemDto>(item));
} }
public Exec<Item, ItemGetOrAddResult> GetOrCreate(Guid userId, string name) public Exec<Item, ItemGetOrAddResult> GetOrCreate(Guid userId, string name)
@@ -191,11 +197,11 @@ public class ItemService
return result.Set(item); return result.Set(item);
} }
public List<Item> FindItems(Guid userId, string term, int limit = 15) public List<ItemDto> FindItems(Guid userId, string term, int limit = 15)
{ {
if (term == null) if (term == null)
throw new ArgumentNullException(nameof(term)); throw new ArgumentNullException(nameof(term));
return _itemRepository.Find(userId, term, limit); return _mapper.Map<List<ItemDto>>(_itemRepository.Find(userId, term, limit));
} }
} }
@@ -3,14 +3,33 @@
using Account.Domain; using Account.Domain;
using AutoMapper; using AutoMapper;
using Data.Models.Accounts; using Data.Models.Accounts;
using Data.Models.Currencies;
using Data.Models.Items;
using Data.Models.Users; using Data.Models.Users;
using MyOffice.Services.Currency.Domain;
public class AccountServiceProfile : Profile public class AccountServiceProfile : Profile
{ {
public AccountServiceProfile() public AccountServiceProfile()
{ {
CreateMap<User, UserDto>(); MapUser();
MapAccount();
MapCurrency();
MapItems();
CreateMap<Motion, MotionDto>();
}
private void MapUser()
{
CreateMap<User, UserDto>();
}
private void MapAccount()
{
CreateMap<Account, AccountDto>() CreateMap<Account, AccountDto>()
.ForMember(x => x.HasMotions, o => o.MapFrom(x => x.Motions!.Any())) .ForMember(x => x.HasMotions, o => o.MapFrom(x => x.Motions!.Any()))
.ForMember(x => x.CurrentUserId, o => o.MapFrom<UserIdResolver>()) .ForMember(x => x.CurrentUserId, o => o.MapFrom<UserIdResolver>())
@@ -45,4 +64,24 @@ public class AccountServiceProfile : Profile
.ForMember(x => x.Account, o => o.MapFrom(x => x.Account!.Name)) .ForMember(x => x.Account, o => o.MapFrom(x => x.Account!.Name))
; ;
} }
private void MapCurrency()
{
CreateMap<CurrencyGlobal, CurrencyGlobalDto>();
CreateMap<Currency, CurrencyDto>();
CreateMap<CurrencyRate, CurrencyRateDto>();
}
private void MapItems()
{
CreateMap<ItemCategory, ItemCategoryDto>();
CreateMap<Item, ItemDto>()
.ForMember(x => x.Id, o => o.MapFrom(x => x.ItemGlobalId))
.ForMember(x => x.Name, o => o.MapFrom(x => x.ItemGlobal.Name))
.ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Motions!.Any()))
;
}
} }
+30 -28
View File
@@ -3,7 +3,6 @@ namespace MyOffice.Web.Controllers;
using AutoMapper; using AutoMapper;
using Core; using Core;
using Core.Extensions; using Core.Extensions;
using Data.Models.Accounts;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -38,15 +37,15 @@ public class AccountController : BaseApiController
} }
[HttpGet("~/api/accounts")] [HttpGet("~/api/accounts")]
public List<AccountDetailedViewModel> AccountsGet(string category) public ObjectResult AccountsGet(string category)
{ {
var list = _accountService.GetByCategoryDetailed(UserId, category!.AsGuid()); var list = _accountService.GetByCategoryDetailed(UserId, category!.AsGuid());
return _mapper.Map<List<AccountDetailedViewModel>>(list.OrderBy(x => x.Account.Name).ToList()); return OkResponse(_mapper.Map<List<AccountDetailedViewModel>>(list.OrderBy(x => x.Account.Name).ToList()));
} }
[HttpGet("~/api/accounts/{id}")] [HttpGet("~/api/accounts/{id}")]
public object AccountGet(string id) public ObjectResult AccountGet(string id)
{ {
var exec = _accountService.GetByIdDetailed(UserId, id!.AsGuid()); var exec = _accountService.GetByIdDetailed(UserId, id!.AsGuid());
@@ -54,10 +53,10 @@ public class AccountController : BaseApiController
{ {
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
return ProblemBadRequest("Account not found."); return ProblemBadResponse("Account not found.");
case GeneralExecStatus.success: case GeneralExecStatus.success:
return _mapper.Map<AccountDetailedViewModel>(exec.Result); return OkResponse(_mapper.Map<AccountDetailedViewModel>(exec.Result));
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -65,7 +64,7 @@ public class AccountController : BaseApiController
} }
[HttpGet("~/api/accounts/{id}/motions")] [HttpGet("~/api/accounts/{id}/motions")]
public object MotionsGet(string id, [FromQuery] MotionsGetModel request) public ObjectResult MotionsGet(string id, [FromQuery] MotionsGetRequest request)
{ {
var exec = _accountService.GetMotions(UserId, id!.AsGuid(), request.From.StartOfDay(), request.To.EndOfDay()); var exec = _accountService.GetMotions(UserId, id!.AsGuid(), request.From.StartOfDay(), request.To.EndOfDay());
@@ -73,11 +72,10 @@ public class AccountController : BaseApiController
{ {
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
return ProblemBadRequest("Account not found."); return ProblemBadResponse("Account not found.");
case GeneralExecStatus.success: case GeneralExecStatus.success:
//return exec.Result!.Select(x => x.ToModel()); return OkResponse(_mapper.Map<List<MotionViewModel>>(exec.Result!));
return _mapper.Map<MotionViewModel[]>(exec.Result!);
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -92,9 +90,9 @@ public class AccountController : BaseApiController
switch (exec.Status) switch (exec.Status)
{ {
case MotionAddStatus.account_not_found: case MotionAddStatus.account_not_found:
return ProblemBadRequest("Account not found."); return ProblemBadResponse("Account not found.");
case MotionAddStatus.failure: case MotionAddStatus.failure:
return ProblemBadRequest("Adding motion failed."); return ProblemBadResponse("Adding motion failed.");
case MotionAddStatus.success: case MotionAddStatus.success:
return _mapper.Map<MotionViewModel[]>(exec.Result!); return _mapper.Map<MotionViewModel[]>(exec.Result!);
@@ -104,18 +102,18 @@ public class AccountController : BaseApiController
} }
[HttpPut("~/api/accounts/{id}/motions/{motionId}")] [HttpPut("~/api/accounts/{id}/motions/{motionId}")]
public object MotionsPut(string id, string motionId, MotionRequest motion) public ObjectResult MotionsPut(string id, string motionId, MotionRequest motion)
{ {
var exec = _accountService.MotionUpdate(UserId, id.AsGuid(), motionId.AsGuid(), _mapper.Map<MotionAddUpdate>(motion)); var exec = _accountService.MotionUpdate(UserId, id.AsGuid(), motionId.AsGuid(), _mapper.Map<MotionAddUpdate>(motion));
switch (exec.Status) switch (exec.Status)
{ {
case MotionUpdateStatus.not_found: case MotionUpdateStatus.not_found:
return ProblemBadRequest("Motion not found."); return ProblemBadResponse("Motion not found.");
case MotionUpdateStatus.failure: case MotionUpdateStatus.failure:
return ProblemBadRequest("Updating motion failed."); return ProblemBadResponse("Updating motion failed.");
case MotionUpdateStatus.success: case MotionUpdateStatus.success:
return exec.Result!.ToModel(); return OkResponse(_mapper.Map<List<MotionViewModel>>(exec.Result!));
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -123,18 +121,18 @@ public class AccountController : BaseApiController
} }
[HttpDelete("~/api/accounts/{id}/motions/{motionId}")] [HttpDelete("~/api/accounts/{id}/motions/{motionId}")]
public object MotionsDelete(string id, string motionId) public ObjectResult MotionsDelete(string id, string motionId)
{ {
var exec = _accountService.MotionRemove(UserId, id.AsGuid(), motionId.AsGuid()); var exec = _accountService.MotionRemove(UserId, id.AsGuid(), motionId.AsGuid());
switch (exec.Status) switch (exec.Status)
{ {
case MotionDeleteStatus.not_found: case MotionDeleteStatus.not_found:
return ProblemBadRequest("Motion not found."); return ProblemBadResponse("Motion not found.");
case MotionDeleteStatus.failure: case MotionDeleteStatus.failure:
return ProblemBadRequest("Deliting motion failed."); return ProblemBadResponse("Deliting motion failed.");
case MotionDeleteStatus.success: case MotionDeleteStatus.success:
return exec.Result!.ToModel(); return OkResponse(_mapper.Map<MotionViewModel>(exec.Result!));
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -142,16 +140,18 @@ public class AccountController : BaseApiController
} }
[HttpGet("~/api/items")] [HttpGet("~/api/items")]
public object FindItems(string term) public ObjectResult FindItems(string term)
{ {
var items = _itemService var itemsDto = _itemService.FindItems(UserId, term);
.FindItems(UserId, term)
.Select(x => x.ToModel()) var items = _mapper.Map<List<ItemViewModel>>(itemsDto);
.ToList();
if (term.StartsWith("+") && term.Length > 1) if (term.StartsWith("+") && term.Length > 1)
{ {
var accounts = _accountService.FindAccounts(UserId, term.Substring(1)); var accounts = _accountService
.FindAccounts(UserId, term.Substring(1))
.OrderByDescending(x => x.Name);
foreach (var account in accounts) foreach (var account in accounts)
{ {
var accountName = $"+{account.Name}"; var accountName = $"+{account.Name}";
@@ -172,8 +172,10 @@ public class AccountController : BaseApiController
} }
} }
return items return OkResponse(_mapper
.Map<List<ItemViewModel>>(items)
.OrderBy(x => x.AccountId) .OrderBy(x => x.AccountId)
.ThenBy(x => x.Name); .ThenBy(x => x.Name)
);
} }
} }
+12 -1
View File
@@ -4,6 +4,7 @@ using System.Security.Authentication;
using Core.Extensions; using Core.Extensions;
using IdentityModel; using IdentityModel;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MyOffice.Web.Models;
using static IdentityServer4.Models.IdentityResources; using static IdentityServer4.Models.IdentityResources;
public class BaseApiController : ControllerBase public class BaseApiController : ControllerBase
@@ -19,8 +20,18 @@ public class BaseApiController : ControllerBase
} }
} }
public ObjectResult ProblemBadRequest(string? detail = null) public ObjectResult ProblemBadResponse(string? detail = null)
{ {
return Problem(detail, statusCode: StatusCodes.Status400BadRequest); return Problem(detail, statusCode: StatusCodes.Status400BadRequest);
} }
public ObjectResult OkResponse(IResponseModel response)
{
return Ok(response);
}
public ObjectResult OkResponse<T>(IEnumerable<T> response) where T : IResponseModel
{
return Ok(response);
}
} }
+20 -20
View File
@@ -1,14 +1,13 @@
namespace MyOffice.Web.Controllers; namespace MyOffice.Web.Controllers;
using AutoMapper;
using Core.Extensions; using Core.Extensions;
using Data.Models.Currencies; using Data.Models.Currencies;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Data.Repositories.Currency;
using Models.Currency; using Models.Currency;
using Services.Currency; using Services.Currency;
using Services.Currency.Domain; using Services.Currency.Domain;
using MyOffice.Core;
[Authorize] [Authorize]
[ApiController] [ApiController]
@@ -17,30 +16,31 @@ public class CurrencyController : BaseApiController
{ {
private readonly CurrencyService _currencyService; private readonly CurrencyService _currencyService;
private readonly ILogger<CurrencyController> _logger; private readonly ILogger<CurrencyController> _logger;
private readonly IMapper _mapper;
public CurrencyController( public CurrencyController(
CurrencyService currencyService, CurrencyService currencyService,
ILogger<CurrencyController> logger ILogger<CurrencyController> logger,
IMapper mapper
) )
{ {
_currencyService = currencyService; _currencyService = currencyService;
_logger = logger; _logger = logger;
_mapper = mapper;
} }
[HttpGet("~/api/settings/currencies")] [HttpGet("~/api/settings/currencies")]
public object Get() public ObjectResult Get()
{ {
var list = _currencyService.GetAllWithRates(UserId); var list = _currencyService.GetAllWithRates(UserId);
return list return OkResponse(_mapper.Map<List<CurrencyViewModel>>(list).OrderBy(x => x.Id));
.OrderBy(x => x.Key.CurrencyGlobalId)
.Select(x => x.Key.ToModel(x.Value));
} }
[HttpPost("~/api/settings/currencies")] [HttpPost("~/api/settings/currencies")]
public object Post(CurrencyAddModel currency) public ObjectResult Post(CurrencyAddModel currency)
{ {
var exec = _currencyService.CurrencyAdd(UserId, new Currency var exec = _currencyService.CurrencyAdd(UserId, new CurrencyDto
{ {
UserId = UserId, UserId = UserId,
CurrencyGlobalId = currency.Id, CurrencyGlobalId = currency.Id,
@@ -52,17 +52,17 @@ public class CurrencyController : BaseApiController
{ {
case CurrencyAddStatus.success: case CurrencyAddStatus.success:
case CurrencyAddStatus.exists: case CurrencyAddStatus.exists:
_currencyService.CurrencyRateAdd(UserId, exec.Result!.Id, new CurrencyRate() _currencyService.CurrencyRateAdd(UserId, exec.Result!.Id, new CurrencyRateDto
{ {
CurrencyId = exec.Result!.Id, CurrencyId = exec.Result!.Id,
Rate = currency.Rate, Rate = currency.Rate,
Quantity = currency.Quantity, Quantity = currency.Quantity,
DateTime = currency.RateDate.Date, DateTime = currency.RateDate.Date,
}); });
return currency; return OkResponse(_mapper.Map<CurrencyViewModel>(exec.Result!));
case CurrencyAddStatus.failed: case CurrencyAddStatus.failed:
return ProblemBadRequest("Adding currency failed."); return ProblemBadResponse("Adding currency failed.");
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -70,7 +70,7 @@ public class CurrencyController : BaseApiController
} }
[HttpPut("~/api/settings/currencies/{id}")] [HttpPut("~/api/settings/currencies/{id}")]
public object Put(string id, CurrencyEditModel currency) public ObjectResult Update(string id, CurrencyEditModel currency)
{ {
var exec = _currencyService.CurrencyUpdate( var exec = _currencyService.CurrencyUpdate(
UserId, UserId,
@@ -81,11 +81,11 @@ public class CurrencyController : BaseApiController
switch (exec.Status) switch (exec.Status)
{ {
case CurrencyEditStatus.success: case CurrencyEditStatus.success:
return exec.Result!.ToModel(); return OkResponse(_mapper.Map<CurrencyViewModel>(exec.Result!));
case CurrencyEditStatus.not_found: case CurrencyEditStatus.not_found:
case CurrencyEditStatus.failed: case CurrencyEditStatus.failed:
return ProblemBadRequest("Currency not found."); return ProblemBadResponse("Currency not found.");
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -93,9 +93,9 @@ public class CurrencyController : BaseApiController
} }
[HttpPost("~/api/settings/currencies/{id}/rate")] [HttpPost("~/api/settings/currencies/{id}/rate")]
public object Post(string id, CurrencyRateModel currencyRate) public ObjectResult Add(string id, CurrencyRateModel currencyRate)
{ {
var exec = _currencyService.CurrencyRateAdd(UserId, id.AsGuid(), new CurrencyRate() var exec = _currencyService.CurrencyRateAdd(UserId, id.AsGuid(), new CurrencyRateDto
{ {
CurrencyId = id.AsGuid(), CurrencyId = id.AsGuid(),
Quantity = currencyRate.Quantity, Quantity = currencyRate.Quantity,
@@ -106,12 +106,12 @@ public class CurrencyController : BaseApiController
switch (exec.Status) switch (exec.Status)
{ {
case CurrencyAddRateStatus.failed: case CurrencyAddRateStatus.failed:
return ProblemBadRequest("Adding currency rate failed."); return ProblemBadResponse("Adding currency rate failed.");
case CurrencyAddRateStatus.not_found: case CurrencyAddRateStatus.not_found:
return ProblemBadRequest("Currency not found."); return ProblemBadResponse("Currency not found.");
case CurrencyAddRateStatus.success: case CurrencyAddRateStatus.success:
return exec.Result!; return OkResponse(_mapper.Map<CurrencyRateViewModel>(exec.Result!));
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -1,8 +1,8 @@
namespace MyOffice.Web.Controllers; namespace MyOffice.Web.Controllers;
using AutoMapper;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Data.Repositories.Currency;
using Models.Currency; using Models.Currency;
using Services.Currency; using Services.Currency;
@@ -12,19 +12,22 @@ using Services.Currency;
public class GeneralController : BaseApiController public class GeneralController : BaseApiController
{ {
private readonly CurrencyService _currencyService; private readonly CurrencyService _currencyService;
private readonly IMapper _mapper;
public GeneralController( public GeneralController(
CurrencyService currencyService CurrencyService currencyService,
IMapper mapper
) )
{ {
_currencyService = currencyService; _currencyService = currencyService;
_mapper = mapper;
} }
[HttpGet("~/api/general/currencies")] [HttpGet("~/api/general/currencies")]
public object Get() public ObjectResult Get()
{ {
var list = _currencyService.GetGlobalAll(); var list = _currencyService.GetGlobalAll();
return list.Select(x => x.ToModel()); return Ok(_mapper.Map<List<CurrencyGlobalViewModel>>(list));
} }
} }
@@ -1,15 +1,15 @@
namespace MyOffice.Web.Controllers; namespace MyOffice.Web.Controllers;
using AutoMapper; using AutoMapper;
using Core;
using Core.Extensions;
using Data.Models.Accounts;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Core;
using Core.Extensions;
using Models.Account; using Models.Account;
using Services.Account; using Services.Account;
using Services.Account.Domain; using Services.Account.Domain;
using MyOffice.Web.Infrastructure.Attributes; using Infrastructure.Attributes;
using Services.Identity; using Services.Identity;
[Authorize] [Authorize]
@@ -52,7 +52,7 @@ public class SettingsAccountController : BaseApiController
{ {
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
return ProblemBadRequest("Account category not found."); return ProblemBadResponse("Account category not found.");
case GeneralExecStatus.success: case GeneralExecStatus.success:
return _mapper.Map<AccountCategoryViewModel>(exec.Result!); return _mapper.Map<AccountCategoryViewModel>(exec.Result!);
@@ -65,7 +65,7 @@ public class SettingsAccountController : BaseApiController
[HttpPost("~/api/settings/account-categories")] [HttpPost("~/api/settings/account-categories")]
public object AccountCategoriesAdd(AccountCategoryViewModel request) public object AccountCategoriesAdd(AccountCategoryViewModel request)
{ {
var exec = _accountService.CategoryAdd(UserId, new AccountCategory { Name = request.Name! }); var exec = _accountService.CategoryAdd(UserId, new AccountCategoryDto { Name = request.Name! });
switch (exec.Status) switch (exec.Status)
{ {
case GeneralExecStatus.success: case GeneralExecStatus.success:
@@ -73,7 +73,7 @@ public class SettingsAccountController : BaseApiController
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
return ProblemBadRequest("Adding account category failed."); return ProblemBadResponse("Adding account category failed.");
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -83,7 +83,7 @@ public class SettingsAccountController : BaseApiController
[HttpPut("~/api/settings/account-categories/{id}")] [HttpPut("~/api/settings/account-categories/{id}")]
public object AccountCategoriesEdit([AsGuid] string id, AccountCategoryViewModel request) public object AccountCategoriesEdit([AsGuid] string id, AccountCategoryViewModel request)
{ {
var exec = _accountService.CategoryUpdate(UserId, id.AsGuid(), new AccountCategory { Name = request.Name! }); var exec = _accountService.CategoryUpdate(UserId, id.AsGuid(), new AccountCategoryDto { Name = request.Name! });
switch (exec.Status) switch (exec.Status)
{ {
case GeneralExecStatus.success: case GeneralExecStatus.success:
@@ -91,7 +91,7 @@ public class SettingsAccountController : BaseApiController
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
return ProblemBadRequest("Update account category failed."); return ProblemBadResponse("Update account category failed.");
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -108,11 +108,11 @@ public class SettingsAccountController : BaseApiController
return exec.Result!; return exec.Result!;
case AccountCategoryRemoveResult.failure: case AccountCategoryRemoveResult.failure:
return ProblemBadRequest("Remove account category failed."); return ProblemBadResponse("Remove account category failed.");
case AccountCategoryRemoveResult.not_found: case AccountCategoryRemoveResult.not_found:
return ProblemBadRequest("Account category not found."); return ProblemBadResponse("Account category not found.");
case AccountCategoryRemoveResult.accounts_exists: case AccountCategoryRemoveResult.accounts_exists:
return ProblemBadRequest("Account category have accounts."); return ProblemBadResponse("Account category have accounts.");
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -143,11 +143,11 @@ public class SettingsAccountController : BaseApiController
switch (exec.Status) switch (exec.Status)
{ {
case AccountAddStatus.category_not_found: case AccountAddStatus.category_not_found:
return ProblemBadRequest("Category not found."); return ProblemBadResponse("Category not found.");
case AccountAddStatus.currency_not_found: case AccountAddStatus.currency_not_found:
return ProblemBadRequest("Currency not found."); return ProblemBadResponse("Currency not found.");
case AccountAddStatus.failure: case AccountAddStatus.failure:
return ProblemBadRequest("Adding account failed."); return ProblemBadResponse("Adding account failed.");
case AccountAddStatus.success: case AccountAddStatus.success:
return exec.Result!; return exec.Result!;
@@ -172,13 +172,13 @@ public class SettingsAccountController : BaseApiController
switch (exec.Status) switch (exec.Status)
{ {
case AccountEditStatus.not_found: case AccountEditStatus.not_found:
return ProblemBadRequest("Account not found."); return ProblemBadResponse("Account not found.");
case AccountEditStatus.category_not_found: case AccountEditStatus.category_not_found:
return ProblemBadRequest("Category not found."); return ProblemBadResponse("Category not found.");
case AccountEditStatus.currency_not_found: case AccountEditStatus.currency_not_found:
return ProblemBadRequest("Currency not found."); return ProblemBadResponse("Currency not found.");
case AccountEditStatus.failure: case AccountEditStatus.failure:
return ProblemBadRequest("Adding account failed."); return ProblemBadResponse("Adding account failed.");
case AccountEditStatus.success: case AccountEditStatus.success:
return exec.Result!; return exec.Result!;
@@ -194,7 +194,7 @@ public class SettingsAccountController : BaseApiController
switch (exec.Status) switch (exec.Status)
{ {
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
return ProblemBadRequest("Account not found."); return ProblemBadResponse("Account not found.");
case GeneralExecStatus.success: case GeneralExecStatus.success:
return exec.Result!; return exec.Result!;
@@ -212,7 +212,7 @@ public class SettingsAccountController : BaseApiController
{ {
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
return ProblemBadRequest("Category not found."); return ProblemBadResponse("Category not found.");
case GeneralExecStatus.success: case GeneralExecStatus.success:
return exec.Result!; return exec.Result!;
@@ -233,7 +233,7 @@ public class SettingsAccountController : BaseApiController
{ {
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
return ProblemBadRequest("Account not found."); return ProblemBadResponse("Account not found.");
case GeneralExecStatus.success: case GeneralExecStatus.success:
break; break;
@@ -252,7 +252,7 @@ public class SettingsAccountController : BaseApiController
switch (inviteExec.Status) switch (inviteExec.Status)
{ {
case AccessInviteStatus.account_not_found: case AccessInviteStatus.account_not_found:
return ProblemBadRequest("Account not found."); return ProblemBadResponse("Account not found.");
case AccessInviteStatus.access_exists: case AccessInviteStatus.access_exists:
case AccessInviteStatus.invite_exists: case AccessInviteStatus.invite_exists:
@@ -273,7 +273,7 @@ public class SettingsAccountController : BaseApiController
{ {
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
return ProblemBadRequest("Account not found."); return ProblemBadResponse("Account not found.");
case GeneralExecStatus.success: case GeneralExecStatus.success:
return exec.Result!; return exec.Result!;
@@ -299,9 +299,9 @@ public class SettingsAccountController : BaseApiController
switch (exec.Status) switch (exec.Status)
{ {
case InviteAcceptStatus.invite_not_found: case InviteAcceptStatus.invite_not_found:
return ProblemBadRequest("Invite not found."); return ProblemBadResponse("Invite not found.");
case InviteAcceptStatus.account_not_found: case InviteAcceptStatus.account_not_found:
return ProblemBadRequest("Account not found."); return ProblemBadResponse("Account not found.");
case InviteAcceptStatus.already_accepted: case InviteAcceptStatus.already_accepted:
case InviteAcceptStatus.success: case InviteAcceptStatus.success:
@@ -321,7 +321,7 @@ public class SettingsAccountController : BaseApiController
{ {
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
return ProblemBadRequest("Invite not found."); return ProblemBadResponse("Invite not found.");
case GeneralExecStatus.success: case GeneralExecStatus.success:
return _mapper.Map<AccountAccessInviteViewModel>(exec.Result!); return _mapper.Map<AccountAccessInviteViewModel>(exec.Result!);
@@ -1,14 +1,13 @@
namespace MyOffice.Web.Controllers; namespace MyOffice.Web.Controllers;
using Data.Models.Items; using AutoMapper;
using Data.Repositories.Account;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Models.Item; using Models.Item;
using MyOffice.Core.Extensions; using Core.Extensions;
using MyOffice.Core; using Core;
using MyOffice.Services.Account; using Infrastructure.Attributes;
using MyOffice.Services.Account.Domain;
using Services.Item; using Services.Item;
using Services.Item.Domain; using Services.Item.Domain;
@@ -18,42 +17,43 @@ using Services.Item.Domain;
public class SettingsItemController : BaseApiController public class SettingsItemController : BaseApiController
{ {
private ILogger<SettingsItemController> _logger; private ILogger<SettingsItemController> _logger;
private IMapper _mapper;
private ItemService _itemService; private ItemService _itemService;
public SettingsItemController( public SettingsItemController(
ILogger<SettingsItemController> logger, ILogger<SettingsItemController> logger,
ItemService itemService ItemService itemService,
IMapper mapper
) )
{ {
_itemService = itemService; _itemService = itemService;
_logger = logger; _logger = logger;
_mapper = mapper;
} }
[HttpGet("~/api/settings/item-categories")] [HttpGet("~/api/settings/item-categories")]
public object ItemsCategories() public ObjectResult ItemsCategories()
{ {
var list = _itemService.GetAllCategories(UserId); var list = _itemService.GetAllCategories(UserId);
return list return Ok(_mapper.Map<List<ItemCategoryViewModel>>(list)
.Select(x => x.ToModel())
.OrderByDescending(x => x.SortOrder) .OrderByDescending(x => x.SortOrder)
.ThenBy(x => x.Name); .ThenBy(x => x.Name));
} }
[HttpPost("~/api/settings/item-categories")] [HttpPost("~/api/settings/item-categories")]
public object ItemCategoriesAdd(ItemCategoryViewModel request) public ObjectResult ItemCategoriesAdd(ItemCategoryViewModel request)
{ {
var exec = _itemService.CategoryAdd(UserId, request.FromModel()); var exec = _itemService.CategoryAdd(UserId, request.FromModel());
switch (exec.Status) switch (exec.Status)
{ {
case GeneralExecStatus.success: case GeneralExecStatus.success:
return exec.Result!.ToModel(); return Ok(_mapper.Map<ItemCategoryViewModel>(exec.Result!));
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
return ProblemBadRequest("Adding item category failed."); return ProblemBadResponse("Adding item category failed.");
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -61,18 +61,18 @@ public class SettingsItemController : BaseApiController
} }
[HttpPut("~/api/settings/item-categories/{id}")] [HttpPut("~/api/settings/item-categories/{id}")]
public object ItemCategoriesEdit(string id, ItemCategoryViewModel request) public ObjectResult ItemCategoriesUpdate([AsGuid] string id, ItemCategoryViewModel request)
{ {
var exec = _itemService.CategoryUpdate(UserId, id.AsGuid(), request.FromModel()); var exec = _itemService.CategoryUpdate(UserId, id.AsGuid(), request.FromModel());
switch (exec.Status) switch (exec.Status)
{ {
case GeneralExecStatus.success: case GeneralExecStatus.success:
return exec.Result!.ToModel(); return Ok(_mapper.Map<ItemCategoryViewModel>(exec.Result!));
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
return ProblemBadRequest("Update item category failed."); return ProblemBadResponse("Update item category failed.");
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -80,20 +80,20 @@ public class SettingsItemController : BaseApiController
} }
[HttpDelete("~/api/settings/item-categories/{id}")] [HttpDelete("~/api/settings/item-categories/{id}")]
public object ItemCategoriesDelete(string id) public ObjectResult ItemCategoriesDelete([AsGuid] string id)
{ {
var exec = _itemService.CategoryRemove(UserId, id.AsGuid()); var exec = _itemService.CategoryRemove(UserId, id.AsGuid());
switch (exec.Status) switch (exec.Status)
{ {
case ItemCategoryRemoveResult.success: case ItemCategoryRemoveResult.success:
return exec.Result!; return Ok(_mapper.Map<ItemCategoryViewModel>(exec.Result!));
case ItemCategoryRemoveResult.failure: case ItemCategoryRemoveResult.failure:
return ProblemBadRequest("Remove item category failed."); return ProblemBadResponse("Remove item category failed.");
case ItemCategoryRemoveResult.not_found: case ItemCategoryRemoveResult.not_found:
return ProblemBadRequest("Account item not found."); return ProblemBadResponse("Account item not found.");
case ItemCategoryRemoveResult.accounts_exists: case ItemCategoryRemoveResult.accounts_exists:
return ProblemBadRequest("Account motion have accounts."); return ProblemBadResponse("Account motion have accounts.");
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
@@ -101,29 +101,28 @@ public class SettingsItemController : BaseApiController
} }
[HttpGet("~/api/settings/items")] [HttpGet("~/api/settings/items")]
public object Items(string? category) public ObjectResult Items([AsGuid] string? category)
{ {
var list = category.IsMissing() var list = category.IsMissing()
? _itemService.GetAll(UserId) ? _itemService.GetAll(UserId)
: _itemService.GetByCategory(UserId, category!.AsGuid()); : _itemService.GetByCategory(UserId, category!.AsGuid());
return list return Ok(_mapper.Map<List<ItemViewModel>>(list.OrderBy(x => x.Name)));
.OrderBy(x => x.ItemGlobal.Name)
.Select(x => x.ToModel());
} }
[HttpPut("~/api/settings/items/{id}")] [HttpPut("~/api/settings/items/{id}")]
public object Items(string id, ItemEditModel request) public ObjectResult Items([AsGuid] string id, ItemEditModel request)
{ {
var exec = _itemService.Update(UserId, id.AsGuid(), request.Category.AsGuid()); var exec = _itemService.Update(UserId, id.AsGuid(), request.Category.AsGuid());
switch (exec.Status) switch (exec.Status)
{ {
case GeneralExecStatus.not_found: case GeneralExecStatus.not_found:
return ProblemBadRequest("Item not found."); return ProblemBadResponse("Item not found.");
case GeneralExecStatus.failure: case GeneralExecStatus.failure:
return ProblemBadRequest("Item update failed."); return ProblemBadResponse("Item update failed.");
case GeneralExecStatus.success: case GeneralExecStatus.success:
return Ok(exec.Result!.ToModel()); return Ok(_mapper.Map<ItemViewModel>(exec.Result!));
default: default:
throw new NotSupportedException(exec.Status.ToString()); throw new NotSupportedException(exec.Status.ToString());
+4 -4
View File
@@ -84,10 +84,10 @@ public class UserController : BaseApiController
public async Task<object> AttachProvider([FromBody] AttachModel model) public async Task<object> AttachProvider([FromBody] AttachModel model)
{ {
var validator = _externalProviderValidators.FirstOrDefault(x => x.Provider.EqualsIgnoreCase(model.Provider)); var validator = _externalProviderValidators.FirstOrDefault(x => x.Provider.EqualsIgnoreCase(model.Provider));
if (validator == null) return ProblemBadRequest("Provider not supported"); if (validator == null) return ProblemBadResponse("Provider not supported");
var result = await validator.ValidateAsync(model.Token); var result = await validator.ValidateAsync(model.Token);
if (!result.IsSuccessed) return ProblemBadRequest("Token not valid"); if (!result.IsSuccessed) return ProblemBadResponse("Token not valid");
var execResult = _userService.AddUserExternal(UserId, model.Provider, result.ExternalId!, result.Email!); var execResult = _userService.AddUserExternal(UserId, model.Provider, result.ExternalId!, result.Email!);
switch (execResult.Status) switch (execResult.Status)
@@ -100,7 +100,7 @@ public class UserController : BaseApiController
case AddUserExternalStatusEnum.externalid_used: case AddUserExternalStatusEnum.externalid_used:
case AddUserExternalStatusEnum.user_not_valid: case AddUserExternalStatusEnum.user_not_valid:
return ProblemBadRequest("Provider already connected"); return ProblemBadResponse("Provider already connected");
default: default:
throw new NotSupportedException(execResult.Status.ToString()); throw new NotSupportedException(execResult.Status.ToString());
@@ -113,7 +113,7 @@ public class UserController : BaseApiController
{ {
var exec = await _userService.RemoveUserExternal(UserId, model.Provider); var exec = await _userService.RemoveUserExternal(UserId, model.Provider);
if (exec.Status == GeneralExecStatus.not_found) return ProblemBadRequest("Provider not connected"); if (exec.Status == GeneralExecStatus.not_found) return ProblemBadResponse("Provider not connected");
return Ok(new return Ok(new
{ {
@@ -52,7 +52,7 @@ public class UserStore :
public async Task<IdentityResult> CreateAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken) public async Task<IdentityResult> CreateAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
{ {
var result = await _userRepository.AddUserAsync(new User var result = _userRepository.AddUser(new User
{ {
Id = user.Id, Id = user.Id,
UserName = user.UserName, UserName = user.UserName,
@@ -83,7 +83,7 @@ public class UserStore :
IsEmailConfirmed = user.IsEmailConfirmed IsEmailConfirmed = user.IsEmailConfirmed
}; };
var result = await _userRepository.UpdateUserAsync(userDb); var result = _userRepository.UpdateUser(userDb);
return result == 1 ? IdentityResult.Success : IdentityResult.Failed(); return result == 1 ? IdentityResult.Success : IdentityResult.Failed();
} }
@@ -1,22 +1,7 @@
namespace MyOffice.Web.Models.Account; namespace MyOffice.Web.Models.Account;
using Data.Models.Accounts; public class AccountDetailedViewModel: BaseViewModel
using Services.Account.Domain;
public class AccountDetailedViewModel
{ {
public AccountViewModel Account { get; set; } = null!; public AccountViewModel Account { get; set; } = null!;
public decimal Rest { get; set; } public decimal Rest { get; set; }
} }
/*public static class AccountDetailedViewModelExtensions
{
public static AccountDetailedViewModel ToModel(this AccountDetailedDto input)
{
return new AccountDetailedViewModel
{
Account = input.Account.ToModel(),
Rest = input.Rest,
};
}
}*/
@@ -1,7 +1,12 @@
namespace MyOffice.Web.Models.Account; namespace MyOffice.Web.Models.Account;
using AutoMapper; using AutoMapper;
using MyOffice.Services.Currency.Domain;
using MyOffice.Services.Identity; using MyOffice.Services.Identity;
using Currency;
using Item;
using Motion;
using Services.Account.Domain; using Services.Account.Domain;
using User; using User;
@@ -67,5 +72,35 @@ public class AccountViewModelProfile : Profile
CreateMap<AccountAccessInviteDto, AccountAccessInviteViewModel>() CreateMap<AccountAccessInviteDto, AccountAccessInviteViewModel>()
.ForMember(x => x.AllowWrite, o => o.MapFrom(x => x.IsAllowWrite)) .ForMember(x => x.AllowWrite, o => o.MapFrom(x => x.IsAllowWrite))
; ;
CreateMap<MotionDto, MotionViewModel>()
;
CreateMap<ItemDto, ItemViewModel>()
.ForMember(x => x.Category, o => o.MapFrom(x => x.Category!.Name))
;
CreateMap<ItemCategoryDto, ItemCategoryViewModel>()
.ForMember(x => x.Internal, o => o.MapFrom(x => x.IsInternal))
.ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Items.Any() && x.Id != x.UserId))
.ForMember(x => x.SortOrder, o => o.MapFrom(x => x.Id == x.UserId ? 1 : 0))
;
CreateMap<CurrencyGlobalDto, CurrencyGlobalViewModel>();
CreateMap<CurrencyDto, CurrencyViewModel>();
CreateMap<CurrencyRateDto, CurrencyRateViewModel>();
CreateMap<CurrencyWithRateDto, CurrencyViewModel>()
.ForMember(x => x.Id, o => o.MapFrom(x => x.Currency.Id))
.ForMember(x => x.Code, o => o.MapFrom(x => x.Currency.CurrencyGlobalId))
.ForMember(x => x.Name, o => o.MapFrom(x => x.Currency.Name))
.ForMember(x => x.ShortName, o => o.MapFrom(x => x.Currency.ShortName))
.ForMember(x => x.Rate, o => o.MapFrom(x => x.Rate == null ? (decimal?)null : x.Rate.Rate))
.ForMember(x => x.IsPrimary, o => o.MapFrom(x => x.Currency.IsPrimary))
.ForMember(x => x.Quantity, o => o.MapFrom(x => x.Rate == null ? (int?)null : x.Rate.Quantity))
.ForMember(x => x.RateDate, o => o.MapFrom(x => x.Rate == null ? (DateTime?)null : x.Rate.DateTime))
;
} }
} }
@@ -2,7 +2,7 @@
{ {
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
public class MotionsGetModel public class MotionsGetRequest
{ {
[Required] [Required]
public DateTime From { get; set; } public DateTime From { get; set; }
+6
View File
@@ -0,0 +1,6 @@
namespace MyOffice.Web.Models;
public class BaseViewModel : IResponseModel
{
}
@@ -0,0 +1,9 @@
namespace MyOffice.Web.Models.Currency;
public class CurrencyRateViewModel: BaseViewModel
{
public string Currency { get; set; }
public DateTime DateTime { get; set; }
public int Quantity { get; set; }
public decimal Rate { get; set; }
}
@@ -1,38 +1,14 @@
namespace MyOffice.Web.Models.Currency namespace MyOffice.Web.Models.Currency;
public class CurrencyViewModel: BaseViewModel
{ {
using Core.Extensions; public string Id { get; set; } = null!;
using Data.Models.Currencies; public string Code { get; set; } = null!;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; public string Symbol { get; set; } = null!;
public string Name { get; set; } = null!;
public class CurrencyViewModel public string ShortName { get; set; } = null!;
{ public decimal? Rate { get; set; }
public string Id { get; set; } = null!; public int? Quantity { get; set; }
public string Code { get; set; } = null!; public DateTime? RateDate { get; set; }
public string Symbol { get; set; } = null!; public bool IsPrimary { get; set; }
public string Name { get; set; } = null!;
public string ShortName { get; set; } = null!;
public decimal? Rate { get; set; }
public int? Quantity { get; set; }
public DateTime? RateDate { get; set; }
public bool IsPrimary { get; set; }
}
public static class CurrencyViewModelExtensions
{
public static CurrencyViewModel ToModel(this Currency input, CurrencyRate? rate = null)
{
return new CurrencyViewModel
{
Id = input.Id.ToShort(),
Code = input.CurrencyGlobal!.Id,
Symbol = input.CurrencyGlobal!.Symbol,
Name = input.Name,
ShortName = input.ShortName,
Quantity = input.CurrentRate?.Quantity ?? rate?.Quantity,
Rate = input.CurrentRate?.Rate ?? rate?.Rate,
RateDate = input.CurrentRate?.DateTime ?? rate?.DateTime,
IsPrimary = input.IsPrimary,
};
}
}
} }
+5
View File
@@ -0,0 +1,5 @@
namespace MyOffice.Web.Models;
public interface IRequestModel
{
}
+5
View File
@@ -0,0 +1,5 @@
namespace MyOffice.Web.Models;
public interface IResponseModel
{
}
@@ -1,9 +1,7 @@
namespace MyOffice.Web.Models.Item namespace MyOffice.Web.Models.Item
{ {
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using MyOffice.Core.Extensions; using Services.Account.Domain;
using MyOffice.Data.Models.Items;
using MyOffice.Migrations.Postgres.Migrations;
public class ItemCategoryViewModel public class ItemCategoryViewModel
{ {
@@ -14,32 +12,20 @@
public bool AllowDelete { get; set; } public bool AllowDelete { get; set; }
public int SortOrder { get; set; } public int SortOrder { get; set; }
public bool IsInternal { get; set; } public bool Internal { get; set; }
} }
public static class ItemCategoryViewModelExtensions public static class ItemCategoryViewModelExtensions
{ {
public static ItemCategoryViewModel ToModel(this ItemCategory input) public static ItemCategoryDto FromModel(this ItemCategoryViewModel input)
{
return new ItemCategoryViewModel
{
Id = input.Id.ToShort(),
Name = input.Name,
AllowDelete = !input.Items.Any() && input.Id != input.UserId,
IsInternal = input.IsInternal,
SortOrder = input.Id == input.UserId ? 1 : 0
};
}
public static ItemCategory FromModel(this ItemCategoryViewModel input)
{ {
if (input == null) if (input == null)
throw new ArgumentNullException(nameof(input)); throw new ArgumentNullException(nameof(input));
return new ItemCategory return new ItemCategoryDto
{ {
Name = input.Name, Name = input.Name,
IsInternal = input.IsInternal, IsInternal = input.Internal,
}; };
} }
} }
+12 -31
View File
@@ -1,36 +1,17 @@
namespace MyOffice.Web.Models.Item namespace MyOffice.Web.Models.Item;
using System.ComponentModel.DataAnnotations;
public class ItemViewModel : BaseViewModel
{ {
using System.ComponentModel.DataAnnotations; public string? Id { get; set; }
using Data.Models.Accounts; [Required]
using MyOffice.Core.Extensions; public string? Name { get; set; }
using MyOffice.Data.Models.Items;
public class ItemViewModel public bool AllowDelete { get; set; }
{
public string? Id { get; set; }
public string CategoryId { get; set; } = null!; public string CategoryId { get; set; } = null!;
public string? Category { get; set; } = null!; public string? Category { get; set; } = null!;
[Required]
public string? Name { get; set; }
public bool AllowDelete { get; set; } public string? AccountId { get; set; }
public string? AccountId { get; set; }
}
public static class ItemViewModelExtensions
{
public static ItemViewModel ToModel(this Item input, Account? account = null)
{
return new ItemViewModel
{
Id = input.ItemGlobal.Id.ToShort(),
CategoryId = input.CategoryId.ToShort(),
Category = input.Category?.Name,
Name = input.ItemGlobal.Name,
AllowDelete = input.Motions != null && !input.Motions.Any(),
AccountId = account?.Id.ToShort(),
};
}
}
} }
+1 -20
View File
@@ -1,9 +1,6 @@
namespace MyOffice.Web.Models.Motion namespace MyOffice.Web.Models.Motion
{ {
using Core.Extensions; public class MotionViewModel: BaseViewModel
using Data.Models.Accounts;
public class MotionViewModel
{ {
public string Id { get; set; } = null!; public string Id { get; set; } = null!;
public DateTime Date { get; set; } public DateTime Date { get; set; }
@@ -13,20 +10,4 @@
public decimal Plus { get; set; } public decimal Plus { get; set; }
public decimal Minus { get; set; } public decimal Minus { get; set; }
} }
public static class MotionViewModelExtensions
{
public static MotionViewModel ToModel(this Motion input)
{
return new MotionViewModel
{
Id = input.Id.ToShort(),
Date = input.DateTime,
Item = input.Item.ItemGlobal.Name,
Description = input.Description,
Plus = input.AmountPlus,
Minus = input.AmountMinus,
};
}
}
} }
@@ -1,4 +1,4 @@
namespace MyOffice.Web.Models.Account; namespace MyOffice.Web.Models;
using AutoMapper; using AutoMapper;
using Core.Extensions; using Core.Extensions;
-2
View File
@@ -44,8 +44,6 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\MyOffice.Core\MyOffice.Core.csproj" /> <ProjectReference Include="..\MyOffice.Core\MyOffice.Core.csproj" />
<ProjectReference Include="..\MyOffice.Data.Models\MyOffice.Data.Models.csproj" />
<ProjectReference Include="..\MyOffice.Data.Repositories\MyOffice.Data.Repositories.csproj" />
<ProjectReference Include="..\MyOffice.DbContext\MyOffice.DbContext.csproj" /> <ProjectReference Include="..\MyOffice.DbContext\MyOffice.DbContext.csproj" />
<ProjectReference Include="..\MyOffice.Migration.Postgres\MyOffice.Migrations.Postgres.csproj" /> <ProjectReference Include="..\MyOffice.Migration.Postgres\MyOffice.Migrations.Postgres.csproj" />
<ProjectReference Include="..\MyOffice.Migration.Sqlite\MyOffice.Migrations.Sqlite.csproj" /> <ProjectReference Include="..\MyOffice.Migration.Sqlite\MyOffice.Migrations.Sqlite.csproj" />
+11 -13
View File
@@ -2,7 +2,6 @@ namespace MyOffice.Web;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Core.Extensions;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.FileProviders.Physical; using Microsoft.Extensions.FileProviders.Physical;
@@ -13,19 +12,22 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Identity;
using Identity.Domain;
using Identity.ExternalProviders;
using Identity.Repositories;
using IdentityServer4.AccessTokenValidation; using IdentityServer4.AccessTokenValidation;
using IdentityServer4.Configuration; using IdentityServer4.Configuration;
using IdentityServer4.Extensions; using IdentityServer4.Extensions;
using IdentityServer4.Models; using IdentityServer4.Models;
using IdentityServer4.Services;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.Extensions.Logging.Console;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Identity;
using Identity.Domain;
using Identity.ExternalProviders;
using Identity.Repositories;
using Core.Identity; using Core.Identity;
using Core.Extensions;
using Data.Repositories.Account; using Data.Repositories.Account;
using Data.Repositories.Currency; using Data.Repositories.Currency;
using Data.Repositories.Item; using Data.Repositories.Item;
@@ -35,17 +37,12 @@ using Services.Users;
using Shared; using Shared;
using Identity.Configure; using Identity.Configure;
using Infrastructure; using Infrastructure;
using Microsoft.Extensions.Logging.Console;
using IdentityServer4.Services;
using Models.Account; using Models.Account;
using MyOffice.Services.Currency; using MyOffice.Services.Currency;
using Services.Account; using Services.Account;
using Services.Item; using Services.Item;
using MyOffice.Services.Dashboard; using MyOffice.Services.Dashboard;
using MyOffice.Services.Identity; using MyOffice.Services.Identity;
using AutoMapper;
using Models.Motion;
using MyOffice.Services.Account.Domain;
using MyOffice.Services.Mapper; using MyOffice.Services.Mapper;
//TODO: Data.Model only Repository and Service, response <-> mapper <-> web <-> mapper <-> service <-> repository //TODO: Data.Model only Repository and Service, response <-> mapper <-> web <-> mapper <-> service <-> repository
@@ -68,9 +65,10 @@ using MyOffice.Services.Mapper;
//TODO: Services auto registration //TODO: Services auto registration
//TODO: openid-configuration failed - lock login //TODO: openid-configuration failed - lock login
//TODO: BUG some times after login redirect to dashboard but exists return url //TODO: BUG some times after login redirect to dashboard but exists return url
//TODO: email confirmation
//TODO: email password reset
//TODO: automapper -> Extension ToModel() ToDbo() FromModel() FromDbo() //TODO: automapper -> Extension ToModel() ToDbo() FromModel() FromDbo()
//TODO: SPA all http requests -> services
//TODO: Items, select category -> save url to allow refresh
//TODO: Accounts, select category -> save url to allow refresh
public class Program public class Program
{ {
+6
View File
@@ -15,3 +15,9 @@ wsl host folders
terminal history to file terminal history to file
history > history_for_print.txt history > history_for_print.txt
ssh remote
ssh root@192.168.1.215 'systemctl status service.name'
update remote
rsync -r --progress --exclude appsettings*.json _Published/ root@192.168.1.215:/var/www/XXX