Compare commits
41
Commits
d48a07a0fe
...
23edfc8b0c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23edfc8b0c | ||
|
|
7d632d46c8 | ||
|
|
3807524412 | ||
|
|
f74125a92c | ||
|
|
12504e61f4 | ||
|
|
a994d72640 | ||
|
|
fe6bf7f412 | ||
|
|
e4f9104eea | ||
|
|
6344546157 | ||
|
|
f693e70d10 | ||
|
|
e318260acd | ||
|
|
d6bf268167 | ||
|
|
028f6bcf16 | ||
|
|
78936cf602 | ||
|
|
67f87e2f21 | ||
|
|
93fa738d72 | ||
|
|
b32d02b001 | ||
|
|
9e2c976c0d | ||
|
|
b72107d14b | ||
|
|
3ad64671ec | ||
|
|
52d2af93e2 | ||
|
|
07ed7a5f60 | ||
|
|
4e3cc0750c | ||
|
|
87c89897c2 | ||
|
|
9dab5536c2 | ||
|
|
f409ff1afb | ||
|
|
1131159112 | ||
|
|
7a0c53facc | ||
|
|
cd38e7a644 | ||
|
|
28f627a36e | ||
|
|
7a28a0fc3b | ||
|
|
da0b1337eb | ||
|
|
39a7931a97 | ||
|
|
85abcfa068 | ||
|
|
cc276d4a17 | ||
|
|
c5ab17115d | ||
|
|
8bdf6dabdc | ||
|
|
1155deaf1a | ||
|
|
4792acea76 | ||
|
|
d90e73dfcc | ||
|
|
9ab1447381 |
+52
-2
@@ -1,3 +1,54 @@
|
|||||||
|
|
||||||
|
# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
|
||||||
|
|
||||||
|
# Compiled output
|
||||||
|
#**/dist
|
||||||
|
dist/
|
||||||
|
**/tmp
|
||||||
|
**/out-tsc
|
||||||
|
**/bazel-out
|
||||||
|
#Visual studio 2022
|
||||||
|
**/bin
|
||||||
|
**/obj
|
||||||
|
**/.vs
|
||||||
|
# Node
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
.idea/
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.history/*
|
||||||
|
|
||||||
|
# Miscellaneous
|
||||||
|
**/.angular/cache
|
||||||
|
.sass-cache/
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
|
||||||
|
# System files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
/API/Properties/PublishProfiles
|
||||||
|
/API/.config
|
||||||
|
/API/CarParkValidationAPI.csproj.user
|
||||||
|
=======
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
##
|
##
|
||||||
@@ -359,5 +410,4 @@ MigrationBackup/
|
|||||||
# Ionide (cross platform F# VS Code tools) working folder
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
.ionide/
|
.ionide/
|
||||||
|
|
||||||
# Fody - auto-generated XML schema
|
|
||||||
FodyWeavers.xsd
|
|
||||||
|
|||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
###############################################################################
|
||||||
|
# Set default behavior to automatically normalize line endings.
|
||||||
|
###############################################################################
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior for command prompt diff.
|
||||||
|
#
|
||||||
|
# This is need for earlier builds of msysgit that does not have it on by
|
||||||
|
# default for csharp files.
|
||||||
|
# Note: This is only used by command line
|
||||||
|
###############################################################################
|
||||||
|
#*.cs diff=csharp
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set the merge driver for project and solution files
|
||||||
|
#
|
||||||
|
# Merging from the command prompt will add diff markers to the files if there
|
||||||
|
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||||
|
# the diff markers are never inserted). Diff markers may cause the following
|
||||||
|
# file extensions to fail to load in VS. An alternative would be to treat
|
||||||
|
# these files as binary and thus will always conflict and require user
|
||||||
|
# intervention with every merge. To do so, just uncomment the entries below
|
||||||
|
###############################################################################
|
||||||
|
#*.sln merge=binary
|
||||||
|
#*.csproj merge=binary
|
||||||
|
#*.vbproj merge=binary
|
||||||
|
#*.vcxproj merge=binary
|
||||||
|
#*.vcproj merge=binary
|
||||||
|
#*.dbproj merge=binary
|
||||||
|
#*.fsproj merge=binary
|
||||||
|
#*.lsproj merge=binary
|
||||||
|
#*.wixproj merge=binary
|
||||||
|
#*.modelproj merge=binary
|
||||||
|
#*.sqlproj merge=binary
|
||||||
|
#*.wwaproj merge=binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# behavior for image files
|
||||||
|
#
|
||||||
|
# image files are treated as binary by default.
|
||||||
|
###############################################################################
|
||||||
|
#*.jpg binary
|
||||||
|
#*.png binary
|
||||||
|
#*.gif binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# diff behavior for common document formats
|
||||||
|
#
|
||||||
|
# Convert binary document formats to text before diffing them. This feature
|
||||||
|
# is only available from the command line. Turn it on by uncommenting the
|
||||||
|
# entries below.
|
||||||
|
###############################################################################
|
||||||
|
#*.doc diff=astextplain
|
||||||
|
#*.DOC diff=astextplain
|
||||||
|
#*.docx diff=astextplain
|
||||||
|
#*.DOCX diff=astextplain
|
||||||
|
#*.dot diff=astextplain
|
||||||
|
#*.DOT diff=astextplain
|
||||||
|
#*.pdf diff=astextplain
|
||||||
|
#*.PDF diff=astextplain
|
||||||
|
#*.rtf diff=astextplain
|
||||||
|
#*.RTF diff=astextplain
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Authorization
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class AllowAnonymousAttribute : Attribute
|
||||||
|
{ }
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Authorization
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||||
|
public class AuthorizeAttribute : Attribute, IAuthorizationFilter
|
||||||
|
{
|
||||||
|
private readonly IList<AdminRole> _roles;
|
||||||
|
|
||||||
|
public AuthorizeAttribute(params AdminRole[] roles)
|
||||||
|
{
|
||||||
|
_roles = roles ?? new AdminRole[] { };
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnAuthorization(AuthorizationFilterContext context)
|
||||||
|
{
|
||||||
|
// skip authorization if action is decorated with [AllowAnonymous] attribute
|
||||||
|
var allowAnonymous = context.ActionDescriptor.EndpointMetadata.OfType<AllowAnonymousAttribute>().Any();
|
||||||
|
if (allowAnonymous)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// authorization
|
||||||
|
var user = (User)context.HttpContext.Items["User"];
|
||||||
|
if (user == null || (_roles.Any() && !_roles.Contains(user.Role)))
|
||||||
|
{
|
||||||
|
// not logged in or role not authorized
|
||||||
|
context.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Repository;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
namespace CarParkValidationAPI.Authorization
|
||||||
|
{
|
||||||
|
public class JwtMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
|
||||||
|
public JwtMiddleware(RequestDelegate next, IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Invoke(HttpContext context, IUserService userService, IJwtUtils jwtUtils)
|
||||||
|
{
|
||||||
|
var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
|
||||||
|
var user = jwtUtils.ValidateJwtToken(token);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
// attach user to context on successful jwt validation
|
||||||
|
//here to put in the real user
|
||||||
|
//TODO if you want to add information for User
|
||||||
|
context.Items["User"] = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using System;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Authorization;
|
||||||
|
|
||||||
|
public class JwtUtils : IJwtUtils
|
||||||
|
{
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
|
||||||
|
public JwtUtils(IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GenerateJwtToken(User user)
|
||||||
|
{
|
||||||
|
// generate token that is valid for 2 days
|
||||||
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
|
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
|
||||||
|
var tokenDescriptor = new SecurityTokenDescriptor
|
||||||
|
{
|
||||||
|
Subject = new ClaimsIdentity(new[] {
|
||||||
|
new Claim("id", user.Id.ToString()),
|
||||||
|
new Claim("subject", user.Username)
|
||||||
|
|
||||||
|
//add more if we need it
|
||||||
|
}
|
||||||
|
),
|
||||||
|
Expires = DateTime.UtcNow.AddDays(2),
|
||||||
|
|
||||||
|
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
|
||||||
|
};
|
||||||
|
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||||
|
return tokenHandler.WriteToken(token);
|
||||||
|
}
|
||||||
|
// get back id and username. in subject
|
||||||
|
public User? ValidateJwtToken(string token)
|
||||||
|
{
|
||||||
|
if (token == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
|
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tokenHandler.ValidateToken(token, new TokenValidationParameters
|
||||||
|
{
|
||||||
|
ValidateIssuerSigningKey = true,
|
||||||
|
IssuerSigningKey = new SymmetricSecurityKey(key),
|
||||||
|
ValidateIssuer = false,
|
||||||
|
ValidateLifetime = true,
|
||||||
|
ValidateAudience = false,
|
||||||
|
// set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later)
|
||||||
|
// ClockSkew = TimeSpan.Zero
|
||||||
|
ClockSkew = TimeSpan.FromDays(2),
|
||||||
|
}, out SecurityToken validatedToken);
|
||||||
|
|
||||||
|
var jwtToken = (JwtSecurityToken)validatedToken;
|
||||||
|
// var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value); //old
|
||||||
|
int userId = 0;
|
||||||
|
string username = "";
|
||||||
|
Claim claim;
|
||||||
|
for (int i = 0; i < jwtToken.Claims.Count(); i++)
|
||||||
|
{
|
||||||
|
claim = jwtToken.Claims.ElementAt(i);
|
||||||
|
if (claim.Type == "id")
|
||||||
|
{
|
||||||
|
userId = int.Parse(claim.Value);
|
||||||
|
}
|
||||||
|
else if (claim.Type == "subject")
|
||||||
|
{
|
||||||
|
username = claim.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(username) && userId > 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
User user = new User();
|
||||||
|
user.Id = userId;
|
||||||
|
user.Username = username;
|
||||||
|
|
||||||
|
// return user id from JWT token if validation successful
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.ToString());
|
||||||
|
// return null if validation fails
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<UserSecretsId>punt</UserSecretsId>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.12" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.12" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.12" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.12" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\CommonAD6\CommonAD.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="SpreadsheetLight">
|
||||||
|
<HintPath>..\..\commonDLL\SpreadsheetLight.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 18
|
||||||
|
VisualStudioVersion = 18.10.12210.168 stable
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CarParkValidationAPI", "CarParkValidationAPI.csproj", "{74980A36-AF9D-44B4-991D-994E033AD54A}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonAD", "..\..\CommonAD6\CommonAD.csproj", "{48F9F9E4-C310-5B1A-D153-BD8BD910F815}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{74980A36-AF9D-44B4-991D-994E033AD54A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{74980A36-AF9D-44B4-991D-994E033AD54A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{74980A36-AF9D-44B4-991D-994E033AD54A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{74980A36-AF9D-44B4-991D-994E033AD54A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{48F9F9E4-C310-5B1A-D153-BD8BD910F815}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{48F9F9E4-C310-5B1A-D153-BD8BD910F815}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{48F9F9E4-C310-5B1A-D153-BD8BD910F815}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{48F9F9E4-C310-5B1A-D153-BD8BD910F815}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {FB2BDB7C-3C90-4CBB-BD6B-CFD125C87D0F}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Controllers
|
||||||
|
{
|
||||||
|
// [Authorize]
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/v1/[controller]")]
|
||||||
|
public class AdminUserController : ControllerBase
|
||||||
|
{
|
||||||
|
private IAdminUser _adminUser;
|
||||||
|
public AdminUserController(IAdminUser adminUser)
|
||||||
|
{
|
||||||
|
_adminUser = adminUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> AdminUser([FromBody] AdminUserDto model)
|
||||||
|
{
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (null == currentUser)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
_adminUser.SetCurrentUser(currentUser.Username);
|
||||||
|
var response = await _adminUser.SaveAdminUserAsync(model);
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> AdminUser(bool onlyActive=true)
|
||||||
|
{
|
||||||
|
var retval = await _adminUser.LoadAdminUserAsync(onlyActive);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id:int}")]
|
||||||
|
public async Task<IActionResult> AdminUser(int id)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// only admins can access other user records
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (id != currentUser.Id && currentUser.Role != Role.Admin)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
*/
|
||||||
|
var retval = await _adminUser.LoadAdminUserByIdAsync(id);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
[HttpDelete("{id:int}")]
|
||||||
|
public async Task<IActionResult> DeleteAdminUser(int id)
|
||||||
|
{
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (null == currentUser)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
_adminUser.SetCurrentUser(currentUser.Username);
|
||||||
|
var retval = await _adminUser.DeleteAdminUserAsync(id);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Controllers
|
||||||
|
{
|
||||||
|
//[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/v1/[controller]")]
|
||||||
|
public class ConcessionTypeController : ControllerBase
|
||||||
|
{
|
||||||
|
private IConcessionType _concessionType;
|
||||||
|
|
||||||
|
public ConcessionTypeController(IConcessionType concessionType)
|
||||||
|
{
|
||||||
|
_concessionType = concessionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> ConcessionType([FromBody] ConcessionTypeDto model)
|
||||||
|
{
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (null == currentUser)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
_concessionType.SetCurrentUser(currentUser.Username);
|
||||||
|
var response = await _concessionType.SaveConcessionTypeAsync(model);
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> ConcessionType(bool onlyActive =true)
|
||||||
|
{
|
||||||
|
var retval = await _concessionType.LoadConcessionTypeAsync(onlyActive);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id:int}")]
|
||||||
|
public async Task<IActionResult> ConcessionType(int id)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// only admins can access other user records
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (id != currentUser.Id && currentUser.Role != Role.Admin)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
*/
|
||||||
|
var retval = await _concessionType.LoadConcessionTypeByIdAsync(id);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
[HttpDelete("{id:int}")]
|
||||||
|
public async Task<IActionResult> DeleteConcessionType(int id)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// only admins can access other user records
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (id != currentUser.Id && currentUser.Role != Role.Admin)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
*/
|
||||||
|
var retval = await _concessionType.DeleteConcessionTypeAsync(id);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.StaticFiles;
|
||||||
|
using CarParkValidationAPI.Repository;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Controllers
|
||||||
|
{
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/v1/[controller]")]
|
||||||
|
public class ConcessionValidationController : ControllerBase
|
||||||
|
{
|
||||||
|
private ConcessionValidationReportRepository _concessionValidationReport;
|
||||||
|
|
||||||
|
private IConcessionValidation _concessionValidation;
|
||||||
|
private readonly FileExtensionContentTypeProvider _contentTypeProvider;
|
||||||
|
|
||||||
|
public ConcessionValidationController(IConcessionValidation concessionValidation,
|
||||||
|
ConcessionValidationReportRepository concesionReportReport)
|
||||||
|
{
|
||||||
|
_concessionValidationReport = concesionReportReport;
|
||||||
|
_concessionValidation = concessionValidation;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> ConcessionValidation([FromBody] ConcessionValidationDto model)
|
||||||
|
{
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (null == currentUser)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
_concessionValidation.SetCurrentUser(currentUser.Username);
|
||||||
|
var response = await _concessionValidation.SaveConcessionValidationAsync(model);
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> ConcessionValidation(bool onlyActive=true)
|
||||||
|
{
|
||||||
|
var retval = await _concessionValidation.LoadConcessionValidationAsync(onlyActive);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("[action]")]
|
||||||
|
public async Task<IActionResult> ConcessionValidationByStaff(string staffLinkNo, DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
var retval = await _concessionValidation.LoadConcessionValidationStaffLinkNoAsync(staffLinkNo, fromDate, toDate);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("[action]")]
|
||||||
|
public async Task<IActionResult> CheckConcessionValidationByStaff(string staffLinkNo, string concessionCard, DateTime currentDate, int id)
|
||||||
|
{
|
||||||
|
var retval = await _concessionValidation.CheckConcessionValidationStaffLinkNoAsync(staffLinkNo, concessionCard, currentDate, id);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id:int}")]
|
||||||
|
public async Task<IActionResult> ConcessionValidation(int id)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// only admins can access other user records
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (id != currentUser.Id && currentUser.Role != Role.Admin)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
*/
|
||||||
|
var retval = await _concessionValidation.LoadConcessionValidationByIdAsync(id);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public async Task<IActionResult> GetConcessionCard(CardNoCriteria criteria)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// only admins can access other user records
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (id != currentUser.Id && currentUser.Role != Role.Admin)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
*/
|
||||||
|
var retval = await _concessionValidation.LoadConcessionValidationByCardNumberAsync(criteria.CardNo);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id:int}")]
|
||||||
|
public async Task<IActionResult> DeleteConcessionValidation(int id)
|
||||||
|
{
|
||||||
|
// only admins can access other user records
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (null == currentUser)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
_concessionValidation.SetCurrentUser(currentUser.Username);
|
||||||
|
var retval = await _concessionValidation.DeleteConcessionValidationAsync(id);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
/* download the excel file */
|
||||||
|
[HttpGet("[action]")]
|
||||||
|
|
||||||
|
public async Task<IActionResult> GetReportFile(DateTime fromDate , DateTime toDate)
|
||||||
|
{
|
||||||
|
// this.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
|
||||||
|
var result = await _concessionValidationReport.GetConcessionValidationReport(fromDate, toDate); // _concessionValidation.GetReport(fromDate, toDate);
|
||||||
|
string fileContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; //Map(result.Data.FileName);
|
||||||
|
return File(result.Data.Content, fileContentType, result.Data.FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonAction]
|
||||||
|
private string Map(string fileName)
|
||||||
|
{
|
||||||
|
if (!_contentTypeProvider.TryGetContentType(fileName, out string contentType))
|
||||||
|
{
|
||||||
|
contentType = "application/octet-stream";
|
||||||
|
}
|
||||||
|
return contentType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Controllers
|
||||||
|
{
|
||||||
|
public class FallbackController : Controller
|
||||||
|
{
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return PhysicalFile(Path.Combine(Directory.GetCurrentDirectory(),
|
||||||
|
"wwwroot", "index.html"), "text/HTML");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Controllers
|
||||||
|
{
|
||||||
|
// [Authorize]
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/v1/[controller]")]
|
||||||
|
public class LookupCodeController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILookupCode _lookupCodeService;
|
||||||
|
|
||||||
|
public LookupCodeController(ILookupCode lookupCode)
|
||||||
|
{
|
||||||
|
_lookupCodeService = lookupCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("[action]")]
|
||||||
|
public async Task<IActionResult> ConcessionTypes(bool onlyActive=true)
|
||||||
|
{
|
||||||
|
var retval = await _lookupCodeService.LoadConcessionTypeAsync(onlyActive);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
[HttpGet("[action]")]
|
||||||
|
public async Task<IActionResult> ValidationPoints(bool onlyActive= true)
|
||||||
|
{
|
||||||
|
var retval = await _lookupCodeService.LoadValidationPointAsync(onlyActive);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Models.Users;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Controllers
|
||||||
|
{
|
||||||
|
//[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/v1/[controller]")]
|
||||||
|
public class UsersController : ControllerBase
|
||||||
|
{
|
||||||
|
private IUserService _userService;
|
||||||
|
|
||||||
|
public UsersController(IUserService userService)
|
||||||
|
{
|
||||||
|
_userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public IActionResult Authenticate(AuthenticateRequest model)
|
||||||
|
{
|
||||||
|
var response = _userService.Authenticate(model);
|
||||||
|
|
||||||
|
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public async Task<IActionResult> LoginAD([FromBody] AuthenticateRequest model)
|
||||||
|
{
|
||||||
|
var response = await _userService.LoginAD(model);
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost("[action]")]
|
||||||
|
public async Task<IActionResult> LoginApiAD([FromBody] AuthenticateRequest model)
|
||||||
|
{
|
||||||
|
var response = await _userService.LoginApiAD(model);
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpGet("[action]")]
|
||||||
|
public async Task<IActionResult> SearchApiStaff(string stafflinkNo)
|
||||||
|
{
|
||||||
|
var user = await _userService.SearchApiStaff(stafflinkNo);
|
||||||
|
return Ok(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpGet("[action]")]
|
||||||
|
public async Task<ResultModel<User>> SearchADStaff(string stafflinkNo)
|
||||||
|
{
|
||||||
|
var user = await _userService.SearchADStaff(stafflinkNo);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [Authorize(AdminRole.Admin)]
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetAllUsers()
|
||||||
|
{
|
||||||
|
var users = await _userService.GetAllUsers();
|
||||||
|
return Ok(users);
|
||||||
|
}
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpGet("{id:int}")]
|
||||||
|
public async Task<IActionResult> GetById(int id)
|
||||||
|
{
|
||||||
|
// only admins can access other user records
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (id != currentUser.Id && currentUser.Role != AdminRole.Admin)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
|
||||||
|
var user = await _userService.GetById(id);
|
||||||
|
return Ok(user);
|
||||||
|
}
|
||||||
|
/* download the excel file */
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpGet("[action]")]
|
||||||
|
public async Task<IActionResult> GetReportFile()
|
||||||
|
{
|
||||||
|
// this.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
|
||||||
|
var result = await _userService.GetAllUserReport(); // .GetReport(fromDate, toDate);
|
||||||
|
string fileContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; //Map(result.Data.FileName);
|
||||||
|
return File(result.Data.Content, fileContentType, result.Data.FileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Controllers
|
||||||
|
{
|
||||||
|
/* [Authorize] */
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/v1/[controller]")]
|
||||||
|
public class ValidationPointController : ControllerBase
|
||||||
|
{
|
||||||
|
private IValidationPoint _validationPoint;
|
||||||
|
|
||||||
|
public ValidationPointController(IValidationPoint validationPoint)
|
||||||
|
{
|
||||||
|
_validationPoint = validationPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> ValidationPoint([FromBody] ValidationPointDto model)
|
||||||
|
{
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (null == currentUser)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
_validationPoint.SetCurrentUser(currentUser.Username);
|
||||||
|
var response = await _validationPoint.SaveValidationPointAsync(model);
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> ValidationPoint(bool onlyActive=true)
|
||||||
|
{
|
||||||
|
var retval = await _validationPoint.LoadValidationPointAsync(onlyActive);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id:int}")]
|
||||||
|
public async Task<IActionResult> ValidationPoint(int id)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// only admins can access other user records
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (id != currentUser.Id && currentUser.Role != Role.Admin)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
*/
|
||||||
|
var retval = await _validationPoint.LoadValidationPointByIdAsync(id);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
[HttpDelete("{id:int}")]
|
||||||
|
public async Task<IActionResult> DeleteConcessionType(int id)
|
||||||
|
{
|
||||||
|
// only admins can access other user records
|
||||||
|
var currentUser = (User)HttpContext.Items["User"];
|
||||||
|
if (null == currentUser)
|
||||||
|
return Unauthorized(new { message = "Unauthorized" });
|
||||||
|
_validationPoint.SetCurrentUser(currentUser.Username);
|
||||||
|
var retval = await _validationPoint.DeleteValidationPointAsync(id);
|
||||||
|
return Ok(retval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,230 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Datas
|
||||||
|
{
|
||||||
|
public class DataContext : DbContext
|
||||||
|
{
|
||||||
|
public DbSet<User> Users { get; set; }
|
||||||
|
public DbSet<AdminUser> AdminUsers { get; set; }
|
||||||
|
public DbSet<ValidationPoint> Validations { get; set; }
|
||||||
|
public DbSet<ConcessionValidation> ConcessionValidations { get; set; }
|
||||||
|
public DbSet<ConcessionType> ConcessionTypes { get; set; }
|
||||||
|
private readonly IConfiguration Configuration;
|
||||||
|
private IOptions<AppSettings> _appSettings;
|
||||||
|
public DataContext(IConfiguration configuration, IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
_appSettings = appSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
modelBuilder.Entity<ValidationPoint>().ToTable("ValidationPoint");
|
||||||
|
modelBuilder.Entity<ConcessionValidation>().ToTable("ConcessionValidation");
|
||||||
|
modelBuilder.Entity<ConcessionType>().ToTable("ConcessionType");
|
||||||
|
modelBuilder.Entity<AdminUser>().ToTable("AdminUser");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder options)
|
||||||
|
{
|
||||||
|
// in memory database used for simplicity, change to a real db for production applications
|
||||||
|
// options.UseInMemoryDatabase("TestDb");
|
||||||
|
options.UseSqlServer(_appSettings.Value.SQLConnectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConcessionValidationExtDto PopulateItem(IDataReader reader)
|
||||||
|
{
|
||||||
|
ConcessionValidationExtDto item = new ConcessionValidationExtDto();
|
||||||
|
object myobj;
|
||||||
|
myobj = reader["ValidationID"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.Id = (int) myobj;
|
||||||
|
|
||||||
|
myobj = reader["ValidateDate"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.ValidateDate = (DateTime)myobj;
|
||||||
|
|
||||||
|
myobj = reader["ConcessionCard"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.ConcessionCard = (string) myobj;
|
||||||
|
|
||||||
|
myobj = reader["ConcessionHolder"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.ConcessionHolder = (string) myobj;
|
||||||
|
|
||||||
|
myobj = reader["ConcessionExpiry"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.ConcessionExpiry = (bool) myobj;
|
||||||
|
/*
|
||||||
|
myobj = reader["ConcessionTypeID"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.ConcessionTypeId = (int)myobj;
|
||||||
|
*/
|
||||||
|
myobj = reader["StafflinkNo"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.StafflinkNo = (string) myobj;
|
||||||
|
|
||||||
|
myobj = reader["ConcessionType"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.ConcessionType = (string) myobj;
|
||||||
|
myobj = reader["ValidationPoint"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.ValidationPoint = (string) myobj;
|
||||||
|
|
||||||
|
myobj = reader["StaffFirstName"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.StaffFirstName = (string) myobj;
|
||||||
|
|
||||||
|
myobj = reader["StaffLastName"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.StaffLastName = (string) myobj;
|
||||||
|
|
||||||
|
myobj = reader["StaffEmail"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.StaffEmail = (string) myobj;
|
||||||
|
/*
|
||||||
|
myobj = reader["ValidationPointID"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.ValidationPointId = (int)myobj;
|
||||||
|
*/
|
||||||
|
myobj = reader["Active"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
item.Active = (bool)myobj;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
public async Task<List<ConcessionValidationExtDto>> SelectConcessionValidationByStaffId(bool activeOnly, string stafflinkNo, DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
var pfromDate = new SqlParameter
|
||||||
|
{
|
||||||
|
ParameterName = "fromDate",
|
||||||
|
Value = fromDate.Date
|
||||||
|
};
|
||||||
|
var pStaffLink = new SqlParameter
|
||||||
|
{
|
||||||
|
ParameterName = "StafflinkNo",
|
||||||
|
Value = string.IsNullOrEmpty(stafflinkNo) ? "" : stafflinkNo,
|
||||||
|
};
|
||||||
|
|
||||||
|
var pToDate = new SqlParameter
|
||||||
|
{
|
||||||
|
ParameterName = "toDate",
|
||||||
|
Value = toDate.Date
|
||||||
|
};
|
||||||
|
ConcessionValidationExtDto item;
|
||||||
|
List<ConcessionValidationExtDto> result = new List<ConcessionValidationExtDto>();
|
||||||
|
using (var command = this.Database.GetDbConnection().CreateCommand())
|
||||||
|
{
|
||||||
|
command.CommandType = CommandType.StoredProcedure;
|
||||||
|
command.CommandText = ("capv_ConValidation_Sel");
|
||||||
|
command.Parameters.Add(pfromDate);
|
||||||
|
command.Parameters.Add(pToDate);
|
||||||
|
command.Parameters.Add(pStaffLink);
|
||||||
|
this.Database.OpenConnection();
|
||||||
|
using (DbDataReader reader = await command.ExecuteReaderAsync())
|
||||||
|
{
|
||||||
|
while (await reader.ReadAsync())
|
||||||
|
{
|
||||||
|
item = PopulateItem(reader);
|
||||||
|
result.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<int>> SelectCheckConcessionValidationAsync(DateTime fromDate, string concessionCard, string staffLinkNo)
|
||||||
|
{
|
||||||
|
var pfromDate = new SqlParameter
|
||||||
|
{
|
||||||
|
ParameterName = "FromDate",
|
||||||
|
Value = fromDate.Date,
|
||||||
|
};
|
||||||
|
|
||||||
|
var pStaffLink = new SqlParameter
|
||||||
|
{
|
||||||
|
ParameterName = "StaffLinkNo",
|
||||||
|
Value = staffLinkNo,
|
||||||
|
};
|
||||||
|
|
||||||
|
var pConcessionCard = new SqlParameter
|
||||||
|
{
|
||||||
|
ParameterName = "ConcessionCard",
|
||||||
|
Value = concessionCard,
|
||||||
|
};
|
||||||
|
|
||||||
|
ConcessionValidationExtDto item;
|
||||||
|
List<int> result = new List<int>();
|
||||||
|
object myobj;
|
||||||
|
int id;
|
||||||
|
using (var command = this.Database.GetDbConnection().CreateCommand())
|
||||||
|
{
|
||||||
|
command.CommandType = CommandType.StoredProcedure;
|
||||||
|
command.CommandText = ("capv_CheckConValidation_Sel");
|
||||||
|
command.Parameters.Add(pfromDate);
|
||||||
|
command.Parameters.Add(pStaffLink);
|
||||||
|
command.Parameters.Add(pConcessionCard);
|
||||||
|
this.Database.OpenConnection();
|
||||||
|
using (DbDataReader reader = await command.ExecuteReaderAsync())
|
||||||
|
{
|
||||||
|
while (await reader.ReadAsync())
|
||||||
|
{
|
||||||
|
myobj = reader["ValidationID"];
|
||||||
|
if (myobj != System.DBNull.Value)
|
||||||
|
{
|
||||||
|
id = (int)myobj;
|
||||||
|
result.Add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<List<ConcessionValidationExtDto>> SelectConcessionValidationByDate(bool activeOnly, DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
var pfromDate = new SqlParameter
|
||||||
|
{
|
||||||
|
ParameterName = "fromDate",
|
||||||
|
Value = fromDate.Date
|
||||||
|
};
|
||||||
|
var pToDate = new SqlParameter
|
||||||
|
{
|
||||||
|
ParameterName = "toDate",
|
||||||
|
Value = toDate.Date
|
||||||
|
};
|
||||||
|
ConcessionValidationExtDto item;
|
||||||
|
List<ConcessionValidationExtDto> result = new List<ConcessionValidationExtDto>();
|
||||||
|
using (var command = this.Database.GetDbConnection().CreateCommand())
|
||||||
|
{
|
||||||
|
command.CommandType = CommandType.StoredProcedure;
|
||||||
|
command.CommandText = ("capv_ConValidationDate_Sel");
|
||||||
|
command.Parameters.Add(pfromDate);
|
||||||
|
command.Parameters.Add(pToDate);
|
||||||
|
|
||||||
|
this.Database.OpenConnection();
|
||||||
|
using (DbDataReader reader = await command.ExecuteReaderAsync())
|
||||||
|
{
|
||||||
|
while (await reader.ReadAsync())
|
||||||
|
{
|
||||||
|
item = PopulateItem(reader);
|
||||||
|
result.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.Sort((x, y) => x.ValidateDate.Date.CompareTo(y.ValidateDate.Date));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Entities
|
||||||
|
{
|
||||||
|
public class AdminUserDto
|
||||||
|
{
|
||||||
|
#region public Member
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string StafflinkNo { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string AddedBy { get; set; }
|
||||||
|
|
||||||
|
public DateTime AddedOn { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
|
||||||
|
public AdminRole RoleType { get; set; }
|
||||||
|
|
||||||
|
public int ValidationPointId { get; set; }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
public class AdminUserViewDto
|
||||||
|
{
|
||||||
|
#region public Member
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string StafflinkNo { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string AddedBy { get; set; }
|
||||||
|
|
||||||
|
public DateTime AddedOn { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
|
||||||
|
public string RoleType { get; set; }
|
||||||
|
|
||||||
|
public string ValidationPoint { get; set; }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Entities
|
||||||
|
{
|
||||||
|
public class ApiException
|
||||||
|
{
|
||||||
|
public ApiException(int statusCode, string message = null, string details = null)
|
||||||
|
{
|
||||||
|
StatusCode = statusCode;
|
||||||
|
Message = message;
|
||||||
|
Details = details;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int StatusCode { get; set; }
|
||||||
|
public string Message { get; set; }
|
||||||
|
public string Details { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Entities
|
||||||
|
{
|
||||||
|
public class ConcessionTypeDto
|
||||||
|
{
|
||||||
|
#region public Member
|
||||||
|
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public string Display { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Entities
|
||||||
|
{
|
||||||
|
public class CardNoCriteria
|
||||||
|
{
|
||||||
|
public string CardNo { get; set; }
|
||||||
|
}
|
||||||
|
public class ConcessionValidationExtDto: ConcessionValidationDto
|
||||||
|
{
|
||||||
|
public string ConcessionType { get; set; }
|
||||||
|
public string ValidationPoint { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public partial class ConcessionValidationDto
|
||||||
|
{
|
||||||
|
#region public Member
|
||||||
|
|
||||||
|
public int Id { get; set; }
|
||||||
|
public DateTime ValidateDate { get; set; }
|
||||||
|
|
||||||
|
public string ConcessionCard { get; set; }
|
||||||
|
|
||||||
|
public string ConcessionHolder { get; set; }
|
||||||
|
|
||||||
|
public bool ConcessionExpiry { get; set; }
|
||||||
|
|
||||||
|
public int ConcessionTypeId { get; set; }
|
||||||
|
|
||||||
|
public string StafflinkNo { get; set; }
|
||||||
|
|
||||||
|
public int ValidationPointId { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
|
||||||
|
public string StaffFirstName { get; set; }
|
||||||
|
public string StaffLastName { get; set; }
|
||||||
|
public string StaffEmail { get; set; }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Entities
|
||||||
|
{
|
||||||
|
public class FileContent
|
||||||
|
{
|
||||||
|
public byte[] Content { get; set; }
|
||||||
|
public string FileName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Entities
|
||||||
|
{
|
||||||
|
public class LookupCodeDto
|
||||||
|
{
|
||||||
|
public int Id
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public string Description
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Entities
|
||||||
|
{
|
||||||
|
public class ValidationPointDto
|
||||||
|
{
|
||||||
|
|
||||||
|
#region public Member
|
||||||
|
|
||||||
|
public int Id { get; set; }
|
||||||
|
[Required]
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public string Display { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Helpers
|
||||||
|
{
|
||||||
|
public class ErrorHandlerMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly ILogger<ErrorHandlerMiddleware> _logger;
|
||||||
|
private readonly IHostEnvironment _env;
|
||||||
|
|
||||||
|
public ErrorHandlerMiddleware(RequestDelegate next,
|
||||||
|
ILogger<ErrorHandlerMiddleware> logger, IHostEnvironment env)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
_logger = logger;
|
||||||
|
_env = env;
|
||||||
|
}
|
||||||
|
public async Task Invoke(HttpContext context)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var response = context.Response;
|
||||||
|
response.ContentType = "application/json";
|
||||||
|
_logger.LogError(ex, ex.Message);
|
||||||
|
/*
|
||||||
|
switch (ex)
|
||||||
|
{
|
||||||
|
// case Exception e:
|
||||||
|
// // custom application error
|
||||||
|
// response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
|
// break;
|
||||||
|
case KeyNotFoundException:
|
||||||
|
// not found error
|
||||||
|
response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// unhandled error
|
||||||
|
response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||||
|
break;
|
||||||
|
} */
|
||||||
|
response.StatusCode = ex switch
|
||||||
|
{
|
||||||
|
// case Exception e:
|
||||||
|
// // custom application error
|
||||||
|
// response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
|
// break;
|
||||||
|
KeyNotFoundException => (int)HttpStatusCode.NotFound,// not found error
|
||||||
|
_ => (int)HttpStatusCode.InternalServerError,// unhandled error
|
||||||
|
};
|
||||||
|
//response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||||
|
var res = _env.IsDevelopment() ?
|
||||||
|
new ApiException(response.StatusCode, ex.Message, ex.StackTrace?.ToString())
|
||||||
|
: new ApiException(response.StatusCode, "Internal Server Error");
|
||||||
|
|
||||||
|
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
|
||||||
|
var json = JsonSerializer.Serialize(res, options);
|
||||||
|
await response.WriteAsync(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Interface
|
||||||
|
{
|
||||||
|
public interface IAdminUser
|
||||||
|
{
|
||||||
|
Task<ResultModel<List<AdminUserViewDto>>> LoadAdminUserAsync(bool OnlyActive);
|
||||||
|
Task<ResultModel<bool>> CheckAdminUserByStaffLinkNoAsync(string staffLinkNo);
|
||||||
|
Task<ResultModel<int>> SaveAdminUserAsync(AdminUserDto item);
|
||||||
|
Task<ResultModel<AdminUserDto>> LoadAdminUserByIdAsync(int id);
|
||||||
|
Task<ResultModel<bool>> DeleteAdminUserAsync(int id);
|
||||||
|
void SetCurrentUser(string username);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Interface
|
||||||
|
{
|
||||||
|
public interface IConcessionType
|
||||||
|
{
|
||||||
|
Task<ResultModel<List<ConcessionTypeDto>>> LoadConcessionTypeAsync(bool OnlyActive);
|
||||||
|
Task<ResultModel<int>> SaveConcessionTypeAsync(ConcessionTypeDto item);
|
||||||
|
Task<ResultModel<ConcessionTypeDto>> LoadConcessionTypeByIdAsync(int id);
|
||||||
|
Task<ResultModel<bool>> DeleteConcessionTypeAsync(int id);
|
||||||
|
Task<ResultModel<Dictionary<int, LookupCodeDto>>> GetConcessionTypeDicAsync();
|
||||||
|
void SetCurrentUser(string username);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CarParkValidationAPI.Repository;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Interface
|
||||||
|
{
|
||||||
|
public interface IConcessionValidation
|
||||||
|
{
|
||||||
|
Task<ResultModel<List<ConcessionValidationExtDto>>> LoadConcessionValidationAsync(bool OnlyActive);
|
||||||
|
Task<ResultModel<List<ConcessionValidationExtDto>>> LoadConcessionValidationStaffLinkNoAsync(string staffLinkNo, DateTime currentDate, DateTime toDate);
|
||||||
|
Task<ResultModel<int>> CheckConcessionValidationStaffLinkNoAsync(string staffLinkNo, string concessionCard, DateTime currentDate, int id);
|
||||||
|
Task<ResultModel<int>> SaveConcessionValidationAsync(ConcessionValidationDto item);
|
||||||
|
Task<ResultModel<ConcessionValidationDto>> LoadConcessionValidationByIdAsync(int id);
|
||||||
|
Task<ResultModel<ConcessionValidationDto>> LoadConcessionValidationByCardNumberAsync(string cardNo);
|
||||||
|
Task<ResultModel<bool>> DeleteConcessionValidationAsync(int id);
|
||||||
|
|
||||||
|
void SetCurrentUser(string username);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Interface
|
||||||
|
{
|
||||||
|
public interface IJwtUtils
|
||||||
|
{
|
||||||
|
public string GenerateJwtToken(User user);
|
||||||
|
public User? ValidateJwtToken(string token);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Interface
|
||||||
|
{
|
||||||
|
public interface ILookupCode
|
||||||
|
{
|
||||||
|
Task<ResultModel<List<LookupCodeDto>>> LoadConcessionTypeAsync(bool OnlyActive);
|
||||||
|
Task<ResultModel<List<LookupCodeDto>>> LoadValidationPointAsync(bool OnlyActive);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using CarParkValidationAPI.Models.Users;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Interface
|
||||||
|
{
|
||||||
|
public interface IUserService
|
||||||
|
{
|
||||||
|
AuthenticateResponse Authenticate(AuthenticateRequest model);
|
||||||
|
Task<ResultModel<AuthenticateResponse>> LoginApiAD(AuthenticateRequest model);
|
||||||
|
Task<ResultModel<AuthenticateResponse>> LoginAD(AuthenticateRequest model);
|
||||||
|
Task<ResultModel<List<User>>> GetAllUsers();
|
||||||
|
Task<ResultModel<User>> GetById(int id);
|
||||||
|
Task<ResultModel<User>> SearchApiStaff(string staffLinkNo);
|
||||||
|
Task<ResultModel<User>> SearchADStaff(string staffLinkNo);
|
||||||
|
Task<ResultModel<FileContent>> GetAllUserReport();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Interface
|
||||||
|
{
|
||||||
|
public interface IValidationPoint
|
||||||
|
{
|
||||||
|
Task<ResultModel<List<ValidationPointDto>>> LoadValidationPointAsync(bool OnlyActive);
|
||||||
|
Task<ResultModel<int>> SaveValidationPointAsync(ValidationPointDto item);
|
||||||
|
Task<ResultModel<ValidationPointDto>> LoadValidationPointByIdAsync(int id);
|
||||||
|
Task<ResultModel<bool>> DeleteValidationPointAsync(int id);
|
||||||
|
Task<ResultModel<Dictionary<int, LookupCodeDto>>> GetValidationPointDicAsync();
|
||||||
|
void SetCurrentUser(string username);
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Models
|
||||||
|
{
|
||||||
|
public enum AdminRole
|
||||||
|
{
|
||||||
|
Normal = 1,
|
||||||
|
Admin = 2
|
||||||
|
}
|
||||||
|
public partial class AdminUserCriteria
|
||||||
|
{
|
||||||
|
public AdminUserCriteria()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#region public Member
|
||||||
|
|
||||||
|
public int? UserID { get; set; }
|
||||||
|
|
||||||
|
public int? StafflinkNo { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string AddedBy { get; set; }
|
||||||
|
|
||||||
|
public DateTime? AddedOn { get; set; }
|
||||||
|
|
||||||
|
public bool? Active { get; set; }
|
||||||
|
|
||||||
|
public int? RoleType { get; set; }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
[Table("AdminUser")]
|
||||||
|
public partial class AdminUser
|
||||||
|
{
|
||||||
|
public AdminUser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#region public Member
|
||||||
|
[Key]
|
||||||
|
public int UserID { get; set; }
|
||||||
|
public string StafflinkNo { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string AddedBy { get; set; }
|
||||||
|
|
||||||
|
public DateTime AddedOn { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
|
||||||
|
public AdminRole RoleType { get; set; }
|
||||||
|
|
||||||
|
public int? ValidationPointID { get; set; }
|
||||||
|
public DateTime? LastModified { get; set; }
|
||||||
|
public string? LastModifiedId { get; set; }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Models
|
||||||
|
{
|
||||||
|
public class AppSettings
|
||||||
|
{
|
||||||
|
public string Secret { get; set; }
|
||||||
|
public string SQLConnectionString { get; set; }
|
||||||
|
public string LDAPPath { get; set; }
|
||||||
|
public string LDAPUser { get; set; }
|
||||||
|
public string LDAPPassword { get; set; }
|
||||||
|
|
||||||
|
public string LoginWebAPI { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// for convert to time. use GetADTimeOut
|
||||||
|
/// TimeSpan.FromSeconds(Convert.ToDouble(ConfigurationManager.AppSettings["ADTimeOut"]));
|
||||||
|
public string ADTimeOut { get; set; }
|
||||||
|
|
||||||
|
public TimeSpan GetADTimeOut()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(ADTimeOut))
|
||||||
|
return TimeSpan.FromSeconds(Convert.ToDouble(ADTimeOut));
|
||||||
|
else
|
||||||
|
return TimeSpan.FromSeconds(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Models
|
||||||
|
{
|
||||||
|
public partial class ConcessionType
|
||||||
|
{
|
||||||
|
public ConcessionType()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#region public Member
|
||||||
|
[Key]
|
||||||
|
public int ConcessionTypeID { get; set; }
|
||||||
|
public string ConcessionDesc { get; set; }
|
||||||
|
|
||||||
|
public string ConcessionDisplay { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
public DateTime? LastModified { get; set; }
|
||||||
|
public string? LastModifiedId { get; set; }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Models
|
||||||
|
{
|
||||||
|
[NotMapped]
|
||||||
|
public class ConcessionValidationExt: ConcessionValidation
|
||||||
|
{
|
||||||
|
#region public Member
|
||||||
|
public string ConcessionType { get; set; }
|
||||||
|
public string ValidationPiont { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
public partial class ConcessionValidation
|
||||||
|
{
|
||||||
|
public ConcessionValidation()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#region public Member
|
||||||
|
[Key]
|
||||||
|
public int ValidationID { get; set; }
|
||||||
|
public DateTime ValidateDate { get; set; }
|
||||||
|
|
||||||
|
public string ConcessionCard { get; set; }
|
||||||
|
|
||||||
|
public string ConcessionHolder { get; set; }
|
||||||
|
|
||||||
|
public bool ConcessionExpiry { get; set; }
|
||||||
|
|
||||||
|
public int ConcessionTypeID { get; set; }
|
||||||
|
|
||||||
|
public string StafflinkNo { get; set; }
|
||||||
|
|
||||||
|
public int ValidationPointID { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
public string StaffFirstName { get; set; }
|
||||||
|
public string StaffLastName { get; set; }
|
||||||
|
public string StaffEmail { get; set; }
|
||||||
|
public DateTime? CreatedDate { get; set; }
|
||||||
|
public string? CreatedId { get; set; }
|
||||||
|
public DateTime? LastModified { get; set; }
|
||||||
|
public string? LastModifiedId{ get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Models
|
||||||
|
{
|
||||||
|
public class ResultModel<T>
|
||||||
|
{
|
||||||
|
public T Data { get; set; }
|
||||||
|
public int StatusCode { get; set; }
|
||||||
|
public string Message { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Models
|
||||||
|
{
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string FirstName { get; set; }
|
||||||
|
public string LastName { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string Username { get; set; }
|
||||||
|
public AdminRole Role { get; set; }
|
||||||
|
public int ValidationPointId { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public string PasswordHash { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Models.Users
|
||||||
|
{
|
||||||
|
public class AuthenticateRequest
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public string Username { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string Password { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Models.Users
|
||||||
|
{
|
||||||
|
public class AuthenticateResponse
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string FirstName { get; set; }
|
||||||
|
public string LastName { get; set; }
|
||||||
|
public string Username { get; set; }
|
||||||
|
public AdminRole Role { get; set; }
|
||||||
|
public int ValidationPointId { get; set; }
|
||||||
|
public string Token { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public AuthenticateResponse(User user, string token)
|
||||||
|
{
|
||||||
|
Id = user.Id;
|
||||||
|
FirstName = user.FirstName;
|
||||||
|
LastName = user.LastName;
|
||||||
|
Username = user.Username;
|
||||||
|
Email = user.Email;
|
||||||
|
Role = user.Role;
|
||||||
|
Token = token;
|
||||||
|
ValidationPointId = user.ValidationPointId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Models
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public class ValidationPoint
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public int ValidationPointID { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public string DisplayName { get; set; }
|
||||||
|
|
||||||
|
public bool Active { get; set; }
|
||||||
|
|
||||||
|
public DateTime? LastModified { get; set; }
|
||||||
|
public string? LastModifiedId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
CreateHostBuilder(args).Build().Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
|
Host.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseStartup<Startup>();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iis": {
|
||||||
|
"applicationUrl": "http://localhost/CarParkValidationAPI",
|
||||||
|
"sslPort": 0
|
||||||
|
},
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:61744",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"CarParkValidationAPI": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"dotnetRunMessages": "true",
|
||||||
|
"applicationUrl": "http://localhost:5100"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
//using BCryptNet = BCrypt.Net.BCrypt;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Helpers;
|
||||||
|
using CarParkValidationAPI.Models.Users;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Datas;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Repository
|
||||||
|
{
|
||||||
|
public class AdminUserFakeRepository : IAdminUser
|
||||||
|
{
|
||||||
|
private DataContext _context;
|
||||||
|
private string _currentUser = "";
|
||||||
|
List<AdminUserViewDto> _resultList = new List<AdminUserViewDto>();
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
|
||||||
|
|
||||||
|
public AdminUserFakeRepository(
|
||||||
|
DataContext context,
|
||||||
|
|
||||||
|
IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCurrentUser(string username)
|
||||||
|
{
|
||||||
|
_currentUser = username;
|
||||||
|
}
|
||||||
|
private AdminUserDto FillAdminUserDto(AdminUser model)
|
||||||
|
{
|
||||||
|
AdminUserDto dto = new AdminUserDto();
|
||||||
|
dto.Id = model.UserID;
|
||||||
|
dto.Name = model.Name;
|
||||||
|
dto.RoleType = model.RoleType;
|
||||||
|
dto.StafflinkNo = model.StafflinkNo;
|
||||||
|
dto.Active = model.Active;
|
||||||
|
dto.AddedBy = model.AddedBy;
|
||||||
|
dto.AddedOn = model.AddedOn;
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AdminUser FillAdminUser(AdminUserDto dto, AdminUser model)
|
||||||
|
{
|
||||||
|
model.UserID = dto.Id;
|
||||||
|
model.Name = dto.Name;
|
||||||
|
model.RoleType = dto.RoleType;
|
||||||
|
model.StafflinkNo = dto.StafflinkNo;
|
||||||
|
model.Active = dto.Active;
|
||||||
|
model.AddedBy = dto.AddedBy;
|
||||||
|
model.AddedOn = dto.AddedOn;
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<bool>> CheckAdminUserByStaffLinkNoAsync(string staffLinkNo)
|
||||||
|
{
|
||||||
|
var list = await _context.AdminUsers.Where(x => x.StafflinkNo == staffLinkNo).ToListAsync();
|
||||||
|
return new ResultModel<bool>()
|
||||||
|
{
|
||||||
|
Data = false,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<List<AdminUserViewDto>>> LoadAdminUserAsync(bool onlyActive)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
List<AdminUserDto> resultList = new List<AdminUserDto>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var it = await _context.AdminUsers.AsQueryable().ToListAsync();
|
||||||
|
|
||||||
|
AdminUserDto dto;
|
||||||
|
for (int i = 0; i < it.Count; i++)
|
||||||
|
{
|
||||||
|
dto = FillAdminUserDto(it[i]);
|
||||||
|
resultList.Add(dto);
|
||||||
|
}
|
||||||
|
//var it = await Task.Run(() => _list);
|
||||||
|
|
||||||
|
return new ResultModel<List<AdminUserDto>>()
|
||||||
|
{
|
||||||
|
Data = resultList,
|
||||||
|
StateCode = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
var list = await _context.AdminUsers.Where(x => x.Active == onlyActive).ToListAsync();
|
||||||
|
for (int i =0; i < list.Count; i++)
|
||||||
|
{
|
||||||
|
AdminUserViewDto dto = new AdminUserViewDto();
|
||||||
|
dto.Id = i;
|
||||||
|
dto.Name = $"Name {i}";
|
||||||
|
dto.RoleType = AdminRole.Admin.ToString();
|
||||||
|
dto.StafflinkNo = $"{i+40000}";
|
||||||
|
dto.Active = true;
|
||||||
|
dto.AddedOn = DateTime.Today.AddDays(i);
|
||||||
|
dto.AddedBy = "ddfed";
|
||||||
|
_resultList.Add(dto);
|
||||||
|
}
|
||||||
|
return new ResultModel<List<AdminUserViewDto>>()
|
||||||
|
{
|
||||||
|
Data = _resultList,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<AdminUserDto>> LoadAdminUserByIdAsync(int id)
|
||||||
|
{
|
||||||
|
AdminUserDto result = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (id > 0)
|
||||||
|
{
|
||||||
|
AdminUser model = await _context.AdminUsers.FindAsync(id);
|
||||||
|
result = FillAdminUserDto(model);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<AdminUserDto>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<int>> SaveAdminUserAsync(AdminUserDto item)
|
||||||
|
{
|
||||||
|
int result = default(int);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AdminUser model;
|
||||||
|
if (item.Id > 0)
|
||||||
|
{
|
||||||
|
model = await _context.AdminUsers.FindAsync(item.Id);
|
||||||
|
model = FillAdminUser(item, model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model = new AdminUser();
|
||||||
|
model = FillAdminUser(item, model);
|
||||||
|
_context.AdminUsers.Add(model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = -1;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<bool>> DeleteAdminUserAsync(int id)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (id > 0)
|
||||||
|
{
|
||||||
|
AdminUser model = await _context.AdminUsers.FindAsync(id);
|
||||||
|
model.Active = false;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<bool>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,275 @@
|
|||||||
|
//using BCryptNet = BCrypt.Net.BCrypt;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Helpers;
|
||||||
|
using CarParkValidationAPI.Models.Users;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Datas;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Repository
|
||||||
|
{
|
||||||
|
public class AdminUserRepository : IAdminUser
|
||||||
|
{
|
||||||
|
private DataContext _context;
|
||||||
|
private string _currentUser = "";
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
private Dictionary<int, string> _ValidationPointDic = null;
|
||||||
|
|
||||||
|
|
||||||
|
public AdminUserRepository(
|
||||||
|
DataContext context,
|
||||||
|
|
||||||
|
IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
}
|
||||||
|
public void SetCurrentUser(string username)
|
||||||
|
{
|
||||||
|
_currentUser = username;
|
||||||
|
}
|
||||||
|
private string GetValidtionPointDesc(int id)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
if (_ValidationPointDic != null && _ValidationPointDic.ContainsKey(id))
|
||||||
|
result = _ValidationPointDic[id];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
private AdminUserViewDto FillAdminUserViewDto(AdminUser model)
|
||||||
|
{
|
||||||
|
AdminUserViewDto dto = new AdminUserViewDto();
|
||||||
|
dto.Id = model.UserID;
|
||||||
|
dto.Name = model.Name;
|
||||||
|
dto.RoleType = model.RoleType.ToString();
|
||||||
|
dto.StafflinkNo = model.StafflinkNo;
|
||||||
|
dto.Active = model.Active;
|
||||||
|
dto.AddedBy = model.AddedBy;
|
||||||
|
dto.AddedOn = model.AddedOn;
|
||||||
|
dto.ValidationPoint = GetValidtionPointDesc(model.ValidationPointID??0);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
private AdminUserDto FillAdminUserDto(AdminUser model)
|
||||||
|
{
|
||||||
|
AdminUserDto dto = new AdminUserDto();
|
||||||
|
dto.Id = model.UserID;
|
||||||
|
dto.Name = model.Name;
|
||||||
|
dto.RoleType = model.RoleType;
|
||||||
|
dto.StafflinkNo = model.StafflinkNo;
|
||||||
|
dto.Active = model.Active;
|
||||||
|
dto.AddedBy = model.AddedBy;
|
||||||
|
dto.AddedOn = model.AddedOn;
|
||||||
|
dto.ValidationPointId = model.ValidationPointID ?? 0;
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AdminUser FillAdminUser(AdminUserDto dto, AdminUser model)
|
||||||
|
{
|
||||||
|
if (dto.Id > 0)
|
||||||
|
model.UserID = dto.Id;
|
||||||
|
model.Name = dto.Name;
|
||||||
|
model.RoleType = dto.RoleType;
|
||||||
|
model.StafflinkNo = dto.StafflinkNo;
|
||||||
|
model.Active = dto.Active;
|
||||||
|
model.AddedBy = dto.AddedBy;
|
||||||
|
model.AddedOn = dto.AddedOn.ToLocalTime();
|
||||||
|
model.ValidationPointID = dto.ValidationPointId;
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<List<AdminUserViewDto>>> LoadAdminUserAsync(bool onlyActive)
|
||||||
|
{
|
||||||
|
List<AdminUserViewDto> resultList = new List<AdminUserViewDto>();
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_ValidationPointDic = await _context.Validations.Where(x => x.Active == true).ToDictionaryAsync((x) => x.ValidationPointID, y => y.Description);
|
||||||
|
|
||||||
|
//var list = await _context.AdminUsers.Where(x => x.Active == onlyActive).ToListAsync();
|
||||||
|
var list = await _context.AdminUsers.AsQueryable().ToListAsync();
|
||||||
|
|
||||||
|
AdminUserViewDto dto;
|
||||||
|
AdminUser user;
|
||||||
|
for (int i = 0; i < list.Count; i++)
|
||||||
|
{
|
||||||
|
user = list[i];
|
||||||
|
dto = FillAdminUserViewDto(user);
|
||||||
|
resultList.Add(dto);
|
||||||
|
|
||||||
|
}
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<List<AdminUserViewDto>>()
|
||||||
|
{
|
||||||
|
Data = resultList,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<bool>> CheckAdminUserByStaffLinkNoAsync(string staffLinkNo)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(staffLinkNo))
|
||||||
|
{
|
||||||
|
var list = await _context.AdminUsers.Where( x=> x.StafflinkNo == staffLinkNo).ToListAsync();
|
||||||
|
if (list.Count > 0)
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<bool>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<AdminUserDto>> LoadAdminUserByIdAsync(int id)
|
||||||
|
{
|
||||||
|
AdminUserDto result = null;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (id > 0)
|
||||||
|
{
|
||||||
|
AdminUser model = await _context.AdminUsers.FindAsync(id);
|
||||||
|
result = FillAdminUserDto(model);
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<AdminUserDto>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<int>> SaveAdminUserAsync(AdminUserDto item)
|
||||||
|
{
|
||||||
|
int result = default(int);
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AdminUser model;
|
||||||
|
if (item.Id > 0)
|
||||||
|
{
|
||||||
|
model = await _context.AdminUsers.FindAsync(item.Id);
|
||||||
|
model = FillAdminUser(item, model);
|
||||||
|
model.LastModified = DateTime.Now;
|
||||||
|
model.LastModifiedId = _currentUser;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
result = model.UserID;
|
||||||
|
statuscode = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
ResultModel<bool> found = await CheckAdminUserByStaffLinkNoAsync(item.StafflinkNo);
|
||||||
|
|
||||||
|
if (!found.Data)
|
||||||
|
{
|
||||||
|
model = new AdminUser();
|
||||||
|
model = FillAdminUser(item, model);
|
||||||
|
_context.AdminUsers.Add(model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
result = model.UserID;
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error = "staff link No '" + item.StafflinkNo + "' already in admin user";
|
||||||
|
statuscode = 0;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = -1;
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<bool>> DeleteAdminUserAsync(int id)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (id > 0)
|
||||||
|
{
|
||||||
|
AdminUser model = await _context.AdminUsers.FindAsync(id);
|
||||||
|
model.Active = false;
|
||||||
|
model.LastModified = DateTime.Now;
|
||||||
|
model.LastModifiedId = _currentUser;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
result = false;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<bool>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
//using BCryptNet = BCrypt.Net.BCrypt;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Helpers;
|
||||||
|
using CarParkValidationAPI.Models.Users;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Datas;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Repository
|
||||||
|
{
|
||||||
|
public class ConcessionTypeRepository : IConcessionType
|
||||||
|
{
|
||||||
|
private DataContext _context;
|
||||||
|
private string _currentUser = "";
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
|
||||||
|
public ConcessionTypeRepository(
|
||||||
|
DataContext context,
|
||||||
|
|
||||||
|
IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
|
||||||
|
_context = context;
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
}
|
||||||
|
public void SetCurrentUser(string username)
|
||||||
|
{
|
||||||
|
_currentUser = username;
|
||||||
|
}
|
||||||
|
private ConcessionTypeDto FillConcessionTypeDto(ConcessionType model)
|
||||||
|
{
|
||||||
|
ConcessionTypeDto dto = new ConcessionTypeDto();
|
||||||
|
dto.Active = model.Active;
|
||||||
|
dto.Description = model.ConcessionDesc;
|
||||||
|
dto.Display = model.ConcessionDisplay;
|
||||||
|
dto.Id = model.ConcessionTypeID;
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
private ConcessionType FillConcessionType(ConcessionTypeDto dto, ConcessionType model)
|
||||||
|
{
|
||||||
|
model.Active = dto.Active;
|
||||||
|
model.ConcessionDesc = dto.Description.Trim();
|
||||||
|
if (!string.IsNullOrEmpty(dto.Display))
|
||||||
|
model.ConcessionDisplay = dto.Display.Trim();
|
||||||
|
if (dto.Id > 0)
|
||||||
|
model.ConcessionTypeID = dto.Id;
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<List<ConcessionTypeDto>>> LoadConcessionTypeAsync(bool onlyActive)
|
||||||
|
{
|
||||||
|
List<ConcessionTypeDto> result = null;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
result = await _context.ConcessionTypes.Select(
|
||||||
|
x => new ConcessionTypeDto()
|
||||||
|
{
|
||||||
|
Id = x.ConcessionTypeID,
|
||||||
|
Description = x.ConcessionDesc,
|
||||||
|
Display = x.ConcessionDisplay,
|
||||||
|
Active = x.Active
|
||||||
|
}).ToListAsync();
|
||||||
|
|
||||||
|
//var olist = await _context.ConcessionTypes.ToListAsync();
|
||||||
|
//result = _mapper.Map<List<ConcessionTypeDto>>(olist);
|
||||||
|
statuscode = 1;
|
||||||
|
result.Sort((x, y) => x.Description.CompareTo(y.Description));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<List<ConcessionTypeDto>>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<ConcessionTypeDto>> LoadConcessionTypeByIdAsync(int id)
|
||||||
|
{
|
||||||
|
ConcessionType result = null;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
ConcessionTypeDto dto;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = await _context.ConcessionTypes.FindAsync(id);
|
||||||
|
dto = new();
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
dto.Id = id;
|
||||||
|
dto.Active = result.Active;
|
||||||
|
dto.Description = result.ConcessionDesc;
|
||||||
|
dto.Display = result.ConcessionDisplay;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// dto = _mapper.Map<ConcessionTypeDto>(result);
|
||||||
|
//dto = FillConcessionTypeDto(result);
|
||||||
|
//result = _list.Find(x => x.Id == id);
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
return new ResultModel<ConcessionTypeDto>()
|
||||||
|
{
|
||||||
|
Data = dto,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<int>> SaveConcessionTypeAsync(ConcessionTypeDto item)
|
||||||
|
{
|
||||||
|
int result = default(int);
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ConcessionType model;
|
||||||
|
if (item.Id > 0)
|
||||||
|
{
|
||||||
|
model = await _context.ConcessionTypes.FindAsync(item.Id);
|
||||||
|
model = FillConcessionType(item, model);
|
||||||
|
model.LastModified = DateTime.Now;
|
||||||
|
model.LastModifiedId = _currentUser;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
result = item.Id;
|
||||||
|
}
|
||||||
|
else //new record
|
||||||
|
{
|
||||||
|
model = new ConcessionType();
|
||||||
|
model = FillConcessionType(item, model);
|
||||||
|
model.LastModified = DateTime.Now;
|
||||||
|
model.LastModifiedId = _currentUser;
|
||||||
|
_context.ConcessionTypes.Add(model);
|
||||||
|
var id = await _context.SaveChangesAsync();
|
||||||
|
result = model.ConcessionTypeID;
|
||||||
|
|
||||||
|
}
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<bool>> DeleteConcessionTypeAsync(int id)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ConcessionType model;
|
||||||
|
if (id > 0)
|
||||||
|
{
|
||||||
|
model = await _context.ConcessionTypes.FindAsync(id);
|
||||||
|
model.Active = false;
|
||||||
|
//_context.ConcessionTypes.Remove(model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
return new ResultModel<bool>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<Dictionary<int, LookupCodeDto>>> GetConcessionTypeDicAsync()
|
||||||
|
{
|
||||||
|
Dictionary<int, LookupCodeDto> resultList = new();
|
||||||
|
|
||||||
|
int statusCode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
resultList = await _context.ConcessionTypes.Where(x => x.Active == true)
|
||||||
|
.Select(item => new LookupCodeDto { Id = item.ConcessionTypeID, Description = item.ConcessionDesc ?? "" })
|
||||||
|
.ToDictionaryAsync(x => x.Id);
|
||||||
|
|
||||||
|
|
||||||
|
statusCode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statusCode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
return new ResultModel<Dictionary<int, LookupCodeDto>>()
|
||||||
|
{
|
||||||
|
Data = resultList,
|
||||||
|
StatusCode = statusCode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
using CarParkValidationAPI.Datas;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SpreadsheetLight;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Repository
|
||||||
|
{
|
||||||
|
public class ConcessionValidationReportRepository
|
||||||
|
{
|
||||||
|
private readonly DataContext _context;
|
||||||
|
private readonly IOptions<AppSettings> _appSettings;
|
||||||
|
const string DateFormat = "dd-MM-yyyy HH:mm";
|
||||||
|
const string dateFormat = "dd-MM-yyyyy";
|
||||||
|
public ConcessionValidationReportRepository(
|
||||||
|
DataContext context, IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_appSettings = appSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<FileContent>> GetConcessionValidationReport(DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
//excel SLDocument sl = new SLDocument();
|
||||||
|
int statusCode = 1;
|
||||||
|
ConcessionValidationExtDto item;
|
||||||
|
int col = 1;
|
||||||
|
int row = 1;
|
||||||
|
SLDocument sl = new SLDocument();
|
||||||
|
|
||||||
|
|
||||||
|
//first sheetName
|
||||||
|
sl.RenameWorksheet(SLDocument.DefaultFirstSheetName, "ConcessionValidation");
|
||||||
|
SLStyle style = sl.CreateStyle();
|
||||||
|
style.SetFontUnderline(DocumentFormat.OpenXml.Spreadsheet.UnderlineValues.Single);
|
||||||
|
style.SetFontBold(true);
|
||||||
|
style.SetFont("Arial Black", 16);
|
||||||
|
sl.SetCellStyle(1, 5, style);
|
||||||
|
sl.SetRowHeight(1, 1, 25);
|
||||||
|
sl.SetCellValue(row++, 5, "The Concession Validation Report");
|
||||||
|
sl.SetCellValue(row, 3, "Date Range: " + fromDate.ToString(dateFormat) + " - " + toDate.ToString(dateFormat) );
|
||||||
|
sl.SetCellValue(1, 6, " " + DateTime.Now.ToString("ddd dd/MM/yyyy HH:mm"));
|
||||||
|
|
||||||
|
int startTitleRow = 3;
|
||||||
|
row = startTitleRow;
|
||||||
|
//make the title bold
|
||||||
|
style = sl.CreateStyle();
|
||||||
|
style.Font.Bold = true;
|
||||||
|
sl.SetRowStyle(startTitleRow, style);
|
||||||
|
//set it height
|
||||||
|
sl.SetRowHeight(startTitleRow, startTitleRow, 25);
|
||||||
|
// add the title first
|
||||||
|
sl.SetCellValue(row, col++, "Date");
|
||||||
|
sl.SetCellValue(row, col++, "Concession Card Number");
|
||||||
|
sl.SetCellValue(row, col++, "Concession Holder Name");
|
||||||
|
sl.SetCellValue(row, col++, "Expiry date checked");
|
||||||
|
sl.SetCellValue(row, col++, "ConcessionType");
|
||||||
|
sl.SetCellValue(row, col++, "Validation Piont");
|
||||||
|
// sl.SetCellValue(row, col++, "StaffLink No");
|
||||||
|
sl.SetCellValue(row, col++, "Enter by");
|
||||||
|
// sl.SetCellValue(row, col++, "Staff Last name");
|
||||||
|
// sl.SetCellValue(row, col++, "Staff Email");
|
||||||
|
sl.FreezePanes(row, col - 1); //frozen the row.
|
||||||
|
//wrap text on is concession Expiry
|
||||||
|
style = sl.CreateStyle();
|
||||||
|
style.SetWrapText(true);
|
||||||
|
sl.SetColumnStyle(4, style);
|
||||||
|
|
||||||
|
//format date
|
||||||
|
|
||||||
|
style = sl.CreateStyle();
|
||||||
|
style.FormatCode = "dd/MM/yyyy HH:MM";
|
||||||
|
sl.SetColumnStyle(1, style);
|
||||||
|
//make column width
|
||||||
|
sl.SetColumnWidth(1, 20);
|
||||||
|
sl.SetColumnWidth(2, 18);
|
||||||
|
sl.SetColumnWidth(3, 25);
|
||||||
|
sl.SetColumnWidth(4, 20);
|
||||||
|
sl.SetColumnWidth(5, 50);
|
||||||
|
sl.SetColumnWidth(6, 40);
|
||||||
|
sl.SetColumnWidth(7, 40);
|
||||||
|
// sl.SetColumnWidth(8, 20);
|
||||||
|
// sl.SetColumnWidth(9, 20);
|
||||||
|
// sl.SetColumnWidth(10, 20);
|
||||||
|
int startRowFrom = startTitleRow+1;
|
||||||
|
var list = await _context.SelectConcessionValidationByDate(true, fromDate.ToLocalTime(), toDate.ToLocalTime());
|
||||||
|
for (int i = 0; i < list.Count; i++)
|
||||||
|
{
|
||||||
|
col = 1;
|
||||||
|
item = list[i];
|
||||||
|
row = i + startRowFrom;
|
||||||
|
sl.SetCellValue(row, col++, item.ValidateDate);
|
||||||
|
sl.SetCellValue(row, col++, item.ConcessionCard);
|
||||||
|
sl.SetCellValue(row, col++, item.ConcessionHolder);
|
||||||
|
sl.SetCellValue(row, col++, item.ConcessionExpiry ? "Yes": "No");
|
||||||
|
sl.SetCellValue(row, col++, item.ConcessionType);
|
||||||
|
sl.SetCellValue(row, col++, item.ValidationPoint);
|
||||||
|
// sl.SetCellValue(row, col++, item.StafflinkNo);
|
||||||
|
sl.SetCellValue(row, col++, item.StaffFirstName + " " + item.StaffLastName);
|
||||||
|
// sl.SetCellValue(row, col++, item.StaffLastName);
|
||||||
|
// sl.SetCellValue(row, col++, item.StaffEmail);
|
||||||
|
}
|
||||||
|
byte[] array;
|
||||||
|
// sl.SaveAs("C:\\Temp\\Report\\ConcessionValidationDate" + DateTime.Now.ToString("yyyyMMddHHmm") + ".xlsx");
|
||||||
|
using (MemoryStream ws = new MemoryStream())
|
||||||
|
{
|
||||||
|
sl.SaveAs(ws);
|
||||||
|
array = ws.ToArray();
|
||||||
|
/*
|
||||||
|
using (FileStream fs = new FileStream("c:\\temp\\Report\\conReport.xlsx",FileMode.Create,FileAccess.Write))
|
||||||
|
{
|
||||||
|
ws.WriteTo(fs);
|
||||||
|
fs.Close();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
ws.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new FileContent
|
||||||
|
{
|
||||||
|
Content = array,
|
||||||
|
FileName = "ConcessionValidation" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm")+ ".xlsx",
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return new ResultModel<FileContent>
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statusCode
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,409 @@
|
|||||||
|
//using BCryptNet = BCrypt.Net.BCrypt;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Helpers;
|
||||||
|
using CarParkValidationAPI.Models.Users;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Datas;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Security.Cryptography.Xml;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Repository
|
||||||
|
{
|
||||||
|
public class ConcessionValidationRepository : IConcessionValidation
|
||||||
|
{
|
||||||
|
private DataContext _context;
|
||||||
|
private string _currentUser = "";
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
|
||||||
|
public ConcessionValidationRepository(
|
||||||
|
DataContext context,
|
||||||
|
IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCurrentUser(string username)
|
||||||
|
{
|
||||||
|
_currentUser = username;
|
||||||
|
}
|
||||||
|
private ConcessionValidationDto FillConcessionValidationDto(ConcessionValidation model)
|
||||||
|
{
|
||||||
|
ConcessionValidationDto dto = new ConcessionValidationDto();
|
||||||
|
dto.Active = model.Active;
|
||||||
|
dto.ConcessionCard = model.ConcessionCard;
|
||||||
|
dto.ConcessionExpiry = model.ConcessionExpiry;
|
||||||
|
dto.ConcessionHolder = model.ConcessionHolder;
|
||||||
|
dto.ConcessionTypeId = model.ConcessionTypeID;
|
||||||
|
dto.Id = model.ValidationID;
|
||||||
|
dto.StafflinkNo = model.StafflinkNo;
|
||||||
|
dto.ValidateDate = model.ValidateDate;
|
||||||
|
dto.ValidationPointId = model.ValidationPointID;
|
||||||
|
dto.StaffFirstName = model.StaffFirstName;
|
||||||
|
dto.StaffLastName = model.StaffLastName;
|
||||||
|
dto.StaffEmail = model.StaffEmail;
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConcessionValidationExtDto FillConcessionValidationExtDto(ConcessionValidation model)
|
||||||
|
{
|
||||||
|
ConcessionValidationExtDto dto = new ConcessionValidationExtDto();
|
||||||
|
dto.Active = model.Active;
|
||||||
|
dto.ConcessionCard = model.ConcessionCard;
|
||||||
|
dto.ConcessionExpiry = model.ConcessionExpiry;
|
||||||
|
dto.ConcessionHolder = model.ConcessionHolder;
|
||||||
|
dto.ConcessionTypeId = model.ConcessionTypeID;
|
||||||
|
dto.Id = model.ValidationID;
|
||||||
|
dto.StaffFirstName = model.StaffFirstName;
|
||||||
|
dto.StaffLastName = model.StaffLastName;
|
||||||
|
dto.StaffEmail = model.StaffEmail;
|
||||||
|
dto.ValidateDate = model.ValidateDate;
|
||||||
|
dto.ValidationPointId = model.ValidationPointID;
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConcessionValidation FillConcessionValidation(ConcessionValidationDto dto, ConcessionValidation model)
|
||||||
|
{
|
||||||
|
model.Active = dto.Active;
|
||||||
|
model.ConcessionCard = dto.ConcessionCard.Trim();
|
||||||
|
model.ConcessionExpiry = dto.ConcessionExpiry;
|
||||||
|
model.ConcessionHolder = dto.ConcessionHolder.Trim();
|
||||||
|
model.ConcessionTypeID = dto.ConcessionTypeId;
|
||||||
|
if (dto.Id > 0)
|
||||||
|
model.ValidationID = dto.Id;
|
||||||
|
model.StafflinkNo = dto.StafflinkNo;
|
||||||
|
model.StaffFirstName = dto.StaffFirstName.Trim();
|
||||||
|
model.StaffLastName = dto.StaffLastName.Trim();
|
||||||
|
model.StaffEmail = dto.StaffEmail.Trim();
|
||||||
|
model.ValidateDate = dto.ValidateDate.ToLocalTime();
|
||||||
|
model.ValidationPointID = dto.ValidationPointId;
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<List<ConcessionValidationExtDto>>> LoadConcessionValidationAsync(bool onlyActive)
|
||||||
|
{
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
List<ConcessionValidationExtDto> result = new List<ConcessionValidationExtDto>();
|
||||||
|
|
||||||
|
ConcessionValidationExtDto dto;
|
||||||
|
ConcessionValidation model;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<ConcessionValidation> clist = await _context.ConcessionValidations.Where(x => x.Active == true).ToListAsync();
|
||||||
|
for (int i = 0; i < clist.Count; i++)
|
||||||
|
{
|
||||||
|
model = clist[i];
|
||||||
|
dto = FillConcessionValidationExtDto(model);
|
||||||
|
result.Add(dto);
|
||||||
|
}
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
statuscode = 0;
|
||||||
|
error = ex.ToString();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<List<ConcessionValidationExtDto>>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<List<ConcessionValidationExtDto>>> LoadConcessionValidationStaffLinkNoAsync(string staffLinkNo, DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
List<ConcessionValidationExtDto> result = new List<ConcessionValidationExtDto>();
|
||||||
|
// ConcessionValidationExtDto dto;
|
||||||
|
// ConcessionValidation model;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//List<ConcessionValidation> clist = await _context.ConcessionValidations.Where(x =>
|
||||||
|
// x.Active == true
|
||||||
|
// && x.StafflinkNo == staffLinkNo
|
||||||
|
// && x.ValidateDate.Date == currentDate.Date
|
||||||
|
//).ToListAsync();
|
||||||
|
result = await _context.SelectConcessionValidationByStaffId(true, staffLinkNo, fromDate, toDate);
|
||||||
|
/*
|
||||||
|
//var clist = await _context.SPSelectValidation(true, staffLinkNo, currentDate);
|
||||||
|
for (int i = 0; i < clist.Count; i++)
|
||||||
|
{
|
||||||
|
model = clist[i];
|
||||||
|
dto = FillConcessionValidationExtDto(model);
|
||||||
|
result.Add(dto);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
statuscode = 1;
|
||||||
|
result.Sort((x, y) => y.ValidateDate.CompareTo(x.ValidateDate));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
statuscode = 0;
|
||||||
|
error = ex.ToString();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<List<ConcessionValidationExtDto>>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<int>> CheckConcessionValidationStaffLinkNoAsync(string staffLinkNo, string concessionCard, DateTime currentDate, int id)
|
||||||
|
{
|
||||||
|
int statuscode = 1;
|
||||||
|
int result = 1;
|
||||||
|
int number = id < 1 ? 0 : 1; // if insert check > 0 . if modify > 1
|
||||||
|
string message = "warning you already add concession card on this date!";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var anyRecord = await _context.SelectCheckConcessionValidationAsync(currentDate.ToLocalTime().Date, concessionCard.Trim(), staffLinkNo.Trim());
|
||||||
|
|
||||||
|
if (anyRecord.Count > number)
|
||||||
|
{
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = 1; //test
|
||||||
|
message = "test OK just one time";
|
||||||
|
}
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
message = "Error " + ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<ResultModel<int>> CheckConcessionValidationStaffLinkNoAsync_old(string staffLinkNo, string concessionCard, DateTime currentDate)
|
||||||
|
{
|
||||||
|
int statuscode = 1;
|
||||||
|
int result = 1;
|
||||||
|
string concard = concessionCard.Trim();
|
||||||
|
string message = "warning you already add concession card on this date!";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var anyRecord = await _context.ConcessionValidations.Where(x =>
|
||||||
|
x.StafflinkNo == staffLinkNo
|
||||||
|
&& x.ConcessionCard == concard
|
||||||
|
&& x.Active == true
|
||||||
|
&& x.ValidateDate.Date == currentDate.ToLocalTime().Date
|
||||||
|
).ToListAsync();
|
||||||
|
if (anyRecord.Count > 0)
|
||||||
|
{
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = 1; //test
|
||||||
|
message = "test OK just one time";
|
||||||
|
}
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
message = "Error " + ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<ConcessionValidationDto>> LoadConcessionValidationByIdAsync(int id)
|
||||||
|
{
|
||||||
|
ConcessionValidationDto result = null;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (id > 0)
|
||||||
|
{
|
||||||
|
ConcessionValidation model = await _context.ConcessionValidations.FindAsync(id);
|
||||||
|
result = FillConcessionValidationDto(model);
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
statuscode = 0;
|
||||||
|
error = ex.ToString();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<ConcessionValidationDto>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<ConcessionValidationDto>> LoadConcessionValidationByCardNumberAsync(string cardNo)
|
||||||
|
{
|
||||||
|
ConcessionValidationDto result = null;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(cardNo))
|
||||||
|
{
|
||||||
|
|
||||||
|
var list = await _context.ConcessionValidations.Where(x => x.ConcessionCard == cardNo).ToListAsync();
|
||||||
|
if (list != null && list.Count > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
result = FillConcessionValidationDto(list[0]);
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
statuscode = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
statuscode = 0;
|
||||||
|
error = ex.ToString();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<ConcessionValidationDto>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<int>> SaveConcessionValidationAsync(ConcessionValidationDto item)
|
||||||
|
{
|
||||||
|
int result = default(int);
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
//_currentUser = item.StafflinkNo;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ConcessionValidation model;
|
||||||
|
if (item.Id > 0)
|
||||||
|
{
|
||||||
|
model = await _context.ConcessionValidations.FindAsync(item.Id);
|
||||||
|
model = FillConcessionValidation(item, model);
|
||||||
|
model.LastModified = DateTime.Now;
|
||||||
|
model.LastModifiedId = _currentUser;
|
||||||
|
result = await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model = new ConcessionValidation();
|
||||||
|
model = FillConcessionValidation(item, model);
|
||||||
|
model.LastModified = DateTime.Now;
|
||||||
|
model.LastModifiedId = _currentUser;
|
||||||
|
model.CreatedDate = DateTime.Now;
|
||||||
|
model.CreatedId = _currentUser;
|
||||||
|
_context.ConcessionValidations.Add(model);
|
||||||
|
result = await _context.SaveChangesAsync();
|
||||||
|
result = model.ValidationID;
|
||||||
|
}
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
statuscode = 0;
|
||||||
|
error = ex.ToString();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<bool>> DeleteConcessionValidationAsync(int id)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (id > 0)
|
||||||
|
{
|
||||||
|
ConcessionValidation model = await _context.ConcessionValidations.FindAsync(id);
|
||||||
|
model.Active = false;
|
||||||
|
model.LastModified = DateTime.Now;
|
||||||
|
model.LastModifiedId = _currentUser;
|
||||||
|
//_context.ConcessionValidations.Remove(model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
statuscode = 0;
|
||||||
|
error = ex.ToString();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new ResultModel<bool>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<FileContent>> GetReport(DateTime fromDate, DateTime toDate)
|
||||||
|
{
|
||||||
|
int statusCode = 1;
|
||||||
|
string fileContext = "filecontain as string this is file contain in string format";
|
||||||
|
//await this._concessionValidationReport.GetConcessionValidationReport(DateTime.Today.AddDays(-30), DateTime.Today.AddDays(30));
|
||||||
|
var result = new FileContent
|
||||||
|
{
|
||||||
|
Content = Convert.FromBase64String(fileContext),
|
||||||
|
FileName = "excel extension"
|
||||||
|
};
|
||||||
|
var task = await Task.Run(() => 1);
|
||||||
|
return new ResultModel<FileContent>
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statusCode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
//using BCryptNet = BCrypt.Net.BCrypt;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Helpers;
|
||||||
|
using CarParkValidationAPI.Models.Users;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Datas;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Repository
|
||||||
|
{
|
||||||
|
|
||||||
|
public class LookupCodeRepository: ILookupCode
|
||||||
|
{
|
||||||
|
private DataContext _context;
|
||||||
|
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
|
||||||
|
public LookupCodeRepository(
|
||||||
|
DataContext context,
|
||||||
|
|
||||||
|
IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<List<LookupCodeDto>>> LoadConcessionTypeAsync(bool onlyActive)
|
||||||
|
{
|
||||||
|
List<LookupCodeDto> result = null;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = await _context.ConcessionTypes.Where(x => x.Active == onlyActive).Select(
|
||||||
|
x => new LookupCodeDto()
|
||||||
|
{
|
||||||
|
Id = x.ConcessionTypeID,
|
||||||
|
Description = x.ConcessionDesc,
|
||||||
|
|
||||||
|
}).ToListAsync();
|
||||||
|
statuscode = 1;
|
||||||
|
result.Sort((x,y) => x.Description.CompareTo(y.Description));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
statuscode = 0;
|
||||||
|
error = ex.ToString();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return new ResultModel<List<LookupCodeDto>>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<List<LookupCodeDto>>> LoadValidationPointAsync(bool onlyActive)
|
||||||
|
{
|
||||||
|
List<LookupCodeDto> result = null;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
result = await _context.Validations.Where(x => x.Active == onlyActive).Select(
|
||||||
|
x => new LookupCodeDto()
|
||||||
|
{
|
||||||
|
Id = x.ValidationPointID,
|
||||||
|
Description = x.Description
|
||||||
|
}).ToListAsync();
|
||||||
|
result.Sort((x, y) => x.Description.CompareTo(y.Description));
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
statuscode = 0;
|
||||||
|
error = ex.ToString();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return new ResultModel<List<LookupCodeDto>>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,384 @@
|
|||||||
|
//using BCryptNet = BCrypt.Net.BCrypt;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Helpers;
|
||||||
|
using CarParkValidationAPI.Models.Users;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Datas;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
using CommonAD;
|
||||||
|
using SpreadsheetLight;
|
||||||
|
using System.IO;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Repository
|
||||||
|
{
|
||||||
|
public class UserRepository : IUserService
|
||||||
|
{
|
||||||
|
private DataContext _context;
|
||||||
|
private IJwtUtils _jwtUtils;
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
private readonly IValidationPoint _validationPoint;
|
||||||
|
private Dictionary<int, LookupCodeDto> _validationPointDic;
|
||||||
|
|
||||||
|
public UserRepository(
|
||||||
|
DataContext context,
|
||||||
|
IJwtUtils jwtUtils,
|
||||||
|
IValidationPoint validationPoint,
|
||||||
|
IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_jwtUtils = jwtUtils;
|
||||||
|
_validationPoint = validationPoint;
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticateResponse Authenticate(AuthenticateRequest model)
|
||||||
|
{
|
||||||
|
var user = _context.Users.SingleOrDefault(x => x.Username == model.Username);
|
||||||
|
|
||||||
|
// validate
|
||||||
|
// if (user == null || !BCryptNet.Verify(model.Password, user.PasswordHash))
|
||||||
|
if (user == null || (model.Password != user.PasswordHash))
|
||||||
|
throw new System.Exception("Username or password is incorrect");
|
||||||
|
|
||||||
|
// authentication successful so generate jwt token
|
||||||
|
var jwtToken = _jwtUtils.GenerateJwtToken(user);
|
||||||
|
|
||||||
|
return new AuthenticateResponse(user, jwtToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<AuthenticateResponse>> LoginApiAD(AuthenticateRequest model)
|
||||||
|
{
|
||||||
|
User myUser = null;
|
||||||
|
AuthenticateResponse retval = null;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
string webAPIUrl = _appSettings.LoginWebAPI;
|
||||||
|
|
||||||
|
var loginInfo = await CommonAD.WebAPIUtil.PostLoginADAsync(webAPIUrl, "CheckCredentials", model.Username, model.Password);
|
||||||
|
if (loginInfo != null && loginInfo.result)
|
||||||
|
{
|
||||||
|
myUser = new User();
|
||||||
|
myUser.Email = loginInfo.email;
|
||||||
|
myUser.FirstName = loginInfo.firstName;
|
||||||
|
myUser.LastName = loginInfo.lastName;
|
||||||
|
myUser.Username = loginInfo.stafflinkNo;
|
||||||
|
//now check the adminuser table
|
||||||
|
var user = _context.AdminUsers.
|
||||||
|
SingleOrDefault(x => x.StafflinkNo == model.Username
|
||||||
|
&& x.Active == true);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
myUser.Role = user.RoleType;
|
||||||
|
myUser.Id = user.UserID;
|
||||||
|
myUser.ValidationPointId = user.ValidationPointID??0;
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
else //not allow
|
||||||
|
{
|
||||||
|
statuscode = 0;
|
||||||
|
error = "username is not exist in admimuser.";
|
||||||
|
myUser.Role = AdminRole.Normal;
|
||||||
|
}
|
||||||
|
// validate
|
||||||
|
// if (user == null || !BCryptNet.Verify(model.Password, user.PasswordHash))
|
||||||
|
|
||||||
|
// authentication successful so generate jwt token
|
||||||
|
var jwtToken = _jwtUtils.GenerateJwtToken(myUser);
|
||||||
|
//statuscode = 1;
|
||||||
|
retval = new AuthenticateResponse(myUser, jwtToken);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = "error username or password is invalid";
|
||||||
|
|
||||||
|
return new ResultModel<AuthenticateResponse>()
|
||||||
|
{
|
||||||
|
Data = retval,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<AuthenticateResponse>> LoginAD(AuthenticateRequest model)
|
||||||
|
{
|
||||||
|
User myUser = null;
|
||||||
|
AuthenticateResponse retval = null;
|
||||||
|
string error = "user name is not in DB or user Name profile is not generic";
|
||||||
|
int statuscode = 0;
|
||||||
|
string webAPIUrl = _appSettings.LoginWebAPI;
|
||||||
|
//KCO, D204KCO
|
||||||
|
//now check the adminuser table
|
||||||
|
//ward clerk
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var loginInfo = await CommonAD.WebAPIUtil.PostLoginADAsync(webAPIUrl, "CheckCredentials", model.Username, model.Password);
|
||||||
|
if (loginInfo != null && loginInfo.result)
|
||||||
|
{
|
||||||
|
myUser = new User();
|
||||||
|
myUser.Email = loginInfo.email;
|
||||||
|
myUser.FirstName = loginInfo.firstName;
|
||||||
|
myUser.LastName = loginInfo.lastName;
|
||||||
|
myUser.Username = loginInfo.stafflinkNo;
|
||||||
|
//myUser.Department = loginInfo.department;
|
||||||
|
//myUser.Position = loginInfo.jobTitle;
|
||||||
|
//myUser.ManagerEmail = loginInfo.managerEmail;
|
||||||
|
//myUser.Phone = loginInfo.phone;
|
||||||
|
//now check the adminuser table
|
||||||
|
var user = _context.AdminUsers.
|
||||||
|
SingleOrDefault(x => x.StafflinkNo == model.Username
|
||||||
|
&& true == x.Active);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
// myUser.Role = user.RoleType;
|
||||||
|
myUser.Id = user.UserID;
|
||||||
|
myUser.Role = user.RoleType;
|
||||||
|
//myUser.ValidationPointId = user.ValidationPointID ?? 0;
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
else // allow
|
||||||
|
{
|
||||||
|
statuscode = 1;
|
||||||
|
myUser.Role = AdminRole.Normal;
|
||||||
|
myUser.Id = -1;
|
||||||
|
|
||||||
|
//error = "user name does not exist in adminUser";
|
||||||
|
}
|
||||||
|
// validate
|
||||||
|
// if (user == null || !BCryptNet.Verify(model.Password, user.PasswordHash))
|
||||||
|
|
||||||
|
// authentication successful so generate jwt token
|
||||||
|
if (statuscode == 1)
|
||||||
|
{
|
||||||
|
var jwtToken = _jwtUtils.GenerateJwtToken(myUser);
|
||||||
|
retval = new AuthenticateResponse(myUser, jwtToken);
|
||||||
|
error = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error = "user name or password is not correct";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
retval = null;
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
return new ResultModel<AuthenticateResponse>()
|
||||||
|
{
|
||||||
|
Data = retval,
|
||||||
|
StatusCode = statuscode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<List<User>>> GetAllUsers()
|
||||||
|
{
|
||||||
|
var retval = await _context.Users.ToListAsync();
|
||||||
|
return new ResultModel<List<User>>()
|
||||||
|
{
|
||||||
|
Data = retval,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<User>> GetById(int id)
|
||||||
|
{
|
||||||
|
var user = await _context.Users.FindAsync(id);
|
||||||
|
if (user == null) throw new KeyNotFoundException("User not found");
|
||||||
|
return new ResultModel<User>()
|
||||||
|
{
|
||||||
|
Data = user,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<User>> SearchApiStaff(string staffLinkNo)
|
||||||
|
{
|
||||||
|
User myUser = null;
|
||||||
|
int statuscode = 0;
|
||||||
|
string webAPIUrl = _appSettings.LoginWebAPI;
|
||||||
|
var loginInfo = await CommonAD.WebAPIUtil.SearchStaffAsync(webAPIUrl, "SearchStaff", staffLinkNo);
|
||||||
|
if (loginInfo != null && loginInfo.result)
|
||||||
|
{
|
||||||
|
myUser = new User();
|
||||||
|
myUser.Email = loginInfo.email;
|
||||||
|
myUser.FirstName = loginInfo.firstName;
|
||||||
|
myUser.LastName = loginInfo.lastName;
|
||||||
|
myUser.Username = loginInfo.stafflinkNo;
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResultModel<User>()
|
||||||
|
{
|
||||||
|
Data = myUser,
|
||||||
|
StatusCode = statuscode
|
||||||
|
};
|
||||||
|
// return myUser;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<User>> SearchADStaff(string staffLinkNo)
|
||||||
|
{
|
||||||
|
int statuscode = 0;
|
||||||
|
User myUser = null;
|
||||||
|
AuthenticateResponse retval = null;
|
||||||
|
|
||||||
|
|
||||||
|
string webAPIUrl = _appSettings.LoginWebAPI;
|
||||||
|
var loginInfo = await CommonAD.WebAPIUtil.SearchStaffAsync(webAPIUrl, "SearchStaff", staffLinkNo);
|
||||||
|
if (!string.IsNullOrEmpty(loginInfo.firstName))
|
||||||
|
{
|
||||||
|
myUser = new();
|
||||||
|
myUser.FirstName = loginInfo.firstName;
|
||||||
|
myUser.LastName = loginInfo.lastName;
|
||||||
|
myUser.Username = staffLinkNo;
|
||||||
|
myUser.Email = loginInfo.email;
|
||||||
|
/*
|
||||||
|
myUser.Department = loginInfo.department;
|
||||||
|
myUser.Position = loginInfo.jobTitle;
|
||||||
|
myUser.Phone = loginInfo.phone;
|
||||||
|
myUser.ManagerEmail = loginInfo.managerEmail;
|
||||||
|
*/
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
return new ResultModel<User>()
|
||||||
|
{
|
||||||
|
Data = myUser,
|
||||||
|
StatusCode = statuscode
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private string GetVPDesc(int? idn)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
int id = idn ?? 1;
|
||||||
|
if (_validationPointDic.ContainsKey(id))
|
||||||
|
{
|
||||||
|
result = _validationPointDic[id].Description;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<FileContent>> GetAllUserReport()
|
||||||
|
{
|
||||||
|
//excel SLDocument sl = new SLDocument();
|
||||||
|
int statusCode = 1;
|
||||||
|
AdminUser item;
|
||||||
|
int col = 1;
|
||||||
|
int row = 1;
|
||||||
|
SLDocument sl = new SLDocument();
|
||||||
|
var ret = await _validationPoint.GetValidationPointDicAsync();
|
||||||
|
if (ret.StatusCode == 1)
|
||||||
|
_validationPointDic = ret.Data;
|
||||||
|
//first sheetName
|
||||||
|
sl.RenameWorksheet(SLDocument.DefaultFirstSheetName, "All User");
|
||||||
|
SLStyle style = sl.CreateStyle();
|
||||||
|
style.SetFontUnderline(DocumentFormat.OpenXml.Spreadsheet.UnderlineValues.Single);
|
||||||
|
style.SetFontBold(true);
|
||||||
|
style.SetFont("Arial Black", 16);
|
||||||
|
sl.SetCellStyle(1, 5, style);
|
||||||
|
sl.SetRowHeight(1, 1, 25);
|
||||||
|
sl.SetCellValue(row++, 5, "The User Report");
|
||||||
|
|
||||||
|
sl.SetCellValue(1, 6, " " + DateTime.Now.ToString("ddd dd/MM/yyyy HH:mm"));
|
||||||
|
|
||||||
|
int startTitleRow = 3;
|
||||||
|
row = startTitleRow;
|
||||||
|
//make the title bold
|
||||||
|
style = sl.CreateStyle();
|
||||||
|
style.Font.Bold = true;
|
||||||
|
sl.SetRowStyle(startTitleRow, style);
|
||||||
|
//set it height
|
||||||
|
sl.SetRowHeight(startTitleRow, startTitleRow, 25);
|
||||||
|
// add the title first
|
||||||
|
sl.SetCellValue(row, col++, "Stafflink ID");
|
||||||
|
sl.SetCellValue(row, col++, "Name");
|
||||||
|
sl.SetCellValue(row, col++, "Role");
|
||||||
|
sl.SetCellValue(row, col++, "Validation Point");
|
||||||
|
sl.SetCellValue(row, col++, "Active");
|
||||||
|
|
||||||
|
sl.FreezePanes(row,0); //frozen the row.
|
||||||
|
//wrap text on is concession Expiry
|
||||||
|
style = sl.CreateStyle();
|
||||||
|
style.SetWrapText(true);
|
||||||
|
sl.SetColumnStyle(4, style);
|
||||||
|
|
||||||
|
//format date
|
||||||
|
|
||||||
|
style = sl.CreateStyle();
|
||||||
|
style.FormatCode = "dd/MM/yyyy HH:MM";
|
||||||
|
sl.SetColumnStyle(1, style);
|
||||||
|
//make column width
|
||||||
|
sl.SetColumnWidth(1, 20);
|
||||||
|
sl.SetColumnWidth(2, 50);
|
||||||
|
sl.SetColumnWidth(3, 20);
|
||||||
|
sl.SetColumnWidth(4, 30);
|
||||||
|
sl.SetColumnWidth(5, 40);
|
||||||
|
/*
|
||||||
|
public enum AdminRole
|
||||||
|
{
|
||||||
|
Normal = 1,
|
||||||
|
Admin = 2
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
int startRowFrom = startTitleRow + 1;
|
||||||
|
var list = await _context.AdminUsers.ToListAsync();
|
||||||
|
for (int i = 0; i < list.Count; i++)
|
||||||
|
{
|
||||||
|
col = 1;
|
||||||
|
item = list[i];
|
||||||
|
row = i + startRowFrom;
|
||||||
|
sl.SetCellValue(row, col++, item.StafflinkNo);
|
||||||
|
sl.SetCellValue(row, col++, item.Name);
|
||||||
|
sl.SetCellValue(row, col++, (int) item.RoleType == 1 ? "Normal": "Admin");
|
||||||
|
sl.SetCellValue(row, col++, GetVPDesc(item.ValidationPointID) );
|
||||||
|
sl.SetCellValue(row, col++, item.Active ? "Yes" : "No");
|
||||||
|
|
||||||
|
}
|
||||||
|
byte[] array;
|
||||||
|
// sl.SaveAs("C:\\Temp\\Report\\ConcessionValidationDate" + DateTime.Now.ToString("yyyyMMddHHmm") + ".xlsx");
|
||||||
|
using (MemoryStream ws = new MemoryStream())
|
||||||
|
{
|
||||||
|
sl.SaveAs(ws);
|
||||||
|
array = ws.ToArray();
|
||||||
|
/*
|
||||||
|
using (FileStream fs = new FileStream("c:\\temp\\Report\\conReport.xlsx",FileMode.Create,FileAccess.Write))
|
||||||
|
{
|
||||||
|
ws.WriteTo(fs);
|
||||||
|
fs.Close();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
ws.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new FileContent
|
||||||
|
{
|
||||||
|
Content = array,
|
||||||
|
FileName = "UserReport" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm") + ".xlsx",
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return new ResultModel<FileContent>
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statusCode
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
using CarParkValidationAPI.Datas;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using DocumentFormat.OpenXml.VariantTypes;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Repository
|
||||||
|
{
|
||||||
|
public class ValidationPointFakeRepository : IValidationPoint
|
||||||
|
{
|
||||||
|
private DataContext _context;
|
||||||
|
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
private string _currentUser = "";
|
||||||
|
private List<ValidationPointDto> _list = new List<ValidationPointDto>();
|
||||||
|
|
||||||
|
public ValidationPointFakeRepository(
|
||||||
|
DataContext context,
|
||||||
|
|
||||||
|
IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
}
|
||||||
|
public void SetCurrentUser(string username)
|
||||||
|
{
|
||||||
|
_currentUser = username;
|
||||||
|
}
|
||||||
|
private ValidationPointDto FillValidationDto(ValidationPoint item)
|
||||||
|
{
|
||||||
|
ValidationPointDto dto = new ValidationPointDto();
|
||||||
|
dto.Active = item.Active;
|
||||||
|
dto.Description = item.Description;
|
||||||
|
dto.Display = item.DisplayName;
|
||||||
|
dto.Id = item.ValidationPointID;
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValidationPoint FillValidationModel(ValidationPointDto item, ValidationPoint model) {
|
||||||
|
|
||||||
|
model.Active = item.Active;
|
||||||
|
model.Description = item.Description;
|
||||||
|
model.DisplayName = item.Display;
|
||||||
|
model.ValidationPointID = item.Id;
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<List<ValidationPointDto>>> LoadValidationPointAsync(bool onlyActive)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
var it = await _context.Validations.AsQueryable().ToListAsync();
|
||||||
|
*/
|
||||||
|
|
||||||
|
ValidationPointDto dto;
|
||||||
|
ValidationPoint val;
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
val = new ValidationPoint()
|
||||||
|
{
|
||||||
|
ValidationPointID = i,
|
||||||
|
Description = $"Validation {i}",
|
||||||
|
DisplayName = $"Display {i}",
|
||||||
|
Active = true,
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
dto = FillValidationDto(val);
|
||||||
|
_list.Add(dto);
|
||||||
|
}
|
||||||
|
//var it = await Task.Run(() => _list);
|
||||||
|
|
||||||
|
return new ResultModel<List<ValidationPointDto>>()
|
||||||
|
{
|
||||||
|
Data = _list,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<ValidationPointDto>> LoadValidationPointByIdAsync(int id)
|
||||||
|
{
|
||||||
|
ValidationPoint result = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ValidationPointDto dto;
|
||||||
|
result = await _context.Validations.FindAsync(id);
|
||||||
|
dto = FillValidationDto(result);
|
||||||
|
//result = _list.Find(x => x.Id == id);
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
return new ResultModel<ValidationPointDto>()
|
||||||
|
{
|
||||||
|
Data = dto,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<int>> SaveValidationPointAsync(ValidationPointDto item)
|
||||||
|
{
|
||||||
|
int result = default(int);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ValidationPoint model;
|
||||||
|
if (item.Id > 0)
|
||||||
|
{
|
||||||
|
model = await _context.Validations.FindAsync(item.Id);
|
||||||
|
model = FillValidationModel(item, model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
result = item.Id;
|
||||||
|
}
|
||||||
|
else //new record
|
||||||
|
{
|
||||||
|
model = new ValidationPoint();
|
||||||
|
model = FillValidationModel(item, model);
|
||||||
|
_context.Validations.Add(model);
|
||||||
|
var id = await _context.SaveChangesAsync();
|
||||||
|
result = id;
|
||||||
|
item.Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
ConcessionTypeDA dataAccess = new ConcessionTypeDA();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = await dataAccess.InsertConcessionTypeAsync(item);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<bool>> DeleteValidationPointAsync(int id)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
ValidationPoint model;
|
||||||
|
if (id > 0)
|
||||||
|
{
|
||||||
|
model = await _context.Validations.FindAsync(id);
|
||||||
|
model.Active = false;
|
||||||
|
//_context.Validations.Remove(model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
return new ResultModel<bool>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<Dictionary<int, LookupCodeDto>>> GetValidationPointDicAsync()
|
||||||
|
{
|
||||||
|
Dictionary<int, LookupCodeDto> resultList = new();
|
||||||
|
return new ResultModel<Dictionary<int, LookupCodeDto>>()
|
||||||
|
{
|
||||||
|
Data = resultList,
|
||||||
|
StatusCode = 1,
|
||||||
|
Message = ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
using CarParkValidationAPI.Datas;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI.Repository
|
||||||
|
{
|
||||||
|
public class ValidationPointRepository : IValidationPoint
|
||||||
|
{
|
||||||
|
private DataContext _context;
|
||||||
|
|
||||||
|
private readonly AppSettings _appSettings;
|
||||||
|
private string _currentUser = "";
|
||||||
|
private List<ValidationPointDto> _list = new List<ValidationPointDto>();
|
||||||
|
|
||||||
|
public ValidationPointRepository(
|
||||||
|
DataContext context,
|
||||||
|
|
||||||
|
IOptions<AppSettings> appSettings)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_appSettings = appSettings.Value;
|
||||||
|
}
|
||||||
|
public void SetCurrentUser(string username)
|
||||||
|
{
|
||||||
|
_currentUser = username;
|
||||||
|
}
|
||||||
|
private ValidationPointDto FillValidationDto(ValidationPoint item)
|
||||||
|
{
|
||||||
|
ValidationPointDto dto = new ValidationPointDto();
|
||||||
|
dto.Active = item.Active;
|
||||||
|
dto.Description = item.Description;
|
||||||
|
dto.Display = item.DisplayName;
|
||||||
|
dto.Id = item.ValidationPointID;
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValidationPoint FillValidationModel(ValidationPointDto item, ValidationPoint model) {
|
||||||
|
|
||||||
|
model.Active = item.Active;
|
||||||
|
model.Description = item.Description.Trim();
|
||||||
|
if (!string.IsNullOrEmpty(item.Display))
|
||||||
|
model.DisplayName = item.Display.Trim();
|
||||||
|
if (item.Id > 0)
|
||||||
|
model.ValidationPointID = item.Id;
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<List<ValidationPointDto>>> LoadValidationPointAsync(bool onlyActive)
|
||||||
|
{
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var it = await _context.Validations.ToListAsync();
|
||||||
|
|
||||||
|
ValidationPointDto dto;
|
||||||
|
for (int i = 0; i < it.Count; i++)
|
||||||
|
{
|
||||||
|
dto = FillValidationDto(it[i]);
|
||||||
|
_list.Add(dto);
|
||||||
|
}
|
||||||
|
_list.Sort((x, y) => x.Description.CompareTo(y.Description));
|
||||||
|
statuscode = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
return new ResultModel<List<ValidationPointDto>>()
|
||||||
|
{
|
||||||
|
Data = _list,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<ValidationPointDto>> LoadValidationPointByIdAsync(int id)
|
||||||
|
{
|
||||||
|
ValidationPoint result = null;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
ValidationPointDto dto = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = await _context.Validations.FindAsync(id);
|
||||||
|
dto = FillValidationDto(result);
|
||||||
|
//result = _list.Find(x => x.Id == id);
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
}
|
||||||
|
return new ResultModel<ValidationPointDto>()
|
||||||
|
{
|
||||||
|
Data = dto,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public async Task<ResultModel<int>> SaveValidationPointAsync(ValidationPointDto item)
|
||||||
|
{
|
||||||
|
int result = default(int);
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ValidationPoint model;
|
||||||
|
if (item.Id > 0)
|
||||||
|
{
|
||||||
|
model = await _context.Validations.FindAsync(item.Id);
|
||||||
|
model = FillValidationModel(item, model);
|
||||||
|
model.LastModified = DateTime.Now;
|
||||||
|
model.LastModifiedId = _currentUser;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
result = item.Id;
|
||||||
|
}
|
||||||
|
else //new record
|
||||||
|
{
|
||||||
|
model = new ValidationPoint();
|
||||||
|
model.LastModified = DateTime.Now;
|
||||||
|
model.LastModifiedId = _currentUser;
|
||||||
|
model = FillValidationModel(item, model);
|
||||||
|
_context.Validations.Add(model);
|
||||||
|
var id = await _context.SaveChangesAsync();
|
||||||
|
result = model.ValidationPointID;
|
||||||
|
|
||||||
|
}
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
}
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
return new ResultModel<int>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<bool>> DeleteValidationPointAsync(int id)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
int statuscode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ValidationPoint model;
|
||||||
|
if (id > 0)
|
||||||
|
{
|
||||||
|
model = await _context.Validations.FindAsync(id);
|
||||||
|
model.Active = false;
|
||||||
|
//_context.Validations.Remove(model);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
statuscode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statuscode = 0;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
//var dto = await Task.Run(() => result);
|
||||||
|
return new ResultModel<bool>()
|
||||||
|
{
|
||||||
|
Data = result,
|
||||||
|
StatusCode = statuscode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ResultModel<Dictionary<int, LookupCodeDto>>> GetValidationPointDicAsync()
|
||||||
|
{
|
||||||
|
Dictionary<int, LookupCodeDto> resultList = new();
|
||||||
|
|
||||||
|
int statusCode = 0;
|
||||||
|
string error = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
resultList = await _context.Validations.Where(x => x.Active == true)
|
||||||
|
.Select(item => new LookupCodeDto { Id = item.ValidationPointID, Description = item.Description ?? "" })
|
||||||
|
.ToDictionaryAsync(x => x.Id);
|
||||||
|
|
||||||
|
|
||||||
|
statusCode = 1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error = ex.ToString();
|
||||||
|
statusCode = 0;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
return new ResultModel<Dictionary<int, LookupCodeDto>>()
|
||||||
|
{
|
||||||
|
Data = resultList,
|
||||||
|
StatusCode = statusCode,
|
||||||
|
Message = error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+135
@@ -0,0 +1,135 @@
|
|||||||
|
using CarParkValidationAPI.Authorization;
|
||||||
|
using CarParkValidationAPI.Datas;
|
||||||
|
using CarParkValidationAPI.Entities;
|
||||||
|
using CarParkValidationAPI.Helpers;
|
||||||
|
using CarParkValidationAPI.Interface;
|
||||||
|
using CarParkValidationAPI.Models;
|
||||||
|
using CarParkValidationAPI.Repository;
|
||||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
|
||||||
|
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CarParkValidationAPI
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public Startup(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConfiguration Configuration { get; }
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddControllers();
|
||||||
|
//** security
|
||||||
|
var appSettingsSection = Configuration.GetSection("AppSettings");
|
||||||
|
services.Configure<AppSettings>(appSettingsSection);
|
||||||
|
|
||||||
|
var appSettings = appSettingsSection.Get<AppSettings>();
|
||||||
|
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
|
||||||
|
//***
|
||||||
|
services.AddDbContext<DataContext>();
|
||||||
|
services.AddCors();
|
||||||
|
//***
|
||||||
|
services.AddAuthentication(x =>
|
||||||
|
{
|
||||||
|
|
||||||
|
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
})
|
||||||
|
.AddJwtBearer(x =>
|
||||||
|
{
|
||||||
|
x.RequireHttpsMetadata = false;
|
||||||
|
x.SaveToken = true;
|
||||||
|
x.TokenValidationParameters = new TokenValidationParameters
|
||||||
|
{
|
||||||
|
ValidateIssuerSigningKey = true,
|
||||||
|
IssuerSigningKey = new SymmetricSecurityKey(key),
|
||||||
|
ValidateIssuer = false,
|
||||||
|
ValidateAudience = false
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// services.AddAutoMapper(typeof(Startup));
|
||||||
|
//**
|
||||||
|
//publish need to take comment out
|
||||||
|
|
||||||
|
services.AddSwaggerGen();
|
||||||
|
|
||||||
|
/*
|
||||||
|
services.AddSwaggerGen(option =>
|
||||||
|
{
|
||||||
|
option.UseAllOfForInheritance();
|
||||||
|
option.UseAllOfToExtendReferenceSchemas();
|
||||||
|
option.IgnoreObsoleteActions();
|
||||||
|
option.IgnoreObsoleteProperties();
|
||||||
|
option.ResolveConflictingActions(api => api.First());
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
services.AddScoped<IJwtUtils, JwtUtils>();
|
||||||
|
//services.AddScoped<IUserService, UserFakeRepository>();
|
||||||
|
services.AddScoped<IUserService, UserRepository>();
|
||||||
|
services.AddScoped<IConcessionType, ConcessionTypeRepository>();
|
||||||
|
services.AddScoped<IValidationPoint, ValidationPointRepository>();
|
||||||
|
services.AddScoped<IAdminUser, AdminUserRepository>();
|
||||||
|
services.AddScoped<IConcessionValidation, ConcessionValidationRepository>();
|
||||||
|
services.AddScoped<ILookupCode, LookupCodeRepository>();
|
||||||
|
services.AddScoped(typeof(ConcessionValidationReportRepository));
|
||||||
|
services.AddHttpContextAccessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext context)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// global cors policy
|
||||||
|
app.UseCors(x => x
|
||||||
|
.SetIsOriginAllowed(origin => true)
|
||||||
|
.AllowAnyMethod()
|
||||||
|
.AllowAnyHeader()
|
||||||
|
.WithExposedHeaders("Content-Disposition")
|
||||||
|
|
||||||
|
.AllowCredentials());
|
||||||
|
app.UseMiddleware<JwtMiddleware>();
|
||||||
|
app.UseMiddleware<ErrorHandlerMiddleware>(); // use this exception
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
app.UseRouting();
|
||||||
|
app.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapControllers();
|
||||||
|
|
||||||
|
});
|
||||||
|
app.UseAuthentication();
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
"SQLConnectionString": "Server=NEPHICT-040931L;Initial Catalog=CarParkValidation;Persist Security Info=False;User ID=bids_admin;Password=Password4BI;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;",
|
||||||
|
user id=bids_admin;password=Password4BI;
|
||||||
|
Server=tcp:10.60.207.82,1433;
|
||||||
|
*/
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"AppSettings": {
|
||||||
|
"Secret": "Nepean Blue Mountain Super Secret SIGN AND VERIFY JWT TOKENS, BEARER TOKEN USE WHEN CALLING THIS API.",
|
||||||
|
"SQLConnectionString": "Server=NEPHMDB-SQL007;Initial Catalog=CarParkValidation;Persist Security Info=False;User ID=bids_admin;Password=Password4BI;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;",
|
||||||
|
"LDAPPath": "",
|
||||||
|
"LDAPUser": "S",
|
||||||
|
"LDAPPassword": "",
|
||||||
|
"ADTimeOut": "30",
|
||||||
|
"LoginWebAPI": "http://NEPHMDB-SQL007/CommonWebApiAD/api/AD"
|
||||||
|
|
||||||
|
},
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"OLDLoginWebAPI": "http://virtapp-mdb048/CommonAPI/api/AD/",
|
||||||
|
"LADP": "http://NEPHMDB-SQL007/CommonWebApiAD/api/AD/",
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"SQLConnectionString": "Server=NEPHMDB-SQL007;Initial Catalog=CarParkValidation;Persist Security Info=False;User ID=bids_admin;Password=Password4BI;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;",
|
||||||
|
"SQLConnectionStringold": "Server=tcp:10.60.207.82,1433;Initial Catalog=CarParkValidation;Persist Security Info=False;User ID=bids_admin;Password=Password4BI;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;"
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<location path="." inheritInChildApplications="false">
|
||||||
|
<system.webServer>
|
||||||
|
<handlers>
|
||||||
|
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
|
||||||
|
</handlers>
|
||||||
|
<aspNetCore processPath="bin\Debug\net5.0\CarParkValidationAPI.exe" arguments="" stdoutLogEnabled="false" hostingModel="InProcess">
|
||||||
|
<environmentVariables>
|
||||||
|
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
|
||||||
|
</environmentVariables>
|
||||||
|
</aspNetCore>
|
||||||
|
</system.webServer>
|
||||||
|
</location>
|
||||||
|
</configuration>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Editor configuration, see https://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.ts]
|
||||||
|
quote_type = single
|
||||||
|
ij_typescript_use_double_quotes = false
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
max_line_length = off
|
||||||
|
trim_trailing_whitespace = false
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
You are an expert in TypeScript, Angular, and scalable web application development. You write functional, maintainable, performant, and accessible code following Angular and TypeScript best practices.
|
||||||
|
|
||||||
|
## TypeScript Best Practices
|
||||||
|
|
||||||
|
- Use strict type checking
|
||||||
|
- Prefer type inference when the type is obvious
|
||||||
|
- Avoid the `any` type; use `unknown` when type is uncertain
|
||||||
|
|
||||||
|
## Angular Best Practices
|
||||||
|
|
||||||
|
- Always use standalone components over NgModules
|
||||||
|
- Must NOT set `standalone: true` inside Angular decorators. It's the default in Angular v20+.
|
||||||
|
- Do NOT set `changeDetection: ChangeDetectionStrategy.OnPush` explicitly. `OnPush` is the default in Angular v22+.
|
||||||
|
- Use signals for state management
|
||||||
|
- Implement lazy loading for feature routes
|
||||||
|
- Do NOT use the `@HostBinding` and `@HostListener` decorators. Put host bindings inside the `host` object of the `@Component` or `@Directive` decorator instead
|
||||||
|
- Use `NgOptimizedImage` for all static images.
|
||||||
|
- `NgOptimizedImage` does not work for inline base64 images.
|
||||||
|
|
||||||
|
## Accessibility Requirements
|
||||||
|
|
||||||
|
- It MUST pass all AXE checks.
|
||||||
|
- It MUST follow all WCAG AA minimums, including focus management, color contrast, and ARIA attributes.
|
||||||
|
|
||||||
|
### Components
|
||||||
|
|
||||||
|
- Keep components small and focused on a single responsibility
|
||||||
|
- Use `input()` and `output()` functions instead of decorators
|
||||||
|
- Use `model()` for two-way bound properties with `[(prop)]` syntax instead of pairing `input()` with `output()`
|
||||||
|
- Use `computed()` for derived state
|
||||||
|
- Use `linkedSignal()` for state derived from multiple reactive sources that must stay synchronized
|
||||||
|
- Prefer inline templates for small components
|
||||||
|
- Prefer Signal Forms (`@angular/forms/signals`) for new forms. They are stable in Angular v22+ and provide signal-based state, type-safe field access, and schema-based validation
|
||||||
|
- When not using Signal Forms, prefer Reactive forms instead of Template-driven ones
|
||||||
|
- Do NOT use `ngClass`, use `class` bindings instead
|
||||||
|
- Do NOT use `ngStyle`, use `style` bindings instead
|
||||||
|
- When using external templates/styles, use paths relative to the component TS file.
|
||||||
|
|
||||||
|
## State Management
|
||||||
|
|
||||||
|
- Use signals for local component state
|
||||||
|
- Use `computed()` for derived state
|
||||||
|
- Keep state transformations pure and predictable
|
||||||
|
- Do NOT use `mutate` on signals, use `update` or `set` instead
|
||||||
|
|
||||||
|
## Templates
|
||||||
|
|
||||||
|
- Keep templates simple and avoid complex logic
|
||||||
|
- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch`
|
||||||
|
- Use the async pipe to handle observables
|
||||||
|
- Do not assume globals like (`new Date()`) are available.
|
||||||
|
|
||||||
|
## Services
|
||||||
|
|
||||||
|
- Design services around a single responsibility
|
||||||
|
- Use the `providedIn: 'root'` option for singleton services
|
||||||
|
- Prefer the `@Service` decorator over `@Injectable({providedIn: 'root'})` for new singleton services (Angular v22+)
|
||||||
|
- Use the `inject()` function instead of constructor injection
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"angular-cli": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["-y", "@angular/cli", "mcp"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ui": {
|
||||||
|
"showLineNumbers": false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
|
||||||
|
|
||||||
|
# Compiled output
|
||||||
|
/dist
|
||||||
|
/tmp
|
||||||
|
/out-tsc
|
||||||
|
/bazel-out
|
||||||
|
|
||||||
|
# Node
|
||||||
|
/node_modules
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
.idea/
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/mcp.json
|
||||||
|
.history/*
|
||||||
|
|
||||||
|
# Miscellaneous
|
||||||
|
/.angular/cache
|
||||||
|
.sass-cache/
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
__screenshots__/
|
||||||
|
|
||||||
|
# System files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"plugins": {
|
||||||
|
"@tailwindcss/postcss": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 100,
|
||||||
|
"singleQuote": true,
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "*.html",
|
||||||
|
"options": {
|
||||||
|
"parser": "angular"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
|
||||||
|
"recommendations": ["angular.ng-template"]
|
||||||
|
}
|
||||||
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "ng serve",
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "npm: start",
|
||||||
|
"url": "http://localhost:4200/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ng test",
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "npm: test",
|
||||||
|
"url": "http://localhost:9876/debug.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+42
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "start",
|
||||||
|
"isBackground": true,
|
||||||
|
"problemMatcher": {
|
||||||
|
"owner": "typescript",
|
||||||
|
"pattern": "$tsc",
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": {
|
||||||
|
"regexp": "Changes detected"
|
||||||
|
},
|
||||||
|
"endsPattern": {
|
||||||
|
"regexp": "bundle generation (complete|failed)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "test",
|
||||||
|
"isBackground": true,
|
||||||
|
"problemMatcher": {
|
||||||
|
"owner": "typescript",
|
||||||
|
"pattern": "$tsc",
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": {
|
||||||
|
"regexp": "Changes detected"
|
||||||
|
},
|
||||||
|
"endsPattern": {
|
||||||
|
"regexp": "bundle generation (complete|failed)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
# Carparkvalidation
|
||||||
|
|
||||||
|
https://www.youtube.com/watch?v=KpNzBU4fNdU
|
||||||
|
|
||||||
|
# install AI google
|
||||||
|
npm install -g @google/gemini-cli
|
||||||
|
|
||||||
|
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 22.1.6.
|
||||||
|
|
||||||
|
## Development server
|
||||||
|
|
||||||
|
To start a local development server, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng serve
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
|
||||||
|
|
||||||
|
## Code scaffolding
|
||||||
|
|
||||||
|
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng generate component component-name
|
||||||
|
```
|
||||||
|
|
||||||
|
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng generate --help
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
To build the project run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng build
|
||||||
|
```
|
||||||
|
|
||||||
|
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running end-to-end tests
|
||||||
|
|
||||||
|
For end-to-end (e2e) testing, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng e2e
|
||||||
|
```
|
||||||
|
|
||||||
|
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"cli": {
|
||||||
|
"packageManager": "npm"
|
||||||
|
},
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"carparkvalidation": {
|
||||||
|
"projectType": "application",
|
||||||
|
"schematics": {},
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"prefix": "app",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular/build:application",
|
||||||
|
"options": {
|
||||||
|
"browser": "src/main.ts",
|
||||||
|
"tsConfig": "tsconfig.app.json",
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"glob": "**/*",
|
||||||
|
"input": "public"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"src/styles.css"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "500kB",
|
||||||
|
"maximumError": "1MB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "4kB",
|
||||||
|
"maximumError": "8kB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputHashing": "all"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"optimization": false,
|
||||||
|
"extractLicenses": false,
|
||||||
|
"sourceMap": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "production"
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular/build:dev-server",
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"buildTarget": "carparkvalidation:build:production"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"buildTarget": "carparkvalidation:build:development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "development"
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular/build:unit-test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+8582
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "carparkvalidation",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"start": "ng serve",
|
||||||
|
"build": "ng build",
|
||||||
|
"watch": "ng build --watch --configuration development",
|
||||||
|
"test": "ng test"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"packageManager": "npm@11.12.1",
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/common": "^22.1.0",
|
||||||
|
"@angular/compiler": "^22.1.0",
|
||||||
|
"@angular/core": "^22.1.0",
|
||||||
|
"@angular/forms": "^22.1.0",
|
||||||
|
"@angular/platform-browser": "^22.1.0",
|
||||||
|
"@angular/router": "^22.1.0",
|
||||||
|
"@google/generative-ai": "^0.24.1",
|
||||||
|
"@primeicons/angular": "^8.0.1",
|
||||||
|
"@primeuix/themes": "^3.0.1",
|
||||||
|
"moment": "^2.31.0",
|
||||||
|
"primeng": "^22.1.1",
|
||||||
|
"rxjs": "~7.8.0",
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@angular/build": "^22.1.6",
|
||||||
|
"@angular/cli": "^22.1.6",
|
||||||
|
"@angular/compiler-cli": "^22.1.0",
|
||||||
|
"@tailwindcss/postcss": "^4.1.12",
|
||||||
|
"jsdom": "^28.0.0",
|
||||||
|
"postcss": "^8.5.3",
|
||||||
|
"prettier": "^3.8.1",
|
||||||
|
"tailwindcss": "^4.1.12",
|
||||||
|
"typescript": "~6.0.2",
|
||||||
|
"vitest": "^4.0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"baseUrl4": "http://localhost:5100",
|
||||||
|
"baseUrl": "http://nephmdb-sql007/CarParkValidationAPI",
|
||||||
|
"loginUrl": "api/login",
|
||||||
|
"updatePersonUrl": "api/updatePerson",
|
||||||
|
"getAllUrl": "api/v1/Users/GetAllUsers",
|
||||||
|
"authenticateUrl": "api/v1/Users/Authenticate",
|
||||||
|
"validationPoint": "api/v1/ValidationPoint",
|
||||||
|
"adminEmail": "NBMLHD-parking@health.nsw.gov.au"
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
@@ -0,0 +1,12 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-form-field {
|
||||||
|
font-size: 14px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
td.mat-column-edit, .mat-column-delete {
|
||||||
|
width: 35px;
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
<div class="edit-content ml-6">
|
||||||
|
<h3>Application Administrators</h3>
|
||||||
|
|
||||||
|
<a class="p-ripple p-button p-component flex justify-self-end mb-2" [routerLink]='["/adminuser", -1]' [queryParams]="{returnUrl:'/home/adminuser'}">
|
||||||
|
|
||||||
|
Add User
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="mb-3 flex justify-end">
|
||||||
|
<p-iconfield iconPosition="left">
|
||||||
|
<p-inputicon>
|
||||||
|
<svg data-p-icon="search" ></svg>
|
||||||
|
</p-inputicon>
|
||||||
|
<input pInputText pSize="small" type="text" (input)="dt.filterGlobal($event.target.value, 'contains')" placeholder="Keyword Search" />
|
||||||
|
</p-iconfield>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p-table #dt [value]="dataSource()" rowHover="true" dataKey="id"
|
||||||
|
[rows]="25" [rowsPerPageOptions]="[ 25, 50,100]" [paginator]="true"
|
||||||
|
[globalFilterFields]="['stafflinkNo', 'name', 'roleType', 'validationPoint']" >
|
||||||
|
|
||||||
|
<ng-template #header>
|
||||||
|
<tr>
|
||||||
|
<th>Stafflink Id</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Role</th>
|
||||||
|
<th>Validation Point</th>
|
||||||
|
<th>Active</th>
|
||||||
|
<th>Edit</th>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template #body let-item>
|
||||||
|
<tr>
|
||||||
|
<td>{{ item.stafflinkNo }}</td>
|
||||||
|
<td>{{ item.name }}</td>
|
||||||
|
<td>{{ item.roleType }}</td>
|
||||||
|
<td>{{ item.validationPoint }}</td>
|
||||||
|
<td>
|
||||||
|
@if(item.active == true) {
|
||||||
|
<svg data-p-icon="check" color="green"></svg>
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
<svg data-p-icon="times" color="red"></svg>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button pButton (click)="showEdit(item)">
|
||||||
|
<svg data-p-icon="pencil"></svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
import { Component, OnInit, signal, OnDestroy } from '@angular/core';
|
||||||
|
|
||||||
|
import { AdminUserView } from '../models';
|
||||||
|
|
||||||
|
|
||||||
|
import { take } from 'rxjs/operators';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { Router, RouterModule } from '@angular/router';
|
||||||
|
import { AdminUserService } from './adminuser.service';
|
||||||
|
import { MessageService } from 'primeng/api';
|
||||||
|
import { TableModule } from 'primeng/table';
|
||||||
|
import { Check } from '@primeicons/angular/check';
|
||||||
|
import { Times } from '@primeicons/angular/times';
|
||||||
|
import { Pencil } from '@primeicons/angular/pencil';
|
||||||
|
import { Search } from '@primeicons/angular/search';
|
||||||
|
import { IconFieldModule } from 'primeng/iconfield';
|
||||||
|
import { InputIconModule } from 'primeng/inputicon';
|
||||||
|
import { InputTextModule } from 'primeng/inputtext';
|
||||||
|
@Component({
|
||||||
|
selector: 'adminuser-list',
|
||||||
|
templateUrl: './adminuser.component.html',
|
||||||
|
imports: [TableModule, RouterModule, Times, Check, Pencil, InputIconModule, IconFieldModule, Search, InputTextModule],
|
||||||
|
styleUrls: ['./adminuser.component.css']
|
||||||
|
})
|
||||||
|
export class AdminUserComponent implements OnInit, OnDestroy {
|
||||||
|
dataSource = signal<AdminUserView[]>([]);
|
||||||
|
private subscription: Subscription = new Subscription();
|
||||||
|
displayedColumns: string[] = ['stafflinkNo', 'name', 'roleType', 'validationPoint', 'active', 'edit'];
|
||||||
|
msg = "[AdminUser component]";
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
private store: Store<appValidationState>
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private adminUserService: AdminUserService,
|
||||||
|
private router: Router,
|
||||||
|
private messageService: MessageService,
|
||||||
|
) {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
//KeyboardEvent
|
||||||
|
applyFilter(event: Event) {
|
||||||
|
const filterValue = (event.target as HTMLInputElement).value;
|
||||||
|
//this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.subscription.add(
|
||||||
|
this.adminUserService.loadAdminusers().subscribe(result => {
|
||||||
|
// console.log(this.msg + "onInit load Data", result);
|
||||||
|
this.dataSource.set(result.data);
|
||||||
|
}, error => {
|
||||||
|
|
||||||
|
console.log("error ", error);
|
||||||
|
})
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
this.store.dispatch(validationActions.LoadValidationpoints());
|
||||||
|
this.store.pipe(select(validationSelector.getAllValidations)).subscribe(result => this.dataSource.data = result);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
showEdit(item: AdminUserView) {
|
||||||
|
console.log(this.msg + "on row click", item);
|
||||||
|
this.router.navigate(['/adminuser/' + item.id], { queryParams: { returnUrl: '/adminuser' } });
|
||||||
|
}
|
||||||
|
deleteItem(id: number): void {
|
||||||
|
|
||||||
|
this.adminUserService.deleteAdminuser(id)
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe({
|
||||||
|
next: result => {
|
||||||
|
console.log(this.msg + " deleteItem success", result);
|
||||||
|
let data = this.dataSource();
|
||||||
|
let index: number = data.findIndex(d => d.id === id);
|
||||||
|
console.log(this.msg + "delete from datasource");
|
||||||
|
data.splice(index, 1)
|
||||||
|
this.dataSource.set(data);
|
||||||
|
},
|
||||||
|
error: e => console.error('error loading', e)
|
||||||
|
});
|
||||||
|
console.log(this.msg + "click button to delete");
|
||||||
|
|
||||||
|
}
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-form-field {
|
||||||
|
font-size: 14px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
td.mat-column-edit, .mat-column-delete {
|
||||||
|
width: 35px;
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<div class="edit-content">
|
||||||
|
<div class="title">
|
||||||
|
{{getEditText()}}
|
||||||
|
</div>
|
||||||
|
<form [formGroup]="adminuserForm" (ngSubmit)="onSubmit()" class="ml-10 flex flex-col gap-2">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div>
|
||||||
|
<label class="flex w-full">Stafflink Number<strong class="app-require">*</strong></label>
|
||||||
|
<input pInputText formControlName="stafflinkNo" (blur)="searchUser()" maxlength="10" name="stafflinkno"
|
||||||
|
placeholder="Stafflink Number" #mystaffid>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="flex w-full">Name</label>
|
||||||
|
<input pInputText formControlName="name" maxlength="100" name="name" placeholder="Name">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="flex w-full">Role<strong class="app-require">*</strong></label>
|
||||||
|
<p-select formControlName="roleType" [options]="Roles()"
|
||||||
|
optionLabel="description" optionValue="categoryId"
|
||||||
|
>
|
||||||
|
|
||||||
|
</p-select>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<label class="flex w-full">Validation Point<strong class="app-require">*</strong></label>
|
||||||
|
<p-select formControlName="validationPointId" [options]="validationPoints()"
|
||||||
|
optionLabel="description" optionValue="id"
|
||||||
|
|
||||||
|
>
|
||||||
|
</p-select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="acheckbox" class="mr-2 text-sm">Active</label>
|
||||||
|
<p-checkbox formControlName="active" [binary]="true" inputId="acheckbox" size="small" />
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-content-end mt-2">
|
||||||
|
<button type="submit" pButton class="mr-2" [disabled]="isFieldsChange">Submit</button>
|
||||||
|
<button type="button" pButton="" (click)="goBack()">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<!--pre>{{ adminuserForm.value|json}}</pre-->
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
import { Component, inject, OnDestroy, OnInit, signal, ViewChild } from '@angular/core';
|
||||||
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
|
import { FormGroup, Validators, ReactiveFormsModule, FormBuilder, FormControl } from '@angular/forms';
|
||||||
|
import { Subject, pipe, Subscription, single } from 'rxjs';
|
||||||
|
|
||||||
|
import { AdminUser, Lookup, userRole } from '../models';
|
||||||
|
import { LookupService, Utils } from '../shares';
|
||||||
|
import { AdminUserService } from './adminuser.service';
|
||||||
|
import { MessageService } from 'primeng/api';
|
||||||
|
import { InputTextModule } from 'primeng/inputtext';
|
||||||
|
import { SelectModule } from 'primeng/select';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { CheckboxModule } from 'primeng/checkbox';
|
||||||
|
@Component({
|
||||||
|
templateUrl: 'adminuser.edit.component.html',
|
||||||
|
imports: [InputTextModule, ButtonModule, ReactiveFormsModule, SelectModule, CheckboxModule],
|
||||||
|
selector: 'adminuser-edit',
|
||||||
|
styleUrls: ['adminuser.edit.component.css']
|
||||||
|
})
|
||||||
|
export class AdminUserEditComponent implements OnInit, OnDestroy {
|
||||||
|
returnUrl = '';
|
||||||
|
loginUser = '';
|
||||||
|
_id = -1;
|
||||||
|
Roles = signal<Lookup[]>([]);
|
||||||
|
validationPoints = signal<Lookup[]>([]);
|
||||||
|
msg = "[adminUser Component] ";
|
||||||
|
//for focus input
|
||||||
|
// @ViewChild('mystaffid') mystaffNo!: MatInput;
|
||||||
|
isChange = true; // disable use false//true for not disable. make sure it true is disable button.
|
||||||
|
private subscription: Subscription = new Subscription();
|
||||||
|
subChanged$ = new Subject<boolean>();
|
||||||
|
private formBuilder = inject(FormBuilder);
|
||||||
|
private adminUserService = inject(AdminUserService);
|
||||||
|
private messageService = inject(MessageService);
|
||||||
|
private lookupService = inject(LookupService);
|
||||||
|
adminuserForm = this.formBuilder.group({
|
||||||
|
id: [0], //Validators.required
|
||||||
|
stafflinkNo: [''], //Validators.required
|
||||||
|
name: [''], //Validators.required
|
||||||
|
addedBy: [''], //Validators.required
|
||||||
|
addedOn: new FormControl<Date | null>(null), //Validators.required
|
||||||
|
active: [false], //Validators.required
|
||||||
|
roleType: [0, Validators.required],
|
||||||
|
validationPointId: [0, Validators.required]
|
||||||
|
});
|
||||||
|
constructor(
|
||||||
|
private router: Router, private route: ActivatedRoute,
|
||||||
|
) {
|
||||||
|
|
||||||
|
|
||||||
|
const roles = [];
|
||||||
|
let item: Lookup = { id: userRole.Admin, categoryId: userRole.Admin, description: 'Admin' };
|
||||||
|
roles.push(item);
|
||||||
|
item = { id: userRole.Normal, categoryId: userRole.Normal, description: 'Normal' };
|
||||||
|
roles.push(item);
|
||||||
|
this.Roles.set(roles);
|
||||||
|
|
||||||
|
}
|
||||||
|
loadData(id: number): void {
|
||||||
|
this.subscription.add(
|
||||||
|
this.lookupService.loadValidationPoint()
|
||||||
|
.subscribe({
|
||||||
|
next: x => {
|
||||||
|
this.validationPoints.set(x.data);
|
||||||
|
if (id > 0) {
|
||||||
|
this.subscription.add(
|
||||||
|
this.adminUserService.loadAdminuserById(id)
|
||||||
|
.subscribe({
|
||||||
|
next: x => this.assignValue(x.data),
|
||||||
|
error: e => console.error("error ", e.message)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: e => console.error("error ", e)
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/adminuser';
|
||||||
|
const id = Number(this.route.snapshot.paramMap.get('id'));
|
||||||
|
// now load thing up
|
||||||
|
const user = Utils.getCurrentUser();
|
||||||
|
// console.log(this.msg + "current login user ", user);
|
||||||
|
if (user.username === '')
|
||||||
|
alert("you are not login.");
|
||||||
|
else
|
||||||
|
this.loginUser = user.firstName;
|
||||||
|
this._id = id;
|
||||||
|
//console.log(this.msg + " " + id );
|
||||||
|
this.subscription.add(this.adminuserForm.valueChanges.subscribe(x => this.isChange = false));
|
||||||
|
this.subscription.add(this.subChanged$.subscribe(x => this.isChange = x));
|
||||||
|
this.loadData(id);
|
||||||
|
|
||||||
|
}
|
||||||
|
getEditText(): string {
|
||||||
|
if (this._id > 0)
|
||||||
|
return "Edit Admin User";
|
||||||
|
else
|
||||||
|
return "New Admin User";
|
||||||
|
}
|
||||||
|
// this for disable submit button
|
||||||
|
get isFieldsChange() {
|
||||||
|
const chan = this.isChange || !this.adminuserForm.valid; // this disable so need true valid = true not
|
||||||
|
//console.log(this.msg + 'is fields change', chan);
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
searchUser(): void {
|
||||||
|
const staffid = this.adminuserForm.controls["stafflinkNo"].value ?? '';
|
||||||
|
// console.log(this.msg + " the staffid is ", staffid);
|
||||||
|
if (staffid != '') {
|
||||||
|
//this.form.controls['your form control name'].value
|
||||||
|
this.adminUserService.getStaffLinkId(staffid).subscribe(
|
||||||
|
{
|
||||||
|
next: x => {
|
||||||
|
//console.log(this.msg + " this is stafflink no ", x);
|
||||||
|
// now get current user.
|
||||||
|
|
||||||
|
if (x.data) {
|
||||||
|
//this.error = true;
|
||||||
|
const fname = x.data.firstName + " " + x.data.lastName;
|
||||||
|
this.adminuserForm.patchValue({ name: fname, addedBy: this.loginUser });
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error', detail: "can not find stafflinkNo:" + staffid });
|
||||||
|
// this.adminuserForm.patchValue({name:x.data.firstName + " " + x.data.lastName
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: e => {
|
||||||
|
|
||||||
|
console.log("error ", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error', detail: "please enter staff link no" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assignValue(adminuser: AdminUser): void {
|
||||||
|
this.adminuserForm.patchValue({
|
||||||
|
id: adminuser.id,
|
||||||
|
stafflinkNo: adminuser.stafflinkNo,
|
||||||
|
name: adminuser.name,
|
||||||
|
addedBy: adminuser.addedBy,
|
||||||
|
addedOn: adminuser.addedOn,
|
||||||
|
active: adminuser.active,
|
||||||
|
roleType: adminuser.roleType,
|
||||||
|
validationPointId: adminuser.validationPointId
|
||||||
|
});
|
||||||
|
// disable use false//true for not disable.
|
||||||
|
this.subChanged$.next(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convenience getter for easy access in form fields
|
||||||
|
get f() { return this.adminuserForm.controls; }
|
||||||
|
|
||||||
|
onSubmit(): void {
|
||||||
|
// if form valid then go save
|
||||||
|
//make sure
|
||||||
|
const okToSave = this.adminuserForm.valid;
|
||||||
|
if (okToSave) {
|
||||||
|
let adminuserValue = this.adminuserForm.value;
|
||||||
|
|
||||||
|
let adminuser: AdminUser = {
|
||||||
|
id: adminuserValue.id ?? -1,
|
||||||
|
stafflinkNo: adminuserValue.stafflinkNo ?? '',
|
||||||
|
name: adminuserValue.name ?? '',
|
||||||
|
addedBy: adminuserValue.addedBy ?? '',
|
||||||
|
addedOn: new Date(),
|
||||||
|
active: adminuserValue.active ?? false,
|
||||||
|
roleType: adminuserValue.roleType ?? 0,
|
||||||
|
validationPointId: adminuserValue.validationPointId ?? 0,
|
||||||
|
};
|
||||||
|
this.subscription.add(
|
||||||
|
this.adminUserService.saveAdminuser(adminuser).subscribe(x => {
|
||||||
|
if (x.statusCode >= 1) {
|
||||||
|
this.messageService.add({ severity: 'success', summary: 'Success', detail: "Save is OK" });
|
||||||
|
this.router.navigate([this.returnUrl]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error', detail: "Fail to save" });
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
|
||||||
|
console.log("error ", error);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goBack(): void {
|
||||||
|
console.log("the return url", this.returnUrl);
|
||||||
|
this.router.navigate([this.returnUrl]);
|
||||||
|
}
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
|
||||||
|
import { Injectable, Inject } from '@angular/core';
|
||||||
|
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { AdminUser, AdminUserView, ResultModel,ConfigureUrl,User } from '../models';
|
||||||
|
import { AppSettingService } from '../shares';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class AdminUserService {
|
||||||
|
|
||||||
|
constructor(private http: HttpClient,
|
||||||
|
private appSetting :AppSettingService
|
||||||
|
) {}
|
||||||
|
loadAdminusers(): Observable<ResultModel<AdminUserView[]>> {
|
||||||
|
let config = { headers : { 'Content-Type': 'application/json' } };
|
||||||
|
//const baseUrl = ConfigureUrl.baseUrl + "/"+ ConfigureUrl.adminUserUrl;
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/"+ ConfigureUrl.adminUserUrl;
|
||||||
|
return this.http.get<ResultModel<AdminUserView[]>>(baseUrl);
|
||||||
|
}
|
||||||
|
getStaffLinkId(staffid:string) :Observable<ResultModel<User>>{
|
||||||
|
const userUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.userByStaffIdUrl;
|
||||||
|
let params = new HttpParams().set("stafflinkNo", ""+staffid);
|
||||||
|
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||||
|
let options = {
|
||||||
|
headers: headers,
|
||||||
|
params: params
|
||||||
|
};
|
||||||
|
return this.http.get<ResultModel<User>>(userUrl, options);
|
||||||
|
}
|
||||||
|
loadAdminuserById(id:number): Observable<ResultModel<AdminUser>> {
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/"+ ConfigureUrl.adminUserUrl;
|
||||||
|
let params = new HttpParams().set("id", ""+id);
|
||||||
|
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||||
|
let options = {
|
||||||
|
headers: headers,
|
||||||
|
params: params
|
||||||
|
};
|
||||||
|
//return this.http.get<AdminUser>(this.baseUrl + 'api/Adminuser/LoadAdminuserById',options);
|
||||||
|
return this.http.get<ResultModel<AdminUser>>(baseUrl + "/" + id);
|
||||||
|
}
|
||||||
|
saveAdminuser(jsData:AdminUser): Observable<ResultModel<number>> { //insert Adminuser
|
||||||
|
let config = { headers : { 'Content-Type': 'application/json' } };
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/"+ ConfigureUrl.adminUserUrl;
|
||||||
|
return this.http.post<ResultModel<number>>(baseUrl, jsData, config);
|
||||||
|
}
|
||||||
|
deleteAdminuser(id:number): Observable<ResultModel<number>>{
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/"+ ConfigureUrl.adminUserUrl;
|
||||||
|
let config = { headers : { 'Content-Type': 'application/json' } };
|
||||||
|
return this.http.delete<ResultModel<number>>(baseUrl + "/" + id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export * from './adminuser.component';
|
||||||
|
export * from './adminuser.edit.component';
|
||||||
|
export * from './adminuser.service';
|
||||||
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { ApplicationConfig, inject, provideAppInitializer, provideBrowserGlobalErrorListeners } from '@angular/core';
|
||||||
|
import { provideRouter } from '@angular/router';
|
||||||
|
import { routes } from './app.routes';
|
||||||
|
import { PrimeNG, providePrimeNG } from 'primeng/config';
|
||||||
|
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||||
|
import { provideHttpClient, withInterceptors, withXhr } from '@angular/common/http';
|
||||||
|
import { AppSettingService, ErrorInterceptor, initializeApp, JwtInterceptor } from './shares';
|
||||||
|
import MyPreset from './mytheme_aura';
|
||||||
|
|
||||||
|
export const appConfig: ApplicationConfig = {
|
||||||
|
providers: [
|
||||||
|
MessageService,
|
||||||
|
ConfirmationService,
|
||||||
|
provideAppInitializer(() => {
|
||||||
|
const primeNG = inject(PrimeNG);
|
||||||
|
const appSettingService = inject(AppSettingService);
|
||||||
|
const loadAppSetting = initializeApp();
|
||||||
|
|
||||||
|
// Return the promise chain so Angular blocks app loading until the request completes
|
||||||
|
return loadAppSetting().then((result) => {
|
||||||
|
// Read the setting directly from the populated service instance
|
||||||
|
const settings = appSettingService.appSetting;
|
||||||
|
console.log('Loaded app settings:', settings, result);
|
||||||
|
|
||||||
|
const licenseKey = settings?.primeNGLicense || '';
|
||||||
|
console.log("primeng license", licenseKey);
|
||||||
|
|
||||||
|
// Apply configuration to PrimeNG
|
||||||
|
primeNG.setConfig({
|
||||||
|
license: licenseKey,
|
||||||
|
theme: {
|
||||||
|
preset: MyPreset,
|
||||||
|
options: {
|
||||||
|
cssLayer: {
|
||||||
|
name: 'primeng',
|
||||||
|
order: 'theme, base, primeng'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
|
provideHttpClient(withXhr(), withInterceptors([JwtInterceptor, ErrorInterceptor])),
|
||||||
|
provideBrowserGlobalErrorListeners(),
|
||||||
|
provideRouter(routes)
|
||||||
|
]
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
@if (isAuth() == true) {
|
||||||
|
<app-nav-toolbar ></app-nav-toolbar>
|
||||||
|
}
|
||||||
|
<router-outlet />
|
||||||
|
<p-confirmdialog></p-confirmdialog>
|
||||||
|
<p-toast></p-toast>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { Routes } from '@angular/router';
|
||||||
|
import { AuthGuard } from './route-guard';
|
||||||
|
import { AdminUserComponent, AdminUserEditComponent } from './adminuser';
|
||||||
|
import { LoginComponent } from './login';
|
||||||
|
import { ConcessionTypeComponent, ConcessiontypeEditComponent } from './concessiontype';
|
||||||
|
import { ValidationPointComponent, ValidationpointEditComponent } from './validationPoint';
|
||||||
|
import { ConcessionValidationComponent, ConcessionValidationEditComponent } from './concessionValidation';
|
||||||
|
import { ConcessionvalidationReportComponent } from './concessionvalidationreport';
|
||||||
|
|
||||||
|
export const routes: Routes = [
|
||||||
|
{ path: 'login', component: LoginComponent },
|
||||||
|
{ path: 'adminuser', component: AdminUserComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' } },
|
||||||
|
|
||||||
|
{ path: 'adminuser/:id', component: AdminUserEditComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' } },
|
||||||
|
{ path: 'concessiontype', component: ConcessionTypeComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' } },
|
||||||
|
{ path: 'concessiontype/:id', component: ConcessiontypeEditComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' } },
|
||||||
|
|
||||||
|
{ path: 'validationpoint', component: ValidationPointComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' } },
|
||||||
|
{ path: 'validationpoint/:id', component: ValidationpointEditComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' } },
|
||||||
|
|
||||||
|
{ path: 'concessionvalidation', component: ConcessionValidationComponent, canActivate: [AuthGuard] },
|
||||||
|
{ path: 'concessionvalidation/:id', component: ConcessionValidationEditComponent, canActivate: [AuthGuard] },
|
||||||
|
|
||||||
|
{ path: 'app-concessionvalidation-report', component: ConcessionvalidationReportComponent, canActivate: [AuthGuard], data: { roleAllowed: 'Admin' } },
|
||||||
|
|
||||||
|
{ path: '', redirectTo: 'login', pathMatch: 'full' },
|
||||||
|
{ path: '**', redirectTo: 'login' },
|
||||||
|
];
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { Component, computed, inject, signal, viewChild } from '@angular/core';
|
||||||
|
import { RouterOutlet } from '@angular/router';
|
||||||
|
import { ConfirmDialogModule } from 'primeng/confirmdialog';
|
||||||
|
import { ToastModule } from 'primeng/toast';
|
||||||
|
import { NavToolarComponent } from './nav-toolbar/nav-toolbar.component';
|
||||||
|
import { AuthenticationService } from './user-services';
|
||||||
|
@Component({
|
||||||
|
imports: [RouterOutlet, ConfirmDialogModule, ToastModule, NavToolarComponent],
|
||||||
|
selector: 'app-root',
|
||||||
|
styleUrl: './app.css',
|
||||||
|
templateUrl: './app.html',
|
||||||
|
})
|
||||||
|
export class App {
|
||||||
|
authService = inject(AuthenticationService);
|
||||||
|
protected readonly title = signal('carparkvalidation');
|
||||||
|
isAuth = computed(() => this.authService.authChange().firstName != '');
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-form-field {
|
||||||
|
font-size: 14px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
td.mat-column-edit, .mat-column-delete {
|
||||||
|
width: 35px;
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
<div class="edit-content">
|
||||||
|
<h3>Concession Validation</h3>
|
||||||
|
@if (isAdmin) {
|
||||||
|
<div >
|
||||||
|
<div class="flex flex-row gap-2 w-full">
|
||||||
|
|
||||||
|
<label>Choose a from date</label>
|
||||||
|
<p-datepicker [(ngModel)]="fromDate" dateFormat="dd/mm/yy" />
|
||||||
|
|
||||||
|
|
||||||
|
<label>Choose a to date</label>
|
||||||
|
<p-datepicker [(ngModel)]="toDate" dateFormat="dd/mm/yy" />
|
||||||
|
|
||||||
|
|
||||||
|
<button pButton (click)="onLoad()" >
|
||||||
|
Load
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div class="addlink">
|
||||||
|
<a class="p-ripple p-button p-component flex justify-self-end mb-2" [routerLink]='["/concessionvalidation", 0]'
|
||||||
|
[queryParams]="{returnUrl:'/concessionvalidation'}"
|
||||||
|
(click)="setDate()">
|
||||||
|
|
||||||
|
Add Concession Validation
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<p-table [value]="dataSource()" rowHover="true" dataKey="id"
|
||||||
|
[rows]="25" [rowsPerPageOptions]="[ 25, 50,100]" [paginator]="true">
|
||||||
|
<ng-template #header>
|
||||||
|
<tr>
|
||||||
|
<th >Date </th>
|
||||||
|
<th >Concession Type </th>
|
||||||
|
<th >Concession Card Number</th>
|
||||||
|
<th >Concession Holder Name</th>
|
||||||
|
<th >Validation Point </th>
|
||||||
|
<th>Expiry date checked</th>
|
||||||
|
|
||||||
|
@if(isAdmin) {
|
||||||
|
<th >Staff Name</th>
|
||||||
|
<th>Delete</th>
|
||||||
|
}
|
||||||
|
<th >Edit</th>
|
||||||
|
<!-- validateDate Column -->
|
||||||
|
</ng-template>
|
||||||
|
<ng-template #body let-element>
|
||||||
|
<tr>
|
||||||
|
<td > {{element.validateDate | date: 'dd/MM/yyyy HH:mm'}} </td>
|
||||||
|
|
||||||
|
<td > {{element.concessionType}} </td>
|
||||||
|
|
||||||
|
|
||||||
|
<td > {{element.concessionCard}} </td>
|
||||||
|
|
||||||
|
|
||||||
|
<td > {{element.concessionHolder}} </td>
|
||||||
|
|
||||||
|
|
||||||
|
<td > {{element.validationPoint}} </td>
|
||||||
|
|
||||||
|
|
||||||
|
<td >
|
||||||
|
@if (element.concessionExpiry == true)
|
||||||
|
{
|
||||||
|
<svg data-p-icon="check" color="green"></svg>
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
<svg data-p-icon="times" color="red"></svg>
|
||||||
|
}
|
||||||
|
|
||||||
|
</td>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- staffFirstName Column -->
|
||||||
|
@if(isAdmin) {
|
||||||
|
|
||||||
|
<td >{{element.staffFirstName}} {{element.staffLastName}} </td>
|
||||||
|
<td >
|
||||||
|
|
||||||
|
|
||||||
|
<button pButton (click)='deleteItem(element.id)'>
|
||||||
|
<svg data-p-icon="times"></svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<button pButton (click)="showEdit(element)" >
|
||||||
|
<svg data-p-icon="pencil"></svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
import { Component, OnInit, OnDestroy, signal, inject } from '@angular/core';
|
||||||
|
|
||||||
|
import { ConcessionValidation } from '../models';
|
||||||
|
|
||||||
|
import { Utils } from '../shares';
|
||||||
|
|
||||||
|
import { Router, RouterModule } from '@angular/router';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { ConcessionValidationService } from './concessionvalidation.service';
|
||||||
|
|
||||||
|
import { DatePickerModule } from 'primeng/datepicker';
|
||||||
|
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||||
|
import { TableModule } from 'primeng/table';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { Pencil } from '@primeicons/angular/pencil';
|
||||||
|
import { Times } from '@primeicons/angular/times';
|
||||||
|
import { Check } from '@primeicons/angular/check';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'concessionvalidation-list',
|
||||||
|
templateUrl: './concessionvalidation.component.html',
|
||||||
|
imports: [TableModule, ButtonModule, CommonModule, FormsModule, Check, Times, Pencil, DatePickerModule, RouterModule],
|
||||||
|
styleUrls: ['./concessionvalidation.component.css']
|
||||||
|
})
|
||||||
|
export class ConcessionValidationComponent implements OnInit, OnDestroy {
|
||||||
|
private concessionValidationService = inject(ConcessionValidationService);
|
||||||
|
private router = inject(Router);
|
||||||
|
private messageService = inject(MessageService);
|
||||||
|
private confirmationService = inject(ConfirmationService);
|
||||||
|
dataSource = signal<ConcessionValidation[]>([]);
|
||||||
|
isAdmin = false;
|
||||||
|
isAllowFilter = true;
|
||||||
|
fromDate = new Date();
|
||||||
|
toDate = new Date();
|
||||||
|
username = '';
|
||||||
|
private subscription: Subscription = new Subscription();
|
||||||
|
|
||||||
|
msg = "[ConcessionValidation component]";
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
private store: Store<appValidationState>
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
this.isAdmin = Utils.getIsAdmin();
|
||||||
|
}
|
||||||
|
//KeyboardEvent
|
||||||
|
applyFilter(event: Event) {
|
||||||
|
const filterValue = (event.target as HTMLInputElement).value;
|
||||||
|
// this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
|
}
|
||||||
|
ngOnInit(): void {
|
||||||
|
const user = Utils.getCurrentUser();
|
||||||
|
// console.log(this.msg + "current login user ", user);
|
||||||
|
if (user.username === "") {
|
||||||
|
user.username = "60249360";
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error', detail: "you are not login! using my number " + user.username });
|
||||||
|
}
|
||||||
|
this.username = user.username;
|
||||||
|
if (this.isAdmin)
|
||||||
|
this.username = '';
|
||||||
|
const dateRange = this.concessionValidationService.getDate();
|
||||||
|
// console.log("the date range for now ", dateRange);
|
||||||
|
if (dateRange.fromDate != '')
|
||||||
|
this.fromDate = dateRange.fromDate;
|
||||||
|
if (dateRange.toDate != '')
|
||||||
|
this.toDate = dateRange.toDate;
|
||||||
|
this.onLoad();
|
||||||
|
/*
|
||||||
|
this.store.dispatch(validationActions.LoadValidationpoints());
|
||||||
|
this.store.pipe(select(validationSelector.getAllValidations)).subscribe(result => this.dataSource.data = result);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(): void {
|
||||||
|
const cDate = this.fromDate;
|
||||||
|
const tDate = this.toDate;
|
||||||
|
|
||||||
|
this.subscription.add(
|
||||||
|
this.concessionValidationService.loadConcessionvalidationByStaffId(this.username, cDate, tDate)
|
||||||
|
.subscribe({
|
||||||
|
next: result => {
|
||||||
|
//console.log(this.msg + "onInit load Data by staffId "+ this.username, result);
|
||||||
|
this.dataSource.set(result.data);
|
||||||
|
}, error: e => console.error("error in loading concession validation", e)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
//this.dataList$ = this.concessionValidationService.loadConcessionvalidationByStaffId(this.username, cDate, tDate)
|
||||||
|
// .pipe(catchError(err => {this.toastr.error(err.message); return EMPTY}));
|
||||||
|
}
|
||||||
|
setDate(): void {
|
||||||
|
this.concessionValidationService.setDateRange(this.fromDate, this.toDate);
|
||||||
|
}
|
||||||
|
showEdit(item: ConcessionValidation) {
|
||||||
|
// console.log(this.msg + "on row click", item);
|
||||||
|
this.setDate();
|
||||||
|
this.router.navigate(['/concessionvalidation/' + item.id], { queryParams: { returnUrl: '/concessionvalidation' } });
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteItem(id: number): void {
|
||||||
|
const message = "Are you sure you want to delete this?";
|
||||||
|
const title = " Confirmation";
|
||||||
|
this.confirmationService.confirm({
|
||||||
|
|
||||||
|
message: message,
|
||||||
|
header: title,
|
||||||
|
icon: 'pi pi-exclamation-triangle',
|
||||||
|
|
||||||
|
accept: () => {
|
||||||
|
this.concessionValidationService.deleteConcessionvalidation(id)
|
||||||
|
.subscribe(result => {
|
||||||
|
console.log(this.msg + " deleteItem success", result);
|
||||||
|
let data = this.dataSource();
|
||||||
|
let index: number = data.findIndex(d => d.id === id);
|
||||||
|
console.log(this.msg + "delete from datasource");
|
||||||
|
data.splice(index, 1)
|
||||||
|
this.dataSource.set(data);
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
|
||||||
|
|
||||||
|
console.log("error ", error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
reject: () => {
|
||||||
|
console.log(this.msg + "click on No to delete");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-form-field {
|
||||||
|
font-size: 14px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
td.mat-column-edit, .mat-column-delete {
|
||||||
|
width: 35px;
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<div class="p-10">
|
||||||
|
<div class="title">
|
||||||
|
{{getEditText()}}
|
||||||
|
</div>
|
||||||
|
<form [formGroup]="concessionvalidationForm" (ngSubmit)="onSubmit()">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
|
||||||
|
<div class="m-2">
|
||||||
|
|
||||||
|
<label class="flex w-full">Concession Card Number<strong class="app-require">*</strong></label>
|
||||||
|
<input pInputText formControlName="concessionCard" maxlength="60" name="concessionCard" (blur)="searchCard()"
|
||||||
|
placeholder="Concession Card Number" required>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@if(isAdmin) {
|
||||||
|
<div class="m-2">
|
||||||
|
<label for="time" class="flex w-full">Current Date</label>
|
||||||
|
<p-datepicker formControlName="validateDate" [showTime]="true" inputId="time"
|
||||||
|
dateFormat="dd/mm/yy"></p-datepicker>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<!--end-->
|
||||||
|
<div class="m-2">
|
||||||
|
|
||||||
|
<label class="flex w-full">Concession Type<strong class="app-require">*</strong></label>
|
||||||
|
<p-select formControlName="concessionTypeId"
|
||||||
|
[options]="concessionTypes()"
|
||||||
|
optionLabel="description" optionValue="id">
|
||||||
|
|
||||||
|
</p-select>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="m-2">
|
||||||
|
|
||||||
|
<label class="flex w-full">Concession Holder Name<strong class="app-require">*</strong></label>
|
||||||
|
<input pInputText formControlName="concessionHolder" maxlength="100" name=""
|
||||||
|
placeholder="Concession Holder Name" >
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="m-2">
|
||||||
|
<label class="flex w-full"> Expiry date checked <strong
|
||||||
|
class="app-require">*</strong> </label>
|
||||||
|
<p-checkbox formControlName="concessionExpiry" [binary]="true"></p-checkbox>
|
||||||
|
|
||||||
|
@if(isAdmin) {
|
||||||
|
<div >
|
||||||
|
|
||||||
|
<label class="flex w-full">Validation Point<strong class="app-require">*</strong></label>
|
||||||
|
<p-select formControlName="validationPointId" [options]="validationPoints()" optionLabel="description" optionValue="id">
|
||||||
|
|
||||||
|
</p-select>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-content-end mt-2">
|
||||||
|
<button class="mr-2" type="submit" pButton [disabled]="isFieldsChange">Submit</button>
|
||||||
|
<button type="button" pButton (click)="goBack()">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<!--pre>{{ concessionvalidationForm.value|json}}</pre-->
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,296 @@
|
|||||||
|
import { Component, inject, OnDestroy, OnInit, signal, ViewChild } from '@angular/core';
|
||||||
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
|
import { FormGroup, Validators, ReactiveFormsModule, FormBuilder, FormControl } from '@angular/forms';
|
||||||
|
|
||||||
|
import { ConcessionValidation, Lookup, ResultModel } from '../models';
|
||||||
|
import { Subject, Subscription } from 'rxjs';
|
||||||
|
import { LookupService } from '../shares';
|
||||||
|
import { ConcessionValidationService } from './concessionvalidation.service';
|
||||||
|
import { Utils } from '../shares';
|
||||||
|
|
||||||
|
import moment from 'moment';
|
||||||
|
import { ConfirmationService, MessageService } from 'primeng/api';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { InputTextModule } from 'primeng/inputtext';
|
||||||
|
import { CheckboxModule } from 'primeng/checkbox';
|
||||||
|
import { DatePickerModule } from 'primeng/datepicker';
|
||||||
|
import { SelectModule } from 'primeng/select';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: 'concessionvalidation.edit.component.html',
|
||||||
|
selector: 'concessionvalidation-edit',
|
||||||
|
imports: [ButtonModule, InputTextModule, CheckboxModule, DatePickerModule,
|
||||||
|
SelectModule, ReactiveFormsModule],
|
||||||
|
styleUrls: ['concessionvalidation.edit.component.css']
|
||||||
|
})
|
||||||
|
export class ConcessionValidationEditComponent implements OnInit, OnDestroy {
|
||||||
|
returnUrl = "";
|
||||||
|
private formBuilder = inject(FormBuilder);
|
||||||
|
private lookupService = inject(LookupService);
|
||||||
|
private concessionValidationService = inject(ConcessionValidationService);
|
||||||
|
private router = inject(Router);
|
||||||
|
|
||||||
|
private confirmationService = inject(ConfirmationService);
|
||||||
|
private messageService = inject(MessageService);
|
||||||
|
private route = inject(ActivatedRoute);
|
||||||
|
msg = "[concessionvalidation edit Component] "
|
||||||
|
isChange = true; // disable use false//true for not disable. make sure it true is disable button.
|
||||||
|
subChanged$ = new Subject<boolean>();
|
||||||
|
_id = -1;
|
||||||
|
isAdmin = false;
|
||||||
|
concessionTypes = signal<Lookup[]>([]);
|
||||||
|
validationPoints = signal<Lookup[]>([]);
|
||||||
|
|
||||||
|
|
||||||
|
private subscription: Subscription = new Subscription();
|
||||||
|
concessionvalidationForm = this.formBuilder.group({
|
||||||
|
id: [0], //Validators.required
|
||||||
|
validateDate: new FormControl<Date | null>(null), //Validators.required
|
||||||
|
concessionCard: ['', Validators.required],
|
||||||
|
concessionHolder: ['', Validators.required],
|
||||||
|
concessionExpiry: [false, Validators.required], //Validators.required
|
||||||
|
concessionTypeId: [-1, Validators.min(1)],
|
||||||
|
stafflinkNo: [''], //Validators.required
|
||||||
|
validationPointId: [-1, Validators.min(1)],
|
||||||
|
validationPoint: [''], //Validators.required
|
||||||
|
staffFirstName: [''], //Validators.required
|
||||||
|
staffLastName: [''], //Validators.required
|
||||||
|
staffEmail: [''], //Validators.required
|
||||||
|
active: [false], //Validators.required
|
||||||
|
});
|
||||||
|
constructor() {
|
||||||
|
/*
|
||||||
|
this.concessionTypes = [];
|
||||||
|
let item:Lookup = {id:1,categoryId:0, description:'Health Care Card'};
|
||||||
|
this.concessionTypes.push(item);
|
||||||
|
item = {id:3,categoryId:1, description:'Gold Veterans Affairs Card'};
|
||||||
|
this.concessionTypes.push(item);
|
||||||
|
item = {id:3,categoryId:1, description:'Pensioner Concession Card'};
|
||||||
|
this.concessionTypes.push(item);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
searchCard(): void {
|
||||||
|
const cardNo = this.concessionvalidationForm.controls["concessionCard"].value ?? '';
|
||||||
|
if (cardNo != "") {
|
||||||
|
const card$ = this.concessionValidationService.loadConcessionvalidationByCard(cardNo);
|
||||||
|
this.subscription.add(card$.subscribe({
|
||||||
|
next: x => {
|
||||||
|
if (x.statusCode == 1) {
|
||||||
|
const data = x.data;
|
||||||
|
this.concessionvalidationForm.patchValue({
|
||||||
|
concessionHolder: data.concessionHolder,
|
||||||
|
concessionTypeId: data.concessionTypeId,
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
|
||||||
|
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||||
|
const id = Number(this.route.snapshot.paramMap.get('id'));
|
||||||
|
|
||||||
|
// now load thing up
|
||||||
|
this._id = id;
|
||||||
|
|
||||||
|
this.isAdmin = Utils.getIsAdmin();
|
||||||
|
|
||||||
|
this.subscription.add(this.lookupService.loadConcessionType().subscribe({
|
||||||
|
next: x => this.concessionTypes.set(x.data),
|
||||||
|
error: e => console.error("error loading concession type", e)
|
||||||
|
}
|
||||||
|
));
|
||||||
|
this.subscription.add(
|
||||||
|
this.lookupService.loadValidationPoint().subscribe({
|
||||||
|
next: x => this.validationPoints.set(x.data),
|
||||||
|
error: e => console.error("error validation Point", e)
|
||||||
|
})
|
||||||
|
|
||||||
|
);
|
||||||
|
this.subscription.add(this.concessionvalidationForm.valueChanges.subscribe(x => this.isChange = false));
|
||||||
|
this.subscription.add(this.subChanged$.subscribe(x => this.isChange = x));
|
||||||
|
const user = Utils.getCurrentUser();
|
||||||
|
|
||||||
|
console.log(this.msg + "current login user ", user);
|
||||||
|
if (user.username === "") {
|
||||||
|
user.username = "60249360";
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error', detail: "you are not login! using my number " + user.username });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._id < 1) {
|
||||||
|
this.concessionvalidationForm.patchValue({
|
||||||
|
validateDate: new Date(),
|
||||||
|
stafflinkNo: user.username,
|
||||||
|
staffFirstName: user.firstName,
|
||||||
|
staffLastName: user.lastName,
|
||||||
|
staffEmail: user.email,
|
||||||
|
validationPointId: user.validationPointId,
|
||||||
|
active: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.subscription.add(
|
||||||
|
this.concessionValidationService.loadConcessionvalidationById(id)
|
||||||
|
.subscribe({
|
||||||
|
next: x => this.assignValue(x.data),
|
||||||
|
error: e => console.log(e.message)
|
||||||
|
}));
|
||||||
|
// console.log(this.msg + " load from db"+id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get isFieldsChange() {
|
||||||
|
const chan = this.isChange || !this.concessionvalidationForm.valid; // this disable so need true valid = true not
|
||||||
|
const fvalid = this.concessionvalidationForm.valid;
|
||||||
|
// console.log(this.msg + "is fields change is valid: " + fvalid , chan,);
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
getEditText(): string {
|
||||||
|
if (this._id > 0)
|
||||||
|
return "Edit Concession Validation";
|
||||||
|
else
|
||||||
|
return "New Concession Validation";
|
||||||
|
}
|
||||||
|
onChangeValidation($event: Event) {
|
||||||
|
//$event.target.value
|
||||||
|
//this.selectedCar = (event.target as HTMLSelectElement).value;
|
||||||
|
var val = ($event.target as HTMLSelectElement).value;
|
||||||
|
// console.log("the log for val " , val);
|
||||||
|
}
|
||||||
|
|
||||||
|
assignValue(concessionvalidation: ConcessionValidation): void {
|
||||||
|
this.concessionvalidationForm.patchValue({
|
||||||
|
id: concessionvalidation.id,
|
||||||
|
validateDate: moment(concessionvalidation.validateDate).toDate(),
|
||||||
|
concessionCard: concessionvalidation.concessionCard,
|
||||||
|
concessionHolder: concessionvalidation.concessionHolder,
|
||||||
|
concessionExpiry: concessionvalidation.concessionExpiry,
|
||||||
|
concessionTypeId: concessionvalidation.concessionTypeId,
|
||||||
|
stafflinkNo: concessionvalidation.stafflinkNo,
|
||||||
|
staffFirstName: concessionvalidation.staffFirstName,
|
||||||
|
staffLastName: concessionvalidation.staffLastName,
|
||||||
|
staffEmail: concessionvalidation.staffEmail,
|
||||||
|
validationPointId: concessionvalidation.validationPointId,
|
||||||
|
active: concessionvalidation.active,
|
||||||
|
});
|
||||||
|
// disable use false//true for not disable.
|
||||||
|
this.subChanged$.next(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// convenience getter for easy access in form fields
|
||||||
|
get f() { return this.concessionvalidationForm.controls; }
|
||||||
|
|
||||||
|
onSubmit(): void {
|
||||||
|
const OkToSave = this.concessionvalidationForm.valid;
|
||||||
|
|
||||||
|
const checkActive = this.concessionvalidationForm.value.concessionExpiry ?? false;
|
||||||
|
console.log("onsubmit value", checkActive, this.concessionvalidationForm.value);
|
||||||
|
if (checkActive == false) {
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Check Concession Expiry', detail: 'Not Check Concession Expiry' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (OkToSave) {
|
||||||
|
const concessionvalidationValue = this.concessionvalidationForm.value;
|
||||||
|
const concessionvalidation: ConcessionValidation = {
|
||||||
|
id: concessionvalidationValue.id ?? 0,
|
||||||
|
validateDate: moment(concessionvalidationValue.validateDate).toDate(),
|
||||||
|
concessionCard: concessionvalidationValue.concessionCard ?? '',
|
||||||
|
concessionHolder: concessionvalidationValue.concessionHolder ?? '',
|
||||||
|
concessionExpiry: concessionvalidationValue.concessionExpiry ?? false,
|
||||||
|
concessionTypeId: concessionvalidationValue.concessionTypeId ?? 0,
|
||||||
|
stafflinkNo: concessionvalidationValue.stafflinkNo ?? '',
|
||||||
|
staffFirstName: concessionvalidationValue.staffFirstName ?? '',
|
||||||
|
staffLastName: concessionvalidationValue.staffLastName ?? '',
|
||||||
|
staffEmail: concessionvalidationValue.staffEmail ?? '',
|
||||||
|
validationPointId: concessionvalidationValue.validationPointId ?? 0,
|
||||||
|
active: concessionvalidationValue.active ?? false,
|
||||||
|
};
|
||||||
|
// console.log(this.msg + "this is OKTOsave", concessionvalidation);
|
||||||
|
//if edit mode just save it don't check
|
||||||
|
if (concessionvalidation.id > 0) {
|
||||||
|
this.saveConcession(concessionvalidation);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//check first only if new
|
||||||
|
this.checkAndSave(concessionvalidation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// console.log(this.msg + "this is NOT OKTOsave");
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Error', detail: "please fill in the required fields" });
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAndSave(concessionvalidation: ConcessionValidation): void {
|
||||||
|
const currentDate = moment(concessionvalidation.validateDate).format("YYYY-MM-DD");
|
||||||
|
const id = concessionvalidation.id;
|
||||||
|
this.subscription.add(
|
||||||
|
this.concessionValidationService.checkConcessionValidationByStaff(concessionvalidation.stafflinkNo,
|
||||||
|
concessionvalidation.concessionCard, currentDate, id)
|
||||||
|
.subscribe(x => {
|
||||||
|
let okTo = true;
|
||||||
|
if (x.data < 0) {
|
||||||
|
const message = "This card was used earlier today. Is it Ok to continue?";
|
||||||
|
const title = "Alert";
|
||||||
|
this.confirmationService.confirm({
|
||||||
|
message: message,
|
||||||
|
header: 'Confirmation',
|
||||||
|
icon: 'pi pi-exclamation-triangle',
|
||||||
|
accept: () => {
|
||||||
|
this.saveConcession(concessionvalidation);
|
||||||
|
},
|
||||||
|
reject: () => {
|
||||||
|
this.router.navigate([this.returnUrl]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.saveConcession(concessionvalidation);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
saveConcession(concessionvalidation: ConcessionValidation): void {
|
||||||
|
//console.log(this.msg + " Save Concession validation to server");
|
||||||
|
this.subscription.add(
|
||||||
|
this.concessionValidationService.saveConcessionvalidation(concessionvalidation)
|
||||||
|
.subscribe({
|
||||||
|
next: x => {
|
||||||
|
if (x.statusCode >= 1) {
|
||||||
|
this.messageService.add({ severity: 'success', summary: 'Success', detail: "Save is OK" });
|
||||||
|
this.router.navigate([this.returnUrl]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Fail to Save', detail: x.message });
|
||||||
|
|
||||||
|
}, error: e => {
|
||||||
|
const message = e || e.message;
|
||||||
|
this.messageService.add({ severity: 'error', summary: 'Fail to Save', detail: message });
|
||||||
|
console.log("error ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
goBack(): void {
|
||||||
|
this.router.navigate([this.returnUrl]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
import { Injectable, Inject } from '@angular/core';
|
||||||
|
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { ConcessionValidation, ResultModel, ConfigureUrl } from '../models';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { AppSettingService } from '../shares';
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class ConcessionValidationService {
|
||||||
|
private dateRange: any;
|
||||||
|
constructor(private http: HttpClient,
|
||||||
|
private appSetting: AppSettingService
|
||||||
|
) {
|
||||||
|
this.dateRange = {};
|
||||||
|
this.dateRange.fromDate = '';
|
||||||
|
this.dateRange.toDate = '';
|
||||||
|
console.log("constructor concessionValidationService daterange", this.dateRange);
|
||||||
|
}
|
||||||
|
public setDateRange(fromDate: any, toDate: any) {
|
||||||
|
this.dateRange.fromDate = moment(fromDate).toDate();
|
||||||
|
this.dateRange.toDate = moment(toDate).toDate();
|
||||||
|
// console.log("concessionValidationService setdaterange", this.dateRange);
|
||||||
|
}
|
||||||
|
public getDate(): any {
|
||||||
|
// console.log("concessionValidationService getdaterange", this.dateRange);
|
||||||
|
return this.dateRange;
|
||||||
|
}
|
||||||
|
loadConcessionvalidations(): Observable<ResultModel<ConcessionValidation[]>> {
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationUrl;
|
||||||
|
let config = { headers: { 'Content-Type': 'application/json' } };
|
||||||
|
// console.log("the concession", baseUrl);
|
||||||
|
return this.http.get<ResultModel<ConcessionValidation[]>>(baseUrl);
|
||||||
|
}
|
||||||
|
loadConcessionvalidationByStaffId(staffLinkId: string, fromDate: Date, toDate: Date): Observable<ResultModel<ConcessionValidation[]>> {
|
||||||
|
this.setDateRange(fromDate, toDate);
|
||||||
|
const strDate = moment(fromDate).format("YYYY-MM-DD");
|
||||||
|
const strtoDate = moment(toDate).format("YYYY-MM-DD");
|
||||||
|
const url = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationByIdUrl;
|
||||||
|
const params = new HttpParams().set("staffLinkNo", staffLinkId)
|
||||||
|
.set("fromDate", strDate)
|
||||||
|
.set("toDate", strtoDate);
|
||||||
|
const headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||||
|
const options = {
|
||||||
|
headers: headers,
|
||||||
|
params: params
|
||||||
|
};
|
||||||
|
//console.log("loadConcessionvalidationByStaffId url", url);
|
||||||
|
return this.http.get<ResultModel<ConcessionValidation[]>>(url, options);
|
||||||
|
}
|
||||||
|
loadConcessionvalidationById(id: number): Observable<ResultModel<ConcessionValidation>> {
|
||||||
|
let params = new HttpParams().set("id", "" + id);
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationUrl;
|
||||||
|
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||||
|
let options = {
|
||||||
|
headers: headers,
|
||||||
|
params: params
|
||||||
|
};
|
||||||
|
//return this.http.get<Concessionvalidation>(this.baseUrl + 'api/Concessionvalidation/LoadConcessionvalidationById',options);
|
||||||
|
return this.http.get<ResultModel<ConcessionValidation>>(baseUrl + "/" + id);
|
||||||
|
}
|
||||||
|
loadConcessionvalidationByCard(cardNo: string): Observable<ResultModel<ConcessionValidation>> {
|
||||||
|
const data = { cardNo };
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationUrl + "/GetConcessionCard";
|
||||||
|
/*
|
||||||
|
let params = new HttpParams().set("id", "" + id);
|
||||||
|
|
||||||
|
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||||
|
let options = {
|
||||||
|
headers: headers,
|
||||||
|
params: params
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
//return this.http.get<Concessionvalidation>(this.baseUrl + 'api/Concessionvalidation/LoadConcessionvalidationById',options);
|
||||||
|
return this.http.post<ResultModel<ConcessionValidation>>(baseUrl, data);
|
||||||
|
}
|
||||||
|
checkConcessionValidationByStaff(staffLinkNo: string, concessionCard: string, currentDate: string, id: number): Observable<ResultModel<number>> {
|
||||||
|
let params = new HttpParams().set("staffLinkNo", staffLinkNo)
|
||||||
|
.set("concessionCard", concessionCard)
|
||||||
|
.set("currentDate", currentDate)
|
||||||
|
.set("id", "" + id);
|
||||||
|
|
||||||
|
let headers = new HttpHeaders().set('Content-Type', 'application/json');
|
||||||
|
let options = {
|
||||||
|
headers: headers,
|
||||||
|
params: params
|
||||||
|
};
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl;
|
||||||
|
const url = baseUrl + "/" + ConfigureUrl.CheckConcessionValidationByStaffUrl;
|
||||||
|
//return this.http.get<Concessionvalidation>(this.baseUrl + 'api/Concessionvalidation/LoadConcessionvalidationById',options);
|
||||||
|
return this.http.get<ResultModel<number>>(url, options);
|
||||||
|
}
|
||||||
|
saveConcessionvalidation(item: ConcessionValidation): Observable<ResultModel<number>> { //insert Concessionvalidation
|
||||||
|
let config = { headers: { 'Content-Type': 'application/json' } };
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationUrl;
|
||||||
|
return this.http.post<ResultModel<number>>(baseUrl, item, config);
|
||||||
|
}
|
||||||
|
deleteConcessionvalidation(Id: number): Observable<ResultModel<number>> {
|
||||||
|
let config = { headers: { 'Content-Type': 'application/json' } };
|
||||||
|
const baseUrl = this.appSetting.appSetting.baseUrl + "/" + ConfigureUrl.concessionValidationUrl;
|
||||||
|
return this.http.delete<ResultModel<number>>(baseUrl + "/" + Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export * from './concessionvalidation.component';
|
||||||
|
export * from './concessionvalidation.edit.component';
|
||||||
|
export * from './concessionvalidation.service';
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-form-field {
|
||||||
|
font-size: 14px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
td.mat-column-edit, .mat-column-delete {
|
||||||
|
width: 35px;
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<div class="edit-content">
|
||||||
|
<h3>Concession Type</h3>
|
||||||
|
|
||||||
|
<div class="addlink">
|
||||||
|
<a class="p-ripple p-button p-component flex justify-self-end mb-2" [routerLink]='["/concessiontype", -1]' [queryParams]="{returnUrl:'/concessiontype'}">
|
||||||
|
|
||||||
|
Add Concession Type
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p-table [value]="dataSource()" rowHover="true" dataKey="id"
|
||||||
|
[rows]="25" [rowsPerPageOptions]="[ 25, 50,100]" [paginator]="true">
|
||||||
|
|
||||||
|
<ng-template #header>
|
||||||
|
<tr>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Display</th>
|
||||||
|
<th>Active</th>
|
||||||
|
<th>Edit</th>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template #body let-item>
|
||||||
|
<tr>
|
||||||
|
<td>{{ item.description }}</td>
|
||||||
|
<td> {{item.display}}</td>
|
||||||
|
<td>
|
||||||
|
@if(item.active == true) {
|
||||||
|
<svg data-p-icon="check" color="green"></svg>
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
<svg data-p-icon="times" color="red"></svg>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button pButton (click)="showEdit(item)">
|
||||||
|
<svg data-p-icon="pencil"></svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
</p-table>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import { Component, OnInit, OnDestroy, signal, inject } from '@angular/core';
|
||||||
|
import { ConcessionTypeService } from './concessiontype.service';
|
||||||
|
import { ConcessionType } from '../models';
|
||||||
|
|
||||||
|
|
||||||
|
import { take } from 'rxjs/operators';
|
||||||
|
import { Router, RouterModule } from '@angular/router';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { MessageService } from 'primeng/api';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { Pencil } from '@primeicons/angular/pencil';
|
||||||
|
import { TableModule } from 'primeng/table';
|
||||||
|
import { Check } from '@primeicons/angular/check';
|
||||||
|
import { Times } from '@primeicons/angular/times';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'concessiontype-list',
|
||||||
|
templateUrl: './concessiontype.component.html',
|
||||||
|
imports: [ButtonModule, TableModule, RouterModule, Pencil, Check, Times],
|
||||||
|
styleUrls: ['./concessiontype.component.css']
|
||||||
|
})
|
||||||
|
export class ConcessionTypeComponent implements OnInit, OnDestroy {
|
||||||
|
private concessionTypeService = inject(ConcessionTypeService);
|
||||||
|
private messageService = inject(MessageService);
|
||||||
|
private router = inject(Router);
|
||||||
|
dataSource = signal<ConcessionType[]>([]);
|
||||||
|
|
||||||
|
private subscription: Subscription = new Subscription();
|
||||||
|
|
||||||
|
|
||||||
|
msg = "[concessionType.com]";
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
private store: Store<appValidationState>
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
applyFilter($event:any) {
|
||||||
|
const filterValue = $event.target.value;
|
||||||
|
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.subscription.add(
|
||||||
|
this.concessionTypeService.loadConcessiontypes().subscribe(
|
||||||
|
{
|
||||||
|
next: result => {
|
||||||
|
// console.log(this.msg + "onInit", result);
|
||||||
|
this.dataSource.set(result.data);
|
||||||
|
}, error: e => {
|
||||||
|
|
||||||
|
console.log("error ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
this.store.dispatch(validationActions.LoadValidationpoints());
|
||||||
|
this.store.pipe(select(validationSelector.getAllValidations)).subscribe(result => this.dataSource.data = result);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
showEdit(item: ConcessionType) {
|
||||||
|
console.log(this.msg + "on row click", item);
|
||||||
|
this.router.navigate(['/concessiontype/' + item.id], { queryParams: { returnUrl: '/concessiontype' } });
|
||||||
|
}
|
||||||
|
deleteItem(id: number): void {
|
||||||
|
|
||||||
|
this.concessionTypeService.deleteConcessiontype(id)
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe(result => {
|
||||||
|
// console.log(this.msg + " deleteItem success", result);
|
||||||
|
let data = this.dataSource();
|
||||||
|
let index: number = data.findIndex(d => d.id === id);
|
||||||
|
// console.log(this.msg + "delete from datasource");
|
||||||
|
data.splice(index, 1)
|
||||||
|
this.dataSource.set(data);
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
|
||||||
|
console.log("error ", error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user