diff --git a/MyOffice.Core/Attributes/LinkAttribute.cs b/MyOffice.Core/Attributes/LinkAttribute.cs deleted file mode 100644 index 94868e7..0000000 --- a/MyOffice.Core/Attributes/LinkAttribute.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace MyOffice.Core.Attributes; - -using System; - -[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)] -public class LinkAttribute : Attribute -{ - public LinkAttribute(Type type) - { - } -} - -[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)] -public class LinkFromAttribute : Attribute -{ - public LinkFromAttribute(Type type) - { - } -} - -[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)] -public class LinkToAttribute : Attribute -{ - public LinkToAttribute(Type type) - { - } -} - -[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)] -public class LinkWithAttribute : Attribute -{ - public LinkWithAttribute(Type type) - { - } -} \ No newline at end of file diff --git a/MyOffice.Data.Models/Accounts/AccountAccessInvite.cs b/MyOffice.Data.Models/Accounts/AccountAccessInvite.cs index 59fef7b..0827695 100644 --- a/MyOffice.Data.Models/Accounts/AccountAccessInvite.cs +++ b/MyOffice.Data.Models/Accounts/AccountAccessInvite.cs @@ -1,6 +1,5 @@ namespace MyOffice.Data.Models.Accounts; -using Core.Attributes; using Users; public class AccountAccessInvite diff --git a/MyOffice.Services/Account/Domain/AccountAccessDto.cs b/MyOffice.Services/Account/Domain/AccountAccessDto.cs index 4bfde1a..a103cd0 100644 --- a/MyOffice.Services/Account/Domain/AccountAccessDto.cs +++ b/MyOffice.Services/Account/Domain/AccountAccessDto.cs @@ -1,14 +1,9 @@ namespace MyOffice.Services.Account.Domain; using AutoMapper; -using Core.Attributes; using Data.Models.Accounts; -using Data.Models.Users; -using Mapper; using MyOffice.Services.Identity; -[Link(typeof(AccountAccess))] -[Link(typeof(AccountServiceProfile))] public class AccountAccessDto { public Guid AccountId { get; set; } @@ -33,7 +28,7 @@ public class AccountAccessDto public string? Name { get; set; } } -public class AccountAccessDtoProfile: Profile +public class AccountAccessDtoProfile : Profile { public AccountAccessDtoProfile() { @@ -43,7 +38,7 @@ public class AccountAccessDtoProfile: Profile } } -public class AccountAccessDtoMappingAction: IMappingAction +public class AccountAccessDtoMappingAction : IMappingAction { private readonly IContextProvider _contextProvider; public AccountAccessDtoMappingAction(IContextProvider contextProvider) @@ -51,8 +46,8 @@ public class AccountAccessDtoMappingAction: IMappingAction +namespace MyOffice.Services.Account.Domain; -using Core.Attributes; +using AutoMapper; using Data.Models.Accounts; -[Link(typeof(AccountAccessInvite))] public class AccountAccessInviteDto { public string Id { get; set; } = null!; public string Account { get; set; } = null!; public bool IsAllowWrite { get; set; } +} + +public class AccountAccessInviteDtoProfile: Profile +{ + public AccountAccessInviteDtoProfile() + { + CreateMap() + .ForMember(x => x.Account, o => o.MapFrom(x => x.Account!.Name)) + ; + } } \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountAccountCategoryDto.cs b/MyOffice.Services/Account/Domain/AccountAccountCategoryDto.cs index 0560f41..1867802 100644 --- a/MyOffice.Services/Account/Domain/AccountAccountCategoryDto.cs +++ b/MyOffice.Services/Account/Domain/AccountAccountCategoryDto.cs @@ -1,7 +1,19 @@ -namespace MyOffice.Services.Account.Domain; +/// +namespace MyOffice.Services.Account.Domain; + +using AutoMapper; +using MyOffice.Data.Models.Accounts; public class AccountAccountCategoryDto { public Guid CategoryId { get; set; } public AccountCategoryDto? Category { get; set; } = null!; +} + +public class AccountAccountCategoryDtoProfile: Profile +{ + public AccountAccountCategoryDtoProfile() + { + CreateMap(); + } } \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountCategoryDto.cs b/MyOffice.Services/Account/Domain/AccountCategoryDto.cs index 9c0abbc..545115a 100644 --- a/MyOffice.Services/Account/Domain/AccountCategoryDto.cs +++ b/MyOffice.Services/Account/Domain/AccountCategoryDto.cs @@ -1,4 +1,8 @@ -namespace MyOffice.Services.Account.Domain; +/// +namespace MyOffice.Services.Account.Domain; + +using AutoMapper; +using MyOffice.Data.Models.Accounts; public class AccountCategoryDto { @@ -6,4 +10,15 @@ public class AccountCategoryDto public Guid UserId { get; set; } public string Name { get; set; } = null!; public bool AllowDelete { get; set; } +} + +public class AccountCategoryDtoProfile: Profile +{ + public AccountCategoryDtoProfile() + { + CreateMap() + .ForMember(x => x.Id, o => o.MapFrom(x => x.Id)) + .ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Accounts!.Any())) + ; + } } \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/AccountDetailedDto.cs b/MyOffice.Services/Account/Domain/AccountDetailedDto.cs index 03f4d4c..4ed39a6 100644 --- a/MyOffice.Services/Account/Domain/AccountDetailedDto.cs +++ b/MyOffice.Services/Account/Domain/AccountDetailedDto.cs @@ -1,9 +1,10 @@ -using AutoMapper; +/// +namespace MyOffice.Services.Account.Domain; + +using AutoMapper; using MyOffice.Core; using MyOffice.Data.Models.Accounts; -namespace MyOffice.Services.Account.Domain; - public class AccountDetailedDto: IDataModelDto { public AccountDto Account { get; set; } = null!; diff --git a/MyOffice.Services/Account/Domain/ItemCategoryDto.cs b/MyOffice.Services/Account/Domain/ItemCategoryDto.cs index 389c699..c7b76a3 100644 --- a/MyOffice.Services/Account/Domain/ItemCategoryDto.cs +++ b/MyOffice.Services/Account/Domain/ItemCategoryDto.cs @@ -1,5 +1,7 @@ -namespace MyOffice.Services.Account.Domain; +/// +namespace MyOffice.Services.Account.Domain; +using AutoMapper; using MyOffice.Data.Models.Items; public class ItemCategoryDto @@ -10,4 +12,12 @@ public class ItemCategoryDto public string Name { get; set; } = null!; public List Items { get; set; } = null!; public bool IsInternal { get; set; } +} + +public class ItemCategoryDtoProfile: Profile +{ + public ItemCategoryDtoProfile() + { + CreateMap(); + } } \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/ItemDto.cs b/MyOffice.Services/Account/Domain/ItemDto.cs index d8ee9f4..357c601 100644 --- a/MyOffice.Services/Account/Domain/ItemDto.cs +++ b/MyOffice.Services/Account/Domain/ItemDto.cs @@ -1,5 +1,7 @@ -namespace MyOffice.Services.Account.Domain; +/// +namespace MyOffice.Services.Account.Domain; +using AutoMapper; using MyOffice.Data.Models.Items; public class ItemDto @@ -11,3 +13,15 @@ public class ItemDto public Guid CategoryId { get; set; } public ItemCategoryDto? Category { get; set; } } + +public class ItemDtoProfile: Profile +{ + public ItemDtoProfile() + { + CreateMap() + .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())) + ; + } +} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/MotionAddUpdate.cs b/MyOffice.Services/Account/Domain/MotionAddUpdate.cs index fe22da4..473dbc9 100644 --- a/MyOffice.Services/Account/Domain/MotionAddUpdate.cs +++ b/MyOffice.Services/Account/Domain/MotionAddUpdate.cs @@ -1,14 +1,22 @@ -namespace MyOffice.Services.Account.Domain +namespace MyOffice.Services.Account.Domain; + +using AutoMapper; + +public class MotionAddUpdate { - public class MotionAddUpdate - { - public DateTime Date { get; set; } - public string Item { get; set; } = null!; - public string? ItemId { get; set; } = null!; - public string? AccountId { get; set; } = null!; - public string? Description { get; set; } - public decimal Plus { get; set; } - public decimal Minus { get; set; } - public decimal AmountBalancing { get; set; } - } + public DateTime Date { get; set; } + public string Item { get; set; } = null!; + public string? ItemId { get; set; } = null!; + public string? AccountId { get; set; } = null!; + public string? Description { get; set; } + public decimal Plus { get; set; } + public decimal Minus { get; set; } + public decimal AmountBalancing { get; set; } } + +public class MotionAddUpdateProfile: Profile +{ + public MotionAddUpdateProfile() + { + } +} \ No newline at end of file diff --git a/MyOffice.Services/Account/Domain/UserDto.cs b/MyOffice.Services/Account/Domain/UserDto.cs index 7e074ef..b6939e9 100644 --- a/MyOffice.Services/Account/Domain/UserDto.cs +++ b/MyOffice.Services/Account/Domain/UserDto.cs @@ -1,5 +1,8 @@ -namespace MyOffice.Services.Account.Domain; +/// +namespace MyOffice.Services.Account.Domain; +using AutoMapper; +using MyOffice.Data.Models.Users; using MyOffice.Services.Currency.Domain; public class UserDto @@ -15,3 +18,11 @@ public class UserDto public string CurrencyId { get; set; } = null!; public CurrencyGlobalDto? Currency { get; set; } } + +public class UserDtoProfile : Profile +{ + public UserDtoProfile() + { + CreateMap(); + } +} \ No newline at end of file diff --git a/MyOffice.Services/Currency/Domain/CurrencyDto.cs b/MyOffice.Services/Currency/Domain/CurrencyDto.cs index 85e8a59..dbedf23 100644 --- a/MyOffice.Services/Currency/Domain/CurrencyDto.cs +++ b/MyOffice.Services/Currency/Domain/CurrencyDto.cs @@ -1,7 +1,8 @@ -namespace MyOffice.Services.Currency.Domain; +/// +namespace MyOffice.Services.Currency.Domain; +using AutoMapper; using MyOffice.Data.Models.Currencies; -using MyOffice.Data.Models.Users; using MyOffice.Services.Account.Domain; public class CurrencyDto @@ -21,3 +22,11 @@ public class CurrencyDto public bool IsPrimary { get; set; } } + +public class CurrencyDtoProfile: Profile +{ + public CurrencyDtoProfile() + { + CreateMap(); + } +} \ No newline at end of file diff --git a/MyOffice.Services/Currency/Domain/CurrencyGlobalDto.cs b/MyOffice.Services/Currency/Domain/CurrencyGlobalDto.cs index f0d2335..7cdaa7f 100644 --- a/MyOffice.Services/Currency/Domain/CurrencyGlobalDto.cs +++ b/MyOffice.Services/Currency/Domain/CurrencyGlobalDto.cs @@ -1,4 +1,8 @@ -namespace MyOffice.Services.Currency.Domain; +/// +namespace MyOffice.Services.Currency.Domain; + +using AutoMapper; +using MyOffice.Data.Models.Currencies; public class CurrencyGlobalDto { @@ -7,3 +11,11 @@ public class CurrencyGlobalDto public string Symbol { get; set; } = null!; public int DefaultQuantity { get; set; } } + +public class CurrencyGlobalDtoProfile: Profile +{ + public CurrencyGlobalDtoProfile() + { + CreateMap(); + } +} \ No newline at end of file diff --git a/MyOffice.Services/Currency/Domain/CurrencyRateDto.cs b/MyOffice.Services/Currency/Domain/CurrencyRateDto.cs index a3a6634..60e2f07 100644 --- a/MyOffice.Services/Currency/Domain/CurrencyRateDto.cs +++ b/MyOffice.Services/Currency/Domain/CurrencyRateDto.cs @@ -1,4 +1,8 @@ -namespace MyOffice.Services.Currency.Domain; +/// +namespace MyOffice.Services.Currency.Domain; + +using AutoMapper; +using MyOffice.Data.Models.Currencies; public class CurrencyRateDto { @@ -10,3 +14,11 @@ public class CurrencyRateDto public decimal Rate { get; set; } public List? Currencies { get; set; } } + +public class CurrencyRateDtoProfile : Profile +{ + public CurrencyRateDtoProfile() + { + CreateMap(); + } +} \ No newline at end of file diff --git a/MyOffice.Services/Dashboard/Domain/DashboardData.cs b/MyOffice.Services/Dashboard/Domain/DashboardData.cs index 88b81b5..8f34850 100644 --- a/MyOffice.Services/Dashboard/Domain/DashboardData.cs +++ b/MyOffice.Services/Dashboard/Domain/DashboardData.cs @@ -1,8 +1,6 @@ namespace MyOffice.Services.Dashboard.Domain; using System.Collections.Generic; -using System.Text.Json.Serialization; -using Data.Models.Accounts; public class DashboardData { diff --git a/MyOffice.Services/Mapper/AccountServiceProfile.cs b/MyOffice.Services/Mapper/AccountServiceProfile.cs deleted file mode 100644 index 54e0f9c..0000000 --- a/MyOffice.Services/Mapper/AccountServiceProfile.cs +++ /dev/null @@ -1,66 +0,0 @@ -namespace MyOffice.Services.Mapper; - -using Account.Domain; -using AutoMapper; -using Data.Models.Accounts; -using Data.Models.Currencies; -using Data.Models.Items; -using Data.Models.Users; -using MyOffice.Services.Currency.Domain; - -public class AccountServiceProfile : Profile -{ - public AccountServiceProfile() - { - MapUser(); - - MapAccount(); - - MapCurrency(); - - MapItems(); - - CreateMap(); - } - - private void MapUser() - { - CreateMap(); - } - - private void MapAccount() - { - CreateMap(); - - CreateMap(); - - CreateMap() - .ForMember(x => x.Id, o => o.MapFrom(x => x.Id)) - .ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Accounts!.Any())) - ; - - CreateMap() - .ForMember(x => x.Account, o => o.MapFrom(x => x.Account!.Name)) - ; - } - - private void MapCurrency() - { - CreateMap(); - - CreateMap(); - - CreateMap(); - } - - private void MapItems() - { - CreateMap(); - - CreateMap() - .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())) - ; - } -} \ No newline at end of file diff --git a/MyOffice.Web/Controllers/AccountController.cs b/MyOffice.Web/Controllers/AccountController.cs index 9c5c2d0..2060cff 100644 --- a/MyOffice.Web/Controllers/AccountController.cs +++ b/MyOffice.Web/Controllers/AccountController.cs @@ -9,13 +9,13 @@ using Microsoft.Extensions.Logging; using Models.Account; using Models.Item; using Models.Motion; +using MyOffice.Web.Infrastructure.Attributes; using Services.Account; using Services.Account.Domain; using Services.Item; [Authorize] -[ApiController] -[Route("api/[controller]")] +[DefaultFromBody] public class AccountController : BaseApiController { private readonly ILogger _logger; @@ -36,7 +36,6 @@ public class AccountController : BaseApiController _itemService = itemService; } - [HttpGet("~/api/accounts")] public ObjectResult AccountsGet(string category) { var list = _accountService.GetByCategoryDetailed(UserId, category!.AsGuid()); @@ -44,7 +43,6 @@ public class AccountController : BaseApiController return OkResponse(_mapper.Map>(list.OrderBy(x => x.Account.Name).ToList())); } - [HttpGet("~/api/accounts/{id}")] public ObjectResult AccountGet(string id) { var exec = _accountService.GetByIdDetailed(UserId, id!.AsGuid()); @@ -63,7 +61,6 @@ public class AccountController : BaseApiController } } - [HttpGet("~/api/accounts/{id}/motions")] public ObjectResult MotionsGet(string id, [FromQuery] MotionsGetRequest request) { var exec = _accountService.GetMotions(UserId, id!.AsGuid(), request.From.StartOfDay(), request.To.EndOfDay()); @@ -82,7 +79,6 @@ public class AccountController : BaseApiController } } - [HttpPost("~/api/accounts/{id}/motions")] public object MotionsPost(string id, MotionRequest motion) { var exec = _accountService.MotionAdd(UserId, id.AsGuid(), _mapper.Map(motion)); @@ -101,7 +97,6 @@ public class AccountController : BaseApiController } } - [HttpPut("~/api/accounts/{id}/motions/{motionId}")] public ObjectResult MotionsPut(string id, string motionId, MotionRequest motion) { var exec = _accountService.MotionUpdate(UserId, id.AsGuid(), motionId.AsGuid(), _mapper.Map(motion)); @@ -120,7 +115,6 @@ public class AccountController : BaseApiController } } - [HttpDelete("~/api/accounts/{id}/motions/{motionId}")] public ObjectResult MotionsDelete(string id, string motionId) { var exec = _accountService.MotionRemove(UserId, id.AsGuid(), motionId.AsGuid()); @@ -139,7 +133,6 @@ public class AccountController : BaseApiController } } - [HttpGet("~/api/items")] public ObjectResult FindItems(string term) { var itemsDto = _itemService.FindItems(UserId, term); diff --git a/MyOffice.Web/Controllers/DashboardController.cs b/MyOffice.Web/Controllers/DashboardController.cs index 6e36900..300a60a 100644 --- a/MyOffice.Web/Controllers/DashboardController.cs +++ b/MyOffice.Web/Controllers/DashboardController.cs @@ -1,51 +1,52 @@ namespace MyOffice.Web.Controllers; +using AutoMapper; using Core.Extensions; using Infrastructure.Attributes; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using MyOffice.Web.Models.Dashboard; using Services.Dashboard; [Authorize] -[ApiController] -[Route("api/[controller]")] +[DefaultFromBody] public class DashboardController : BaseApiController { private readonly ILogger _logger; private readonly DashboardService _dashboardService; + private readonly IMapper _mapper; public DashboardController( ILogger logger, - DashboardService dashboardService + DashboardService dashboardService, + IMapper mapper ) { _logger = logger; _dashboardService = dashboardService; + _mapper = mapper; } - [HttpGet("~/api/dashboard")] - public object Index() + public ObjectResult Index() { var data = _dashboardService.GetDashboardRestData(UserId); - return data; + return OkResponse(_mapper.Map(data)); } - [HttpGet("~/api/dashboard/income")] - public object Income(DateTime from, DateTime to, [AsGuid(true)] string? category) + public ObjectResult Income(DateTime from, DateTime to, [AsGuid(true)] string? category) { var data = _dashboardService.GetDashboardIncomeData(UserId, from.StartOfDay(), to.EndOfDay(), category?.AsGuidNull()); - return data; + return OkResponse(_mapper.Map(data)); } - [HttpGet("~/api/dashboard/outcome")] - public object Outcome(DateTime from, DateTime to, [AsGuid(true)] string? category) + public ObjectResult Outcome(DateTime from, DateTime to, [AsGuid(true)] string? category) { var data = _dashboardService.GetDashboardOutcomeData(UserId, from.StartOfDay(), to.EndOfDay(), category?.AsGuidNull()); - return data; + return OkResponse(_mapper.Map(data)); } } diff --git a/MyOffice.Web/Controllers/SettingsAccountCategoryController.cs b/MyOffice.Web/Controllers/SettingsAccountCategoryController.cs index 5d8102c..fdc8d51 100644 --- a/MyOffice.Web/Controllers/SettingsAccountCategoryController.cs +++ b/MyOffice.Web/Controllers/SettingsAccountCategoryController.cs @@ -1,7 +1,6 @@ namespace MyOffice.Web.Controllers; using AutoMapper; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using Core; @@ -11,10 +10,10 @@ using Services.Account; using Services.Account.Domain; using Infrastructure.Attributes; using Services.Identity; +using Microsoft.AspNetCore.Mvc; [Authorize] -[ApiController] -[Route("api/[controller]")] +[DefaultFromBody] public class SettingsAccountCategoryController : BaseApiController { private readonly ILogger _logger; @@ -35,16 +34,14 @@ public class SettingsAccountCategoryController : BaseApiController _contextProvider = contextProvider; } - [HttpGet("~/api/settings/account-categories")] - public object AccountCategories() + public ObjectResult AccountCategories() { var list = _accountService.GetAllCategories(UserId); return OkResponse(_mapper.Map>(list).OrderBy(x => x.Name)); } - [HttpGet("~/api/settings/account-categories/{id}")] - public object AccountCategory([AsGuid] string id) + public ObjectResult AccountCategory([AsGuid] string id) { var exec = _accountService.GetCategory(UserId, id.AsGuid()); @@ -55,21 +52,20 @@ public class SettingsAccountCategoryController : BaseApiController return ProblemBadResponse("Account category not found."); case GeneralExecStatus.success: - return _mapper.Map(exec.Result!); + return OkResponse(_mapper.Map(exec.Result!)); default: throw new NotSupportedException(exec.Status.ToString()); } } - [HttpPost("~/api/settings/account-categories")] - public object AccountCategoriesAdd(AccountCategoryViewModel request) + public ObjectResult AccountCategoriesAdd(AccountCategoryViewModel request) { var exec = _accountService.CategoryAdd(UserId, new AccountCategoryDto { Name = request.Name! }); switch (exec.Status) { case GeneralExecStatus.success: - return exec.Result!; + return OkResponse(_mapper.Map(exec.Result!)); case GeneralExecStatus.failure: case GeneralExecStatus.not_found: @@ -80,14 +76,13 @@ public class SettingsAccountCategoryController : BaseApiController } } - [HttpPut("~/api/settings/account-categories/{id}")] - public object AccountCategoriesEdit([AsGuid] string id, AccountCategoryViewModel request) + public ObjectResult AccountCategoriesUpdate([AsGuid] string id, AccountCategoryViewModel request) { var exec = _accountService.CategoryUpdate(UserId, id.AsGuid(), new AccountCategoryDto { Name = request.Name! }); switch (exec.Status) { case GeneralExecStatus.success: - return exec.Result!; + return OkResponse(_mapper.Map(exec.Result!)); case GeneralExecStatus.failure: case GeneralExecStatus.not_found: @@ -98,14 +93,13 @@ public class SettingsAccountCategoryController : BaseApiController } } - [HttpDelete("~/api/settings/account-categories/{id}")] - public object AccountCategoriesDelete([AsGuid] string id) + public ObjectResult AccountCategoriesDelete([AsGuid] string id) { var exec = _accountService.CategoryRemove(UserId, id.AsGuid()); switch (exec.Status) { case AccountCategoryRemoveResult.success: - return exec.Result!; + return OkResponse(_mapper.Map(exec.Result!)); case AccountCategoryRemoveResult.failure: return ProblemBadResponse("Remove account category failed."); diff --git a/MyOffice.Web/Controllers/SettingsAccountController.cs b/MyOffice.Web/Controllers/SettingsAccountController.cs index 86df420..c51a0a4 100644 --- a/MyOffice.Web/Controllers/SettingsAccountController.cs +++ b/MyOffice.Web/Controllers/SettingsAccountController.cs @@ -13,8 +13,7 @@ using Infrastructure.Attributes; using Services.Identity; [Authorize] -[ApiController] -[Route("api/[controller]")] +[DefaultFromBody] public class SettingsAccountController : BaseApiController { private readonly ILogger _logger; @@ -35,17 +34,15 @@ public class SettingsAccountController : BaseApiController _contextProvider = contextProvider; } - [HttpGet("~/api/settings/accounts")] public ObjectResult AccountsGet([AsGuid(true)] string? category) { var list = category.IsPresent() ? _accountService.GetByCategory(UserId, category!.AsGuid()) : _accountService.GetAllAccounts(UserId); - return OkResponse(list.ToViewModel(_mapper)); + return OkResponse(_mapper.Map>(list.OrderBy(x => x.Name))); } - //[HttpPost("~/api/settings/accounts")] public object AccountsAdd(AccountViewModel request) { var exec = _accountService.AccountAdd(UserId, new AccountAdd @@ -73,8 +70,7 @@ public class SettingsAccountController : BaseApiController } - [HttpPut("~/api/settings/accounts/{id}")] - public object AccountsAdd([AsGuid] string id, AccountEditRequestModel request) + public object AccountsUpdate([AsGuid] string id, AccountEditRequestModel request) { var exec = _accountService.AccountUpdate(UserId, id.AsGuid(), new AccountEdit { @@ -103,7 +99,6 @@ public class SettingsAccountController : BaseApiController } } - [HttpDelete("~/api/settings/accounts/{id}")] public object AccountsDelete([AsGuid] string id) { var exec = _accountService.AccountDelete(UserId, id); @@ -119,8 +114,7 @@ public class SettingsAccountController : BaseApiController } } - [HttpDelete("~/api/settings/accounts/{id}/category/{categoryId}")] - public object AccountsCategoryRemove([AsGuid] string id, [AsGuid] string categoryId) + public object AccountsCategoryDelete([AsGuid] string id, [AsGuid] string categoryId) { var exec = _accountService.AccountCategoryRemove(UserId, id.AsGuid(), categoryId.AsGuid()); @@ -138,8 +132,7 @@ public class SettingsAccountController : BaseApiController } } - [HttpPost("~/api/settings/accounts/{id}/access")] - public object AccountsAdd([AsGuid] string id, AccountAccessViewModel request) + public object AccountsAccessAdd([AsGuid] string id, AccountAccessViewModel request) { var model = _mapper.Map>(request.Accesses); @@ -180,8 +173,7 @@ public class SettingsAccountController : BaseApiController } } - [HttpDelete("~/api/settings/accounts/{id}/access/{userId}")] - public object AccountsAdd([AsGuid] string id, [AsGuid] string userId) + public object AccountsAccessDelete([AsGuid] string id, [AsGuid] string userId) { var exec = _accountService.AccessDelete(UserId, id.AsGuid(), userId.AsGuid()); @@ -199,7 +191,6 @@ public class SettingsAccountController : BaseApiController } } - [HttpGet("~/api/settings/accounts/invites")] public List AccountInvites() { var invites = _accountService.InvitesGet(_contextProvider.User.Email); @@ -207,8 +198,7 @@ public class SettingsAccountController : BaseApiController return _mapper.Map>(invites); } - [HttpPost("~/api/settings/accounts/invites/{id}/accept")] - public object AccountInviteAccept([AsGuid]string id, AccountInviteAcceptRequest request) + public object AccountInviteAccept([AsGuid] string id, AccountInviteAcceptRequest request) { var exec = _accountService.InviteAccept(UserId, id.AsGuid(), request.Name); @@ -228,7 +218,6 @@ public class SettingsAccountController : BaseApiController } } - [HttpPost("~/api/settings/accounts/invites/{id}/reject")] public object AccountInviteReject([AsGuid] string id) { var exec = _accountService.InviteReject(id.AsGuid()); diff --git a/MyOffice.Web/Controllers/CurrencyController.cs b/MyOffice.Web/Controllers/SettingsCurrencyController.cs similarity index 94% rename from MyOffice.Web/Controllers/CurrencyController.cs rename to MyOffice.Web/Controllers/SettingsCurrencyController.cs index 3f4fd4d..d7547e1 100644 --- a/MyOffice.Web/Controllers/CurrencyController.cs +++ b/MyOffice.Web/Controllers/SettingsCurrencyController.cs @@ -12,15 +12,15 @@ using Services.Currency.Domain; [Authorize] [DefaultFromBody] -public class CurrencyController : BaseApiController +public class SettingCurrencyController : BaseApiController { private readonly CurrencyService _currencyService; - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IMapper _mapper; - public CurrencyController( + public SettingCurrencyController( CurrencyService currencyService, - ILogger logger, + ILogger logger, IMapper mapper ) { diff --git a/MyOffice.Web/Controllers/SettingsItemController.cs b/MyOffice.Web/Controllers/SettingsItemController.cs index 40ab898..a74e40d 100644 --- a/MyOffice.Web/Controllers/SettingsItemController.cs +++ b/MyOffice.Web/Controllers/SettingsItemController.cs @@ -12,8 +12,7 @@ using Services.Item; using Services.Item.Domain; [Authorize] -[ApiController] -[Route("api/[controller]")] +[DefaultFromBody] public class SettingsItemController : BaseApiController { private ILogger _logger; @@ -31,7 +30,6 @@ public class SettingsItemController : BaseApiController _mapper = mapper; } - [HttpGet("~/api/settings/item-categories")] public ObjectResult ItemsCategories() { var list = _itemService.GetAllCategories(UserId); @@ -41,7 +39,6 @@ public class SettingsItemController : BaseApiController .ThenBy(x => x.Name)); } - [HttpPost("~/api/settings/item-categories")] public ObjectResult ItemCategoriesAdd(ItemCategoryViewModel request) { var exec = _itemService.CategoryAdd(UserId, request.FromModel()); @@ -60,7 +57,6 @@ public class SettingsItemController : BaseApiController } } - [HttpPut("~/api/settings/item-categories/{id}")] public ObjectResult ItemCategoriesUpdate([AsGuid] string id, ItemCategoryViewModel request) { var exec = _itemService.CategoryUpdate(UserId, id.AsGuid(), request.FromModel()); @@ -79,7 +75,6 @@ public class SettingsItemController : BaseApiController } } - [HttpDelete("~/api/settings/item-categories/{id}")] public ObjectResult ItemCategoriesDelete([AsGuid] string id) { var exec = _itemService.CategoryRemove(UserId, id.AsGuid()); @@ -100,7 +95,6 @@ public class SettingsItemController : BaseApiController } } - [HttpGet("~/api/settings/items")] public ObjectResult Items([AsGuid] string category) { var categoryId = category.AsGuid(); @@ -112,8 +106,7 @@ public class SettingsItemController : BaseApiController return Ok(_mapper.Map>(list.OrderBy(x => x.Name))); } - [HttpPut("~/api/settings/items/{id}")] - public ObjectResult Items([AsGuid] string id, ItemEditModel request) + public ObjectResult ItemsUpdate([AsGuid] string id, ItemEditModel request) { var exec = _itemService.Update(UserId, id.AsGuid(), request.Category.AsGuid()); @@ -131,8 +124,7 @@ public class SettingsItemController : BaseApiController } } - [HttpPost("~/api/settings/items")] - public ObjectResult Items(ItemChangeCategoryModel request) + public ObjectResult ItemsPost(ItemChangeCategoryModel request) { var exec = _itemService.UpdateItemsCategory(UserId, request.category.AsGuid(), request.Items.Select(x => x.AsGuid()).ToList()); diff --git a/MyOffice.Web/Controllers/UserController.cs b/MyOffice.Web/Controllers/UserController.cs index 1c9d0b1..b61772b 100644 --- a/MyOffice.Web/Controllers/UserController.cs +++ b/MyOffice.Web/Controllers/UserController.cs @@ -14,9 +14,9 @@ using Core; using Services.Users; using Services.Users.Domain; using MyOffice.Data.Models.Currencies; +using MyOffice.Web.Infrastructure.Attributes; -[ApiController] -[Route("api/[controller]")] +[DefaultFromBody] public class UserController : BaseApiController { private readonly UserManager> _userManager; @@ -34,7 +34,6 @@ public class UserController : BaseApiController _externalProviderValidators = externalProviderValidators; } - [HttpPost("~/api/user/register")] public async Task Register([FromBody] RegisterModel request) { var user = new ApplicationUser @@ -55,7 +54,6 @@ public class UserController : BaseApiController } [Authorize] - [HttpGet("~/api/user/profile")] public async Task ProfileGet() { var user = await _userManager.GetUserAsync(User); @@ -64,7 +62,6 @@ public class UserController : BaseApiController } [Authorize] - [HttpPost("~/api/user/profile")] public async Task ProfileUpdate([FromBody] ProfileModel model) { var user = await _userManager.GetUserAsync(User); @@ -80,7 +77,6 @@ public class UserController : BaseApiController } [Authorize] - [HttpPost("~/api/user/attach")] public async Task AttachProvider([FromBody] AttachModel model) { var validator = _externalProviderValidators.FirstOrDefault(x => x.Provider.EqualsIgnoreCase(model.Provider)); @@ -108,7 +104,6 @@ public class UserController : BaseApiController } [Authorize] - [HttpPost("~/api/user/deattach")] public async Task DeattachProvider([FromBody] DeattachModel model) { var exec = await _userService.RemoveUserExternal(UserId, model.Provider); diff --git a/MyOffice.Web/Infrastructure/Attributes/DefaultFromBodyAttribute.cs b/MyOffice.Web/Infrastructure/Attributes/DefaultFromBodyAttribute.cs index 7f13195..5f249c1 100644 --- a/MyOffice.Web/Infrastructure/Attributes/DefaultFromBodyAttribute.cs +++ b/MyOffice.Web/Infrastructure/Attributes/DefaultFromBodyAttribute.cs @@ -1,9 +1,6 @@ namespace MyOffice.Web.Infrastructure.Attributes; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApplicationModels; -using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.ModelBinding; [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] @@ -11,28 +8,6 @@ public sealed class DefaultFromBodyAttribute : Attribute { } -public class GlobalModelStateValidatorAttribute : ActionFilterAttribute -{ - private readonly ProblemDetailsFactory _problemDetailsFactory; - - public GlobalModelStateValidatorAttribute(ProblemDetailsFactory problemDetailsFactory) - { - _problemDetailsFactory = problemDetailsFactory; - } - - public override void OnActionExecuting(ActionExecutingContext context) - { - if (!context.ModelState.IsValid) - { - context.Result = new ObjectResult(_problemDetailsFactory.CreateValidationProblemDetails(context.HttpContext, context.ModelState)) - { - StatusCode = StatusCodes.Status400BadRequest - }; - } - - base.OnActionExecuting(context); - } -} public class DefaultFromBodyBindingConvention : IActionModelConvention { public void Apply(ActionModel action) @@ -43,13 +18,16 @@ public class DefaultFromBodyBindingConvention : IActionModelConvention } if (action.Controller.Attributes.Any(a => a is DefaultFromBodyAttribute)) - { + { foreach (var parameter in action.Parameters) { var paramType = parameter.ParameterInfo.ParameterType; var isSimpleType = paramType.IsPrimitive || paramType.IsEnum || paramType == typeof(string) + || paramType == typeof(int) + || paramType == typeof(Guid) + || paramType == typeof(DateTime) || paramType == typeof(decimal); if (!isSimpleType) diff --git a/MyOffice.Web/Infrastructure/Attributes/GlobalModelStateValidatorAttribute.cs b/MyOffice.Web/Infrastructure/Attributes/GlobalModelStateValidatorAttribute.cs new file mode 100644 index 0000000..fa8d645 --- /dev/null +++ b/MyOffice.Web/Infrastructure/Attributes/GlobalModelStateValidatorAttribute.cs @@ -0,0 +1,28 @@ +namespace MyOffice.Web.Infrastructure.Attributes; + +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc.Infrastructure; + +public class GlobalModelStateValidatorAttribute : ActionFilterAttribute +{ + private readonly ProblemDetailsFactory _problemDetailsFactory; + + public GlobalModelStateValidatorAttribute(ProblemDetailsFactory problemDetailsFactory) + { + _problemDetailsFactory = problemDetailsFactory; + } + + public override void OnActionExecuting(ActionExecutingContext context) + { + if (!context.ModelState.IsValid) + { + context.Result = new ObjectResult(_problemDetailsFactory.CreateValidationProblemDetails(context.HttpContext, context.ModelState)) + { + StatusCode = StatusCodes.Status400BadRequest + }; + } + + base.OnActionExecuting(context); + } +} diff --git a/MyOffice.Web/Infrastructure/Filters/ResponseFilter.cs b/MyOffice.Web/Infrastructure/Filters/ResponseFilter.cs new file mode 100644 index 0000000..b4cd3d5 --- /dev/null +++ b/MyOffice.Web/Infrastructure/Filters/ResponseFilter.cs @@ -0,0 +1,45 @@ +namespace MyOffice.Web.Infrastructure.Filters; + +using System.Collections; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using MyOffice.Web.Models; + +public class ResponseFilter : IActionFilter +{ + private readonly ILogger _logger; + + public ResponseFilter(ILogger logger) + { + _logger = logger; + } + + public void OnActionExecuting(ActionExecutingContext context) + { + } + + public void OnActionExecuted(ActionExecutedContext context) + { + if (context.Result == null) + throw new NotSupportedException($"Response must be - empty"); + if (!(context.Result is ObjectResult result)) + throw new NotSupportedException($"Response must be an ObjectResult - {context.Result?.GetType().Name}"); + if (result.Value == null) + throw new NotSupportedException($"Response must be an ObjectResult - empty"); + + if (result.Value is IResponseModel) + { + return; + } + + var type = result.Value.GetType(); + if (type.IsGenericType + && result.Value is IEnumerable + && type.GenericTypeArguments.Any(x => x.GetInterfaces().Any(y => y == typeof(IResponseModel)))) + { + return; + } + + throw new NotSupportedException($"Response must be an ObjectResult with an IResponseModel - {result.Value?.GetType().Name}"); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/AccessRightsViewModel.cs b/MyOffice.Web/Models/Account/AccessRightsViewModel.cs index 0edd940..108f2f8 100644 --- a/MyOffice.Web/Models/Account/AccessRightsViewModel.cs +++ b/MyOffice.Web/Models/Account/AccessRightsViewModel.cs @@ -1,5 +1,8 @@ namespace MyOffice.Web.Models.Account; +using AutoMapper; +using MyOffice.Services.Account.Domain; +using MyOffice.Services.Identity; using User; public class AccessRightsViewModel @@ -11,3 +14,28 @@ public class AccessRightsViewModel public bool AllowDelete { get; set; } public bool IsOwner { get; set; } } + +public class AccessRightsViewModelProfile : Profile +{ + public AccessRightsViewModelProfile() + { + CreateMap() + .AfterMap() + ; + + } +} + +public class AccessRightsViewModelMappingAction : IMappingAction +{ + private readonly IContextProvider _contextProvider; + + public AccessRightsViewModelMappingAction(IContextProvider contextProvider) + { + _contextProvider = contextProvider; + } + + public void Process(AccountAccessDto source, AccessRightsViewModel destination, ResolutionContext context) + { + } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/AccountAccessInviteViewModel.cs b/MyOffice.Web/Models/Account/AccountAccessInviteViewModel.cs index 6fbaf55..43cc3c9 100644 --- a/MyOffice.Web/Models/Account/AccountAccessInviteViewModel.cs +++ b/MyOffice.Web/Models/Account/AccountAccessInviteViewModel.cs @@ -1,13 +1,21 @@ namespace MyOffice.Web.Models.Account; -using Core.Attributes; -using Services.Account.Domain; +using AutoMapper; +using MyOffice.Services.Account.Domain; -[LinkFrom(typeof(AccountAccessInviteDto))] -[LinkWith(typeof(AccountViewModelProfile))] public class AccountAccessInviteViewModel { public string? Id { get; set; } public string? Account { get; set; } public bool? AllowWrite { get; set; } +} + +public class AccountAccessInviteViewModelProfile: Profile +{ + public AccountAccessInviteViewModelProfile() + { + CreateMap() + .ForMember(x => x.AllowWrite, o => o.MapFrom(x => x.IsAllowWrite)) + ; + } } \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/AccountAccessViewModel.cs b/MyOffice.Web/Models/Account/AccountAccessViewModel.cs new file mode 100644 index 0000000..90046b7 --- /dev/null +++ b/MyOffice.Web/Models/Account/AccountAccessViewModel.cs @@ -0,0 +1,24 @@ +using AutoMapper; +using MyOffice.Services.Account.Domain; + +namespace MyOffice.Web.Models.Account; + +public class AccountAccessViewModel +{ + public class AccountAccessItemViewModel + { + public string UserId { get; set; } = null!; + public bool AllowWrite { get; set; } + } + + public string? Email { get; set; } + public bool AllowWrite { get; set; } + public List Accesses { get; set; } = null!; +} + +public class AccountAccessItemViewModelProfile : Profile +{ + public AccountAccessItemViewModelProfile() + { + } +} diff --git a/MyOffice.Web/Models/Account/AccountCategoryViewModel.cs b/MyOffice.Web/Models/Account/AccountCategoryViewModel.cs index 24493a2..b36df26 100644 --- a/MyOffice.Web/Models/Account/AccountCategoryViewModel.cs +++ b/MyOffice.Web/Models/Account/AccountCategoryViewModel.cs @@ -1,10 +1,9 @@ namespace MyOffice.Web.Models.Account; -using MyOffice.Core.Attributes; -using MyOffice.Services.Account.Domain; using System.ComponentModel.DataAnnotations; +using AutoMapper; +using MyOffice.Services.Account.Domain; -[Link(typeof(AccountCategoryDto))] public class AccountCategoryViewModel: IResponseModel { public string? Id { get; set; } @@ -13,4 +12,19 @@ public class AccountCategoryViewModel: IResponseModel public string? Name { get; set; } public bool? AllowDelete { get; set; } +} + +public class AccountCategoryViewModelProfile: Profile +{ + public AccountCategoryViewModelProfile() + { + CreateMap() + .ForMember(x => x.Id, o => o.MapFrom(x => x.CategoryId)) + .ForMember(x => x.Name, o => o.MapFrom(x => x.Category!.Name)) + ; + CreateMap() + .ForMember(x => x.Id, o => o.MapFrom(x => x.Id)) + .ForMember(x => x.Name, o => o.MapFrom(x => x.Name)) + ; + } } \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/AccountDetailedViewModel.cs b/MyOffice.Web/Models/Account/AccountDetailedViewModel.cs index d5a736d..63b1448 100644 --- a/MyOffice.Web/Models/Account/AccountDetailedViewModel.cs +++ b/MyOffice.Web/Models/Account/AccountDetailedViewModel.cs @@ -1,7 +1,20 @@ namespace MyOffice.Web.Models.Account; +using AutoMapper; +using MyOffice.Services.Account.Domain; + public class AccountDetailedViewModel: BaseViewModel { public AccountViewModel Account { get; set; } = null!; public decimal Rest { get; set; } } + +public class AccountDetailedViewModelProfile: Profile +{ + public AccountDetailedViewModelProfile() + { + CreateMap() + .ForMember(x => x.Account, o => o.MapFrom(x => x.Account)) + ; + } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/Account/AccountViewModel.cs b/MyOffice.Web/Models/Account/AccountViewModel.cs index ac7c43c..5ee5a51 100644 --- a/MyOffice.Web/Models/Account/AccountViewModel.cs +++ b/MyOffice.Web/Models/Account/AccountViewModel.cs @@ -34,27 +34,6 @@ public class AccountViewModel: IResponseModel #endregion Permissions } -public static class AccountViewModelExtensions -{ - public static List ToViewModel(this List accounts, IMapper mapper) - { - return mapper.Map>(accounts.OrderBy(x => x.Name)); - } -} - -public class AccountAccessViewModel -{ - public class AccountAccessItemViewModel - { - public string UserId { get; set; } = null!; - public bool AllowWrite { get; set; } - } - - public string? Email { get; set; } - public bool AllowWrite { get; set; } - public List Accesses { get; set; } = null!; -} - public class AccountViewModelProfile : Profile { public AccountViewModelProfile() @@ -64,31 +43,19 @@ public class AccountViewModelProfile : Profile .ForMember(x => x.CurrencyName, o => o.MapFrom(x => x.Currency!.Name)) .AfterMap() ; - - CreateMap() - .AfterMap() - ; - } } public class AccountViewModelMappingAction : IMappingAction -{ - public void Process(AccountDto source, AccountViewModel destination, ResolutionContext context) - { - } -} - -public class AccessRightsViewModelMappingAction : IMappingAction { private readonly IContextProvider _contextProvider; - public AccessRightsViewModelMappingAction(IContextProvider contextProvider) + public AccountViewModelMappingAction(IContextProvider contextProvider) { _contextProvider = contextProvider; } - public void Process(AccountAccessDto source, AccessRightsViewModel destination, ResolutionContext context) + public void Process(AccountDto source, AccountViewModel destination, ResolutionContext context) { } -} \ No newline at end of file +} diff --git a/MyOffice.Web/Models/Account/AccountViewModelProfile.cs b/MyOffice.Web/Models/Account/AccountViewModelProfile.cs index 1bcb558..5a8b582 100644 --- a/MyOffice.Web/Models/Account/AccountViewModelProfile.cs +++ b/MyOffice.Web/Models/Account/AccountViewModelProfile.cs @@ -30,79 +30,19 @@ using MyOffice.Services.Identity; } }*/ -public class PublicationSystemResolver : IMemberValueResolver +/*public class PublicationSystemResolver : IMemberValueResolver { - private readonly IContextProvider _contextProvider; + private readonly IContextProvider _contextProvider; - public PublicationSystemResolver( + public PublicationSystemResolver( IContextProvider contextProvider ) - { - this._contextProvider = contextProvider; - } - - public bool Resolve(object source, object destination, string sourceMember, bool destMember, ResolutionContext context) - { - return true; - } -} - -public class AccountViewModelGeneralProfile : Profile -{ - public AccountViewModelGeneralProfile() { - CreateMap() - .ForMember(x => x.Account, o => o.MapFrom(x => x.Account)) - ; - - CreateMap(); - - CreateMap(); - - CreateMap() - .ForMember(x => x.Id, o => o.MapFrom(x => x.CategoryId)) - .ForMember(x => x.Name, o => o.MapFrom(x => x.Category!.Name)) - ; - - CreateMap() - .ForMember(x => x.IsAllowWrite, o => o.MapFrom(x => x.AllowWrite)) - ; - - CreateMap() - ; - - CreateMap() - .ForMember(x => x.AllowWrite, o => o.MapFrom(x => x.IsAllowWrite)) - ; - - CreateMap() - ; - - CreateMap() - .ForMember(x => x.Category, o => o.MapFrom(x => x.Category!.Name)) - ; - - CreateMap() - .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(); - - CreateMap(); - - CreateMap(); - - CreateMap() - .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)) - ; + this._contextProvider = contextProvider; } -} \ No newline at end of file + + public bool Resolve(object source, object destination, string sourceMember, bool destMember, ResolutionContext context) + { + return true; + } +}*/ \ No newline at end of file diff --git a/MyOffice.Web/Models/Currency/CurrencyGlobalViewModel.cs b/MyOffice.Web/Models/Currency/CurrencyGlobalViewModel.cs index 4e51ac2..a6d160e 100644 --- a/MyOffice.Web/Models/Currency/CurrencyGlobalViewModel.cs +++ b/MyOffice.Web/Models/Currency/CurrencyGlobalViewModel.cs @@ -1,27 +1,22 @@ -namespace MyOffice.Web.Models.Currency +/// +/// +namespace MyOffice.Web.Models.Currency; + +using AutoMapper; +using MyOffice.Services.Currency.Domain; + +public class CurrencyGlobalViewModel { - using Data.Models.Currencies; - using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; - - public class CurrencyGlobalViewModel - { - public string Id { get; set; } = null!; - public string Name { get; set; } = null!; - public int Quantity { get; set; } - public string Symbol { get; set; } = null!; - } - - public static class CurrencyGlobalViewModelExtensions - { - public static CurrencyGlobalViewModel ToModel(this CurrencyGlobal input) - { - return new CurrencyGlobalViewModel - { - Id = input.Id, - Name = input.Name, - Quantity = input.DefaultQuantity, - Symbol = input.Symbol, - }; - } - } + public string Id { get; set; } = null!; + public string Name { get; set; } = null!; + public int Quantity { get; set; } + public string Symbol { get; set; } = null!; } + +public class CurrencyGlobalViewModelProfile : Profile +{ + public CurrencyGlobalViewModelProfile() + { + CreateMap(); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/Currency/CurrencyRateViewModel.cs b/MyOffice.Web/Models/Currency/CurrencyRateViewModel.cs index 9f47435..0b6f26c 100644 --- a/MyOffice.Web/Models/Currency/CurrencyRateViewModel.cs +++ b/MyOffice.Web/Models/Currency/CurrencyRateViewModel.cs @@ -1,9 +1,20 @@ namespace MyOffice.Web.Models.Currency; +using AutoMapper; +using MyOffice.Services.Currency.Domain; + public class CurrencyRateViewModel: BaseViewModel { public string Currency { get; set; } = null!; public DateTime DateTime { get; set; } public int Quantity { get; set; } public decimal Rate { get; set; } +} + +public class CurrencyRateViewModelProfile: Profile +{ + public CurrencyRateViewModelProfile() + { + CreateMap(); + } } \ No newline at end of file diff --git a/MyOffice.Web/Models/Currency/CurrencyViewModel.cs b/MyOffice.Web/Models/Currency/CurrencyViewModel.cs index b49f64c..efade2f 100644 --- a/MyOffice.Web/Models/Currency/CurrencyViewModel.cs +++ b/MyOffice.Web/Models/Currency/CurrencyViewModel.cs @@ -1,5 +1,8 @@ namespace MyOffice.Web.Models.Currency; +using AutoMapper; +using MyOffice.Services.Currency.Domain; + public class CurrencyViewModel: BaseViewModel { public string Id { get; set; } = null!; @@ -11,4 +14,23 @@ public class CurrencyViewModel: BaseViewModel public int? Quantity { get; set; } public DateTime? RateDate { get; set; } public bool IsPrimary { get; set; } +} + +public class CurrencyViewModelProfile: Profile +{ + public CurrencyViewModelProfile() + { + CreateMap(); + + CreateMap() + .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)) + ; + } } \ No newline at end of file diff --git a/MyOffice.Web/Models/Dashboard/DashboardIncomeDataViewModel.cs b/MyOffice.Web/Models/Dashboard/DashboardIncomeDataViewModel.cs new file mode 100644 index 0000000..8af7fb0 --- /dev/null +++ b/MyOffice.Web/Models/Dashboard/DashboardIncomeDataViewModel.cs @@ -0,0 +1,17 @@ +namespace MyOffice.Web.Models.Dashboard; + +using AutoMapper; +using MyOffice.Services.Dashboard.Domain; + +public class DashboardIncomeDataViewModel : DashboardIncomeData, IResponseModel +{ + +} + +public class DashboardIncomeDataViewModelProfile : Profile +{ + public DashboardIncomeDataViewModelProfile() + { + CreateMap(); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/Dashboard/DashboardViewModel.cs b/MyOffice.Web/Models/Dashboard/DashboardViewModel.cs new file mode 100644 index 0000000..42d4b46 --- /dev/null +++ b/MyOffice.Web/Models/Dashboard/DashboardViewModel.cs @@ -0,0 +1,17 @@ +namespace MyOffice.Web.Models.Dashboard; + +using AutoMapper; +using MyOffice.Services.Dashboard.Domain; + +public class DashboardViewModel : DashboardData, IResponseModel +{ + +} + +public class DashboardViewModelProfile : Profile +{ + public DashboardViewModelProfile() + { + CreateMap(); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/Item/ItemCategoryViewModel.cs b/MyOffice.Web/Models/Item/ItemCategoryViewModel.cs index 4c9256e..25e6417 100644 --- a/MyOffice.Web/Models/Item/ItemCategoryViewModel.cs +++ b/MyOffice.Web/Models/Item/ItemCategoryViewModel.cs @@ -1,32 +1,45 @@ -namespace MyOffice.Web.Models.Item +namespace MyOffice.Web.Models.Item; + +using System.ComponentModel.DataAnnotations; +using AutoMapper; +using Services.Account.Domain; + +public class ItemCategoryViewModel { - using System.ComponentModel.DataAnnotations; - using Services.Account.Domain; + public string? Id { get; set; } - public class ItemCategoryViewModel + [Required] + public string Name { get; set; } = null!; + + public bool AllowDelete { get; set; } + public int SortOrder { get; set; } + public bool Internal { get; set; } +} + +//TODO: REMOVE +public static class ItemCategoryViewModelExtensions +{ + public static ItemCategoryDto FromModel(this ItemCategoryViewModel input) { - public string? Id { get; set; } + if (input == null) + throw new ArgumentNullException(nameof(input)); - [Required] - public string Name { get; set; } = null!; - - public bool AllowDelete { get; set; } - public int SortOrder { get; set; } - public bool Internal { get; set; } - } - - public static class ItemCategoryViewModelExtensions - { - public static ItemCategoryDto FromModel(this ItemCategoryViewModel input) + return new ItemCategoryDto { - if (input == null) - throw new ArgumentNullException(nameof(input)); - - return new ItemCategoryDto - { - Name = input.Name, - IsInternal = input.Internal, - }; - } + Name = input.Name, + IsInternal = input.Internal, + }; } } + +public class ItemCategoryViewModelProfile: Profile +{ + public ItemCategoryViewModelProfile() + { + CreateMap() + .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)) + ; + } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/Item/ItemViewModel.cs b/MyOffice.Web/Models/Item/ItemViewModel.cs index e68d502..33a0a12 100644 --- a/MyOffice.Web/Models/Item/ItemViewModel.cs +++ b/MyOffice.Web/Models/Item/ItemViewModel.cs @@ -1,6 +1,8 @@ namespace MyOffice.Web.Models.Item; using System.ComponentModel.DataAnnotations; +using AutoMapper; +using MyOffice.Services.Account.Domain; public class ItemViewModel : BaseViewModel { @@ -15,3 +17,13 @@ public class ItemViewModel : BaseViewModel public string? AccountId { get; set; } } + +public class ItemViewModelProfile: Profile +{ + public ItemViewModelProfile() + { + CreateMap() + .ForMember(x => x.Category, o => o.MapFrom(x => x.Category!.Name)) + ; + } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/Motion/AccountControllerProfile.cs b/MyOffice.Web/Models/Motion/AccountControllerProfile.cs index 8508dad..c976d20 100644 --- a/MyOffice.Web/Models/Motion/AccountControllerProfile.cs +++ b/MyOffice.Web/Models/Motion/AccountControllerProfile.cs @@ -8,8 +8,6 @@ public class AccountControllerProfile : Profile { public AccountControllerProfile() { - CreateMap(); - CreateMap() .ForMember(x => x.Date, o => o.MapFrom(x => x.DateTime)) .ForMember(x => x.Item, o => o.MapFrom(x => x.Item.ItemGlobal.Name)) diff --git a/MyOffice.Web/Models/Motion/MotionRequest.cs b/MyOffice.Web/Models/Motion/MotionRequest.cs index 46753f9..a4f2bc8 100644 --- a/MyOffice.Web/Models/Motion/MotionRequest.cs +++ b/MyOffice.Web/Models/Motion/MotionRequest.cs @@ -1,5 +1,8 @@ namespace MyOffice.Web.Models.Motion; +using AutoMapper; +using MyOffice.Services.Account.Domain; + public class MotionRequest { public DateTime Date { get; set; } @@ -10,4 +13,12 @@ public class MotionRequest public decimal? Plus { get; set; } public decimal? Minus { get; set; } public decimal? AmountBalancing { get; set; } +} + +public class MotionRequestProfile : Profile +{ + public MotionRequestProfile() + { + CreateMap(); + } } \ No newline at end of file diff --git a/MyOffice.Web/Models/Motion/MotionViewModel.cs b/MyOffice.Web/Models/Motion/MotionViewModel.cs index f9a46fa..5160846 100644 --- a/MyOffice.Web/Models/Motion/MotionViewModel.cs +++ b/MyOffice.Web/Models/Motion/MotionViewModel.cs @@ -1,13 +1,23 @@ -namespace MyOffice.Web.Models.Motion +namespace MyOffice.Web.Models.Motion; + +using AutoMapper; +using MyOffice.Services.Account.Domain; + +public class MotionViewModel : BaseViewModel { - public class MotionViewModel: BaseViewModel - { - public string Id { get; set; } = null!; - public DateTime Date { get; set; } - public string AccountId { get; set; } = null!; - public string Item { get; set; } = null!; - public string? Description { get; set; } - public decimal Plus { get; set; } - public decimal Minus { get; set; } - } + public string Id { get; set; } = null!; + public DateTime Date { get; set; } + public string AccountId { get; set; } = null!; + public string Item { get; set; } = null!; + public string? Description { get; set; } + public decimal Plus { get; set; } + public decimal Minus { get; set; } } + +public class MotionViewModelProfile : Profile +{ + public MotionViewModelProfile() + { + CreateMap(); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Models/User/UserViewModel.cs b/MyOffice.Web/Models/User/UserViewModel.cs index 317ab59..03d8b8b 100644 --- a/MyOffice.Web/Models/User/UserViewModel.cs +++ b/MyOffice.Web/Models/User/UserViewModel.cs @@ -1,7 +1,7 @@ namespace MyOffice.Web.Models.User; -using Core.Extensions; -using MyOffice.Data.Models.Users; +using AutoMapper; +using MyOffice.Services.Account.Domain; public class UserViewModel { @@ -9,3 +9,11 @@ public class UserViewModel public string UserName { get; set; } = null!; public string Email { get; set; } = null!; } + +public class UserViewModelProfile: Profile +{ + public UserViewModelProfile() + { + CreateMap(); + } +} \ No newline at end of file diff --git a/MyOffice.Web/Program.Routes.cs b/MyOffice.Web/Program.Routes.cs index d887f3d..9f507e5 100644 --- a/MyOffice.Web/Program.Routes.cs +++ b/MyOffice.Web/Program.Routes.cs @@ -5,13 +5,62 @@ public partial class Program private static void MapRoutes(WebApplication app) { MapRoute(app, Routes.GlobalCurrencies, "General", "GetGlobalCurrencies", HttpMethod.Get); - + // Settings Currency - MapRoute(app, Routes.SettingsCurrencies, "Currency", "Get", HttpMethod.Get); - MapRoute(app, Routes.SettingsCurrencies, "Currency", "Add", HttpMethod.Post); - MapRoute(app, Routes.SettingsCurrency, "Currency", "Update", HttpMethod.Put); - MapRoute(app, Routes.SettingsCurrency, "Currency", "Delete", HttpMethod.Delete); - MapRoute(app, Routes.SettingsCurrencyRate, "Currency", "AddRate", HttpMethod.Post); + MapRoute(app, Routes.SettingsCurrencies, "SettingCurrency", "Get", HttpMethod.Get); + MapRoute(app, Routes.SettingsCurrencies, "SettingCurrency", "Add", HttpMethod.Post); + MapRoute(app, Routes.SettingsCurrency, "SettingCurrency", "Update", HttpMethod.Put); + MapRoute(app, Routes.SettingsCurrency, "SettingCurrency", "Delete", HttpMethod.Delete); + MapRoute(app, Routes.SettingsCurrencyRate, "SettingCurrency", "AddRate", HttpMethod.Post); + + // Settings Account Categories + MapRoute(app, Routes.SettingsAccountCategories, "SettingsAccountCategory", "AccountCategories", HttpMethod.Get); + MapRoute(app, Routes.SettingsAccountCategory, "SettingsAccountCategory", "AccountCategory", HttpMethod.Get); + MapRoute(app, Routes.SettingsAccountCategories, "SettingsAccountCategory", "AccountCategoriesAdd", HttpMethod.Post); + MapRoute(app, Routes.SettingsAccountCategory, "SettingsAccountCategory", "AccountCategoriesUpdate", HttpMethod.Put); + MapRoute(app, Routes.SettingsAccountCategory, "SettingsAccountCategory", "AccountCategoriesDelete", HttpMethod.Delete); + + // Settings Account + MapRoute(app, Routes.SettingsAccounts, "SettingsAccount", "AccountsGet", HttpMethod.Get); + MapRoute(app, Routes.SettingsAccounts, "SettingsAccount", "AccountsAdd", HttpMethod.Post); + MapRoute(app, Routes.SettingsAccount, "SettingsAccount", "AccountsUpdate", HttpMethod.Put); + MapRoute(app, Routes.SettingsAccount, "SettingsAccount", "AccountsDelete", HttpMethod.Delete); + MapRoute(app, Routes.SettingsAccountAccountCategory, "SettingsAccount", "AccountsCategoryDelete", HttpMethod.Delete); + MapRoute(app, Routes.SettingsAccountAccesses, "SettingsAccount", "AccountsAccessAdd", HttpMethod.Post); + MapRoute(app, Routes.SettingsAccountAccess, "SettingsAccount", "AccountsAccessDelete", HttpMethod.Delete); + MapRoute(app, Routes.SettingsAccountInvites, "SettingsAccount", "AccountInvites", HttpMethod.Get); + MapRoute(app, Routes.SettingsAccountInviteAccept, "SettingsAccount", "AccountInviteAccept", HttpMethod.Post); + MapRoute(app, Routes.SettingsAccountInviteReject, "SettingsAccount", "AccountInviteReject", HttpMethod.Post); + + // Settings Items + MapRoute(app, Routes.SettingsItemCategories, "SettingsItem", "ItemsCategories", HttpMethod.Get); + MapRoute(app, Routes.SettingsItemCategories, "SettingsItem", "ItemCategoriesAdd", HttpMethod.Post); + MapRoute(app, Routes.SettingsItemCategory, "SettingsItem", "ItemCategoriesUpdate", HttpMethod.Put); + MapRoute(app, Routes.SettingsItemCategory, "SettingsItem", "ItemCategoriesDelete", HttpMethod.Delete); + MapRoute(app, Routes.SettingsItems, "SettingsItem", "Items", HttpMethod.Get); + MapRoute(app, Routes.SettingsItem, "SettingsItem", "ItemsUpdate", HttpMethod.Put); + MapRoute(app, Routes.SettingsItems, "SettingsItem", "ItemsPost", HttpMethod.Post); + + // Account + MapRoute(app, Routes.Accounts, "Account", "AccountsGet", HttpMethod.Get); + MapRoute(app, Routes.Account, "Account", "AccountGet", HttpMethod.Get); + MapRoute(app, Routes.AccountMotions, "Account", "MotionsGet", HttpMethod.Get); + MapRoute(app, Routes.AccountMotions, "Account", "MotionsPost", HttpMethod.Post); + MapRoute(app, Routes.AccountMotion, "Account", "MotionsPut", HttpMethod.Put); + MapRoute(app, Routes.AccountMotion, "Account", "MotionsDelete", HttpMethod.Delete); + MapRoute(app, Routes.Items, "Account", "FindItems", HttpMethod.Get); + + // Dashboard + MapRoute(app, Routes.Dashboard, "Dashboard", "Index", HttpMethod.Get); + MapRoute(app, Routes.DashboardIncome, "Dashboard", "Income", HttpMethod.Get); + MapRoute(app, Routes.DashboardOutcome, "Dashboard", "Outcome", HttpMethod.Get); + + // User + MapRoute(app, Routes.UserRegister, "User", "Register", HttpMethod.Post); + MapRoute(app, Routes.UserProfile, "User", "ProfileGet", HttpMethod.Get); + MapRoute(app, Routes.UserProfile, "User", "ProfileUpdate", HttpMethod.Post); + MapRoute(app, Routes.UserAttach, "User", "AttachProvider", HttpMethod.Post); + MapRoute(app, Routes.UserDeattach, "User", "DeattachProvider", HttpMethod.Post); } private static void MapRoute( @@ -50,4 +99,37 @@ public static class Routes public static readonly string SettingsCurrencies = "api/settings/currencies"; public static readonly string SettingsCurrency = "api/settings/currencies/{id}"; public static readonly string SettingsCurrencyRate = "api/settings/currencies/{id}/rate"; + + public static readonly string SettingsAccountCategories = "api/settings/account-categories"; + public static readonly string SettingsAccountCategory = "api/settings/account-categories/{id}"; + + public static readonly string SettingsAccounts = "api/settings/accounts"; + public static readonly string SettingsAccount = "api/settings/accounts/{id}"; + public static readonly string SettingsAccountAccountCategory = "api/settings/accounts/{id}/category/{categoryId}"; + + public static readonly string SettingsAccountAccesses = "api/settings/accounts/{id}/access"; + public static readonly string SettingsAccountAccess = "api/settings/accounts/{id}/access/{userId}"; + public static readonly string SettingsAccountInvites = "api/settings/accounts/invites"; + public static readonly string SettingsAccountInviteAccept = "api/settings/accounts/invites/{id}/accept"; + public static readonly string SettingsAccountInviteReject = "api/settings/accounts/invites/{id}/reject"; + + public static readonly string SettingsItemCategories = "api/settings/item-categories"; + public static readonly string SettingsItemCategory = "api/settings/item-categories/{id}"; + public static readonly string SettingsItems = "api/settings/items"; + public static readonly string SettingsItem = "api/settings/items/{id}"; + + public static readonly string Accounts = "api/accounts"; + public static readonly string Account = "api/accounts/{id}"; + public static readonly string AccountMotions = "api/accounts/{id}/motions"; + public static readonly string AccountMotion = "api/accounts/{id}/motions/{motionId}"; + public static readonly string Items = "api/items"; + + public static readonly string Dashboard = "api/dashboard"; + public static readonly string DashboardIncome = "api/dashboard/income"; + public static readonly string DashboardOutcome = "api/dashboard/outcome"; + + public static readonly string UserRegister = "api/user/register"; + public static readonly string UserProfile = "api/user/profile"; + public static readonly string UserAttach = "api/user/attach"; + public static readonly string UserDeattach = "api/user/deattach"; } \ No newline at end of file diff --git a/MyOffice.Web/Program.cs b/MyOffice.Web/Program.cs index 02adc61..750ab0a 100644 --- a/MyOffice.Web/Program.cs +++ b/MyOffice.Web/Program.cs @@ -48,6 +48,7 @@ using MyOffice.Web.Infrastructure.Attributes; using System.Text.Json; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Infrastructure; +using MyOffice.Web.Infrastructure.Filters; //TODO: Data.Model only Repository and Service, response <-> mapper <-> web <-> mapper <-> service <-> repository //TODO: Project management @@ -169,6 +170,7 @@ public partial class Program { options.Conventions.Add(new DefaultFromBodyBindingConvention()); options.Filters.Add(typeof(GlobalModelStateValidatorAttribute)); + options.Filters.Add(typeof(ResponseFilter)); }); builder.Services.Configure(options =>