Modernize and Dockerize server
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,7 +4,8 @@
|
|||||||
client/node_modules
|
client/node_modules
|
||||||
client/dist
|
client/dist
|
||||||
|
|
||||||
.vs
|
.vs/
|
||||||
|
.user
|
||||||
|
|
||||||
# Build results
|
# Build results
|
||||||
[Dd]ebug/
|
[Dd]ebug/
|
||||||
|
|||||||
30
server/.dockerignore
Normal file
30
server/.dockerignore
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
**/.classpath
|
||||||
|
**/.dockerignore
|
||||||
|
**/.env
|
||||||
|
**/.git
|
||||||
|
**/.gitignore
|
||||||
|
**/.project
|
||||||
|
**/.settings
|
||||||
|
**/.toolstarget
|
||||||
|
**/.vs
|
||||||
|
**/.vscode
|
||||||
|
**/*.*proj.user
|
||||||
|
**/*.dbmdl
|
||||||
|
**/*.jfm
|
||||||
|
**/azds.yaml
|
||||||
|
**/bin
|
||||||
|
**/charts
|
||||||
|
**/docker-compose*
|
||||||
|
**/Dockerfile*
|
||||||
|
**/node_modules
|
||||||
|
**/npm-debug.log
|
||||||
|
**/obj
|
||||||
|
**/secrets.dev.yaml
|
||||||
|
**/values.dev.yaml
|
||||||
|
LICENSE
|
||||||
|
README.md
|
||||||
|
!**/.gitignore
|
||||||
|
!.git/HEAD
|
||||||
|
!.git/config
|
||||||
|
!.git/packed-refs
|
||||||
|
!.git/refs/heads/**
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<UserSecretsId>a7b40068-a2f6-4c63-bbd9-0fd346908fb0</UserSecretsId>
|
||||||
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
|
<DockerfileContext>..\..</DockerfileContext>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Dapper" Version="2.1.72" />
|
<PackageReference Include="Dapper" Version="2.1.72" />
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="7.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +1,29 @@
|
|||||||
|
using CPATapi.Server.Interfaces;
|
||||||
|
using CPATapi.Server.Models;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using Microsoft.Data.SqlClient;
|
using Microsoft.Data.SqlClient;
|
||||||
|
|
||||||
namespace CPATapi.Server.Controllers
|
namespace CPATapi.Server.Controllers;
|
||||||
{
|
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class AvailabilityController(IConfiguration config) : ControllerBase
|
public class AvailabilityController(IZeitConsensRepository zeitConsens) : ControllerBase
|
||||||
{
|
{
|
||||||
[HttpGet, Route("users")]
|
[HttpGet]
|
||||||
public async Task<IEnumerable<string>> GetUsers()
|
[Route("users")]
|
||||||
|
[ProducesResponseType<IEnumerable<string>>(StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetUsers()
|
||||||
{
|
{
|
||||||
await using var con = new SqlConnection(config["Db:ConnectionStringZc"]);
|
return Ok(await zeitConsens.GetUsersAsync());
|
||||||
await con.OpenAsync();
|
|
||||||
return await con.QueryAsync<string>("""
|
|
||||||
SELECT DISTINCT MA_USER_NAME
|
|
||||||
FROM dbo.MA_DATEN
|
|
||||||
WHERE MA_USER_NAME IS NOT NULL AND MA_USER_AKTIV = 1
|
|
||||||
ORDER BY MA_USER_NAME
|
|
||||||
""");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet, Route("{user}")]
|
[HttpGet]
|
||||||
public async Task<object> GetAvailability(string user)
|
[Route("{user}")]
|
||||||
|
[ProducesResponseType<Availability>(StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetAvailability(string user)
|
||||||
{
|
{
|
||||||
await using var con = new SqlConnection(config["Db:ConnectionStringZc"]);
|
var stampCount = (await zeitConsens.GetStampsAsync(user, DateTime.Now.Date, DateTime.Now.AddDays(1).Date)).Count();
|
||||||
await con.OpenAsync();
|
return Ok(new Availability { User = user, LoggedIn = stampCount % 2 != 0 });
|
||||||
var stampCount = (await con.QueryAsync("""
|
|
||||||
SELECT *
|
|
||||||
FROM dbo.BU
|
|
||||||
INNER JOIN dbo.MA_DATEN on MA_NR = BU_MA_NR
|
|
||||||
WHERE
|
|
||||||
MA_USER_NAME = @user AND
|
|
||||||
BU_BU >= @date AND BU_BU < @tomorrow
|
|
||||||
""", new { user, date = DateTime.Now.Date, tomorrow = DateTime.Now.AddDays(1).Date })).Count();
|
|
||||||
return new { user, loggedIn = stampCount % 2 != 0 };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
|
using CPATapi.Server.Interfaces;
|
||||||
using CPATapi.Server.Models;
|
using CPATapi.Server.Models;
|
||||||
using Dapper;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
|
|
||||||
namespace CPATapi.Server.Controllers
|
namespace CPATapi.Server.Controllers;
|
||||||
{
|
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class CallerIdController(IConfiguration config) : ControllerBase
|
public class CallerIdController(ITapiDirectoryRepository tapiDirectory) : ControllerBase
|
||||||
{
|
{
|
||||||
[HttpGet, Route("{number}")]
|
[HttpGet]
|
||||||
public async Task<TapiContact> CallerIdAsync([FromRoute] string number)
|
[Route("{number}")]
|
||||||
|
[ProducesResponseType<TapiContact>(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> CallerIdAsync([FromRoute] string number)
|
||||||
{
|
{
|
||||||
if (number.Length >= 5)
|
if (number.Length >= 5)
|
||||||
{
|
{
|
||||||
@@ -18,20 +20,11 @@ namespace CPATapi.Server.Controllers
|
|||||||
number = "%" + minMatch;
|
number = "%" + minMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
await using var con = new SqlConnection(config["Db:ConnectionString"]);
|
var result = await tapiDirectory.SearchByNumberAsync(number);
|
||||||
await con.OpenAsync();
|
if (result != null)
|
||||||
|
{
|
||||||
var result = await con.QueryFirstOrDefaultAsync<TapiContact>("""
|
return Ok(result);
|
||||||
SELECT
|
}
|
||||||
TD_ID,
|
return NotFound();
|
||||||
TD_NAME,
|
|
||||||
TD_NUMBER,
|
|
||||||
TD_NUMBER_TAPI,
|
|
||||||
TD_MEDIUM
|
|
||||||
FROM dbo.CP_TAPI_DIRECTORY
|
|
||||||
WHERE TD_NUMBER_TAPI LIKE @number
|
|
||||||
""", new {number});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,21 @@
|
|||||||
|
using CPATapi.Server.Interfaces;
|
||||||
using CPATapi.Server.Models;
|
using CPATapi.Server.Models;
|
||||||
using Dapper;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
|
|
||||||
namespace CPATapi.Server.Controllers
|
namespace CPATapi.Server.Controllers;
|
||||||
{
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
public class ContactController(ILogger<ContactController> logger, IConfiguration config) : ControllerBase
|
public class ContactController(ILogger<ContactController> logger, ITapiDirectoryRepository tapiDirectory) : ControllerBase
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly ILogger<ContactController> _logger = logger;
|
private readonly ILogger<ContactController> _logger = logger;
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IEnumerable<TapiContact>> GetAsync()
|
[Produces("application/json")]
|
||||||
|
[ProducesResponseType<IEnumerable<TapiContact>>(StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetAsync()
|
||||||
{
|
{
|
||||||
await using var con = new SqlConnection(config["Db:ConnectionString"]);
|
return Ok(await tapiDirectory.GetAllAsync());
|
||||||
await con.OpenAsync();
|
|
||||||
|
|
||||||
var contacts = await con.QueryAsync<TapiContact>("""
|
|
||||||
SELECT
|
|
||||||
TD_ID,
|
|
||||||
TD_NAME,
|
|
||||||
TD_NUMBER,
|
|
||||||
TD_NUMBER_TAPI,
|
|
||||||
TD_MEDIUM
|
|
||||||
FROM dbo.CP_TAPI_DIRECTORY
|
|
||||||
""");
|
|
||||||
return contacts;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +1,25 @@
|
|||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using CPATapi.Server.Interfaces;
|
||||||
using CPATapi.Server.Models;
|
using CPATapi.Server.Models;
|
||||||
using Dapper;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
|
|
||||||
namespace CPATapi.Server.Controllers
|
namespace CPATapi.Server.Controllers;
|
||||||
{
|
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class SearchController(IConfiguration config) : ControllerBase
|
public class SearchController(ITapiDirectoryRepository tapiDirectory) : ControllerBase
|
||||||
{
|
{
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IEnumerable<TapiContact>> SearchAsync([FromQuery] string query)
|
[ProducesResponseType<IEnumerable<TapiContact>>(StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> SearchAsync([FromQuery] string query)
|
||||||
{
|
{
|
||||||
if (query == null)
|
if (query == null)
|
||||||
{
|
{
|
||||||
return new List<TapiContact>();
|
return Ok(new List<TapiContact>());
|
||||||
}
|
}
|
||||||
|
|
||||||
var args = Regex.Split(query, "\\s").Where(s => !string.IsNullOrWhiteSpace(s)).Select(s => s.Trim()).ToArray();
|
var args = Regex.Split(query, "\\s").Where(s => !string.IsNullOrWhiteSpace(s)).Select(s => s.Trim()).ToArray();
|
||||||
|
|
||||||
if (args.Length == 0)
|
return Ok(await tapiDirectory.SearchAsync(args));
|
||||||
{
|
|
||||||
return new List<TapiContact>();
|
|
||||||
}
|
|
||||||
|
|
||||||
await using var con = new SqlConnection(config["Db:ConnectionString"]);
|
|
||||||
await con.OpenAsync();
|
|
||||||
var sql = new StringBuilder("""
|
|
||||||
SELECT TOP 10
|
|
||||||
TD_ID,
|
|
||||||
TD_NAME,
|
|
||||||
TD_NUMBER,
|
|
||||||
TD_NUMBER_TAPI,
|
|
||||||
TD_MEDIUM
|
|
||||||
FROM dbo.CP_TAPI_DIRECTORY
|
|
||||||
WHERE
|
|
||||||
""");
|
|
||||||
var first = true;
|
|
||||||
var dp = new DynamicParameters();
|
|
||||||
for (var i = 1; i <= args.Length; i++)
|
|
||||||
{
|
|
||||||
if (!first)
|
|
||||||
{
|
|
||||||
sql.AppendLine("AND");
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
sql.AppendLine($"(TD_NAME LIKE @s{i} OR");
|
|
||||||
sql.AppendLine($" TD_NUMBER_TAPI LIKE @s{i})");
|
|
||||||
dp.Add($"s{i}", $"%{args[i-1]}%");
|
|
||||||
}
|
|
||||||
|
|
||||||
return await con.QueryAsync<TapiContact>(sql.ToString(), dp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
server/src/CPATapi.Server/Dockerfile
Normal file
28
server/src/CPATapi.Server/Dockerfile
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||||
|
|
||||||
|
# This stage is used when running from VS in fast mode (Default for Debug configuration)
|
||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
|
||||||
|
USER $APP_UID
|
||||||
|
WORKDIR /app
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# This stage is used to build the service project
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||||
|
ARG BUILD_CONFIGURATION=Release
|
||||||
|
WORKDIR /src
|
||||||
|
COPY ["CPATapi.Server/CPATapi.Server.csproj", "CPATapi.Server/"]
|
||||||
|
RUN dotnet restore "CPATapi.Server/CPATapi.Server.csproj"
|
||||||
|
COPY . .
|
||||||
|
WORKDIR "/src/CPATapi.Server"
|
||||||
|
RUN dotnet build "./CPATapi.Server.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||||
|
|
||||||
|
# This stage is used to publish the service project to be copied to the final stage
|
||||||
|
FROM build AS publish
|
||||||
|
ARG BUILD_CONFIGURATION=Release
|
||||||
|
RUN dotnet publish "./CPATapi.Server.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||||
|
|
||||||
|
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
|
||||||
|
FROM base AS final
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=publish /app/publish .
|
||||||
|
ENTRYPOINT ["dotnet", "CPATapi.Server.dll"]
|
||||||
5
server/src/CPATapi.Server/Interfaces/IRepository.cs
Normal file
5
server/src/CPATapi.Server/Interfaces/IRepository.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
namespace CPATapi.Server.Interfaces;
|
||||||
|
|
||||||
|
public interface IRepository
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using CPATapi.Server.Models;
|
||||||
|
|
||||||
|
namespace CPATapi.Server.Interfaces;
|
||||||
|
|
||||||
|
public interface ITapiDirectoryRepository : IRepository
|
||||||
|
{
|
||||||
|
Task<IEnumerable<TapiContact>> SearchAsync(string[] args);
|
||||||
|
Task<TapiContact?> SearchByNumberAsync(string number);
|
||||||
|
Task<IEnumerable<TapiContact>> GetAllAsync();
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using CPATapi.Server.Models;
|
||||||
|
|
||||||
|
namespace CPATapi.Server.Interfaces;
|
||||||
|
|
||||||
|
public interface IZeitConsensRepository : IRepository
|
||||||
|
{
|
||||||
|
Task<IEnumerable<string>> GetUsersAsync();
|
||||||
|
Task<IEnumerable<Stamp>> GetStampsAsync(string user, DateTime from, DateTime to);
|
||||||
|
}
|
||||||
11
server/src/CPATapi.Server/Models/Availability.cs
Normal file
11
server/src/CPATapi.Server/Models/Availability.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace CPATapi.Server.Models;
|
||||||
|
|
||||||
|
public class Availability
|
||||||
|
{
|
||||||
|
[JsonPropertyName("user")]
|
||||||
|
public string User { get; set; }
|
||||||
|
[JsonPropertyName("loggedIn")]
|
||||||
|
public bool LoggedIn { get; set; }
|
||||||
|
}
|
||||||
7
server/src/CPATapi.Server/Models/Stamp.cs
Normal file
7
server/src/CPATapi.Server/Models/Stamp.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace CPATapi.Server.Models;
|
||||||
|
|
||||||
|
public class Stamp
|
||||||
|
{
|
||||||
|
public int MA_NR { get; set; }
|
||||||
|
public DateTime BU_BU { get; set; }
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
namespace CPATapi.Server.Models
|
namespace CPATapi.Server.Models;
|
||||||
{
|
|
||||||
public class TapiContact
|
public class TapiContact
|
||||||
{
|
{
|
||||||
public string TD_ID { get; set; }
|
public string TD_ID { get; set; }
|
||||||
@@ -8,4 +8,3 @@
|
|||||||
public string TD_NUMBER_TAPI { get; set; }
|
public string TD_NUMBER_TAPI { get; set; }
|
||||||
public string TD_MEDIUM { get; set; }
|
public string TD_MEDIUM { get; set; }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
|
using CPATapi.Server.Interfaces;
|
||||||
|
using CPATapi.Server.Repository;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
builder.Services.AddTransient<ITapiDirectoryRepository, TapiDirectoryRepository>();
|
||||||
|
builder.Services.AddTransient<IZeitConsensRepository, ZeitConsensRepository>();
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
@@ -13,4 +19,4 @@ app.UseAuthorization();
|
|||||||
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
app.Run();
|
await app.RunAsync();
|
||||||
|
|||||||
@@ -1,13 +1,4 @@
|
|||||||
{
|
{
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:62406",
|
|
||||||
"sslPort": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"IIS Express": {
|
"IIS Express": {
|
||||||
"commandName": "IISExpress",
|
"commandName": "IISExpress",
|
||||||
@@ -20,11 +11,30 @@
|
|||||||
"CPATapiServer": {
|
"CPATapiServer": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"launchUrl": "weatherforecast",
|
"launchUrl": "availability/users",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
},
|
},
|
||||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
"applicationUrl": "https://3cxtapi.cp-austria.at:5001;https://localhost:5001;http://localhost:5000"
|
||||||
|
},
|
||||||
|
"Container (Dockerfile)": {
|
||||||
|
"commandName": "Docker",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/contact",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_HTTP_PORTS": "8080"
|
||||||
|
},
|
||||||
|
"publishAllPorts": true,
|
||||||
|
"useSSL": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:62406",
|
||||||
|
"sslPort": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
21
server/src/CPATapi.Server/Repository/Repository.cs
Normal file
21
server/src/CPATapi.Server/Repository/Repository.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System.Data.Common;
|
||||||
|
using CPATapi.Server.Interfaces;
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
|
|
||||||
|
namespace CPATapi.Server.Repository;
|
||||||
|
|
||||||
|
public class Repository: IRepository
|
||||||
|
{
|
||||||
|
private readonly IConfiguration _config;
|
||||||
|
|
||||||
|
protected Repository(IConfiguration config)
|
||||||
|
{
|
||||||
|
_config = config;
|
||||||
|
}
|
||||||
|
protected async Task<DbConnection> OpenAsync(string name)
|
||||||
|
{
|
||||||
|
var db = new SqlConnection(_config.GetConnectionString(name));
|
||||||
|
await db.OpenAsync();
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
using System.Text;
|
||||||
|
using CPATapi.Server.Interfaces;
|
||||||
|
using CPATapi.Server.Models;
|
||||||
|
using Dapper;
|
||||||
|
|
||||||
|
namespace CPATapi.Server.Repository;
|
||||||
|
|
||||||
|
internal class TapiDirectoryRepository(IConfiguration config) : Repository(config), ITapiDirectoryRepository
|
||||||
|
{
|
||||||
|
public async Task<IEnumerable<TapiContact>> SearchAsync(string[] args)
|
||||||
|
{
|
||||||
|
await using var con = await OpenAsync("Tapi");
|
||||||
|
var sql = new StringBuilder("""
|
||||||
|
SELECT TOP 10
|
||||||
|
TD_ID,
|
||||||
|
TD_NAME,
|
||||||
|
TD_NUMBER,
|
||||||
|
TD_NUMBER_TAPI,
|
||||||
|
TD_MEDIUM
|
||||||
|
FROM dbo.CP_TAPI_DIRECTORY
|
||||||
|
WHERE
|
||||||
|
""");
|
||||||
|
var first = true;
|
||||||
|
var dp = new DynamicParameters();
|
||||||
|
for (var i = 1; i <= args.Length; i++)
|
||||||
|
{
|
||||||
|
if (!first)
|
||||||
|
{
|
||||||
|
sql.AppendLine("AND");
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
sql.AppendLine($"(TD_NAME LIKE @s{i} OR");
|
||||||
|
sql.AppendLine($" TD_NUMBER_TAPI LIKE @s{i})");
|
||||||
|
dp.Add($"s{i}", $"%{args[i-1]}%");
|
||||||
|
}
|
||||||
|
|
||||||
|
return await con.QueryAsync<TapiContact>(sql.ToString(), dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<TapiContact?> SearchByNumberAsync(string number)
|
||||||
|
{
|
||||||
|
await using var con = await OpenAsync("Tapi");
|
||||||
|
|
||||||
|
var result = await con.QueryFirstOrDefaultAsync<TapiContact>("""
|
||||||
|
SELECT
|
||||||
|
TD_ID
|
||||||
|
,TD_NAME
|
||||||
|
,TD_NUMBER
|
||||||
|
,TD_NUMBER_TAPI
|
||||||
|
,TD_MEDIUM
|
||||||
|
FROM dbo.CP_TAPI_DIRECTORY
|
||||||
|
WHERE TD_NUMBER_TAPI LIKE @number
|
||||||
|
""", new {number});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<TapiContact>> GetAllAsync()
|
||||||
|
{
|
||||||
|
await using var con = await OpenAsync("Tapi");
|
||||||
|
|
||||||
|
return await con.QueryAsync<TapiContact>("""
|
||||||
|
SELECT
|
||||||
|
TD_ID
|
||||||
|
,TD_NAME
|
||||||
|
,TD_NUMBER
|
||||||
|
,TD_NUMBER_TAPI
|
||||||
|
,TD_MEDIUM
|
||||||
|
FROM dbo.CP_TAPI_DIRECTORY
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using CPATapi.Server.Interfaces;
|
||||||
|
using CPATapi.Server.Models;
|
||||||
|
using Dapper;
|
||||||
|
|
||||||
|
namespace CPATapi.Server.Repository;
|
||||||
|
|
||||||
|
internal class ZeitConsensRepository(IConfiguration config) : Repository(config), IZeitConsensRepository
|
||||||
|
{
|
||||||
|
public async Task<IEnumerable<string>> GetUsersAsync()
|
||||||
|
{
|
||||||
|
await using var con = await OpenAsync("ZeitConsens");
|
||||||
|
return await con.QueryAsync<string>("""
|
||||||
|
SELECT DISTINCT MA_USER_NAME
|
||||||
|
FROM dbo.MA_DATEN
|
||||||
|
WHERE MA_USER_NAME IS NOT NULL AND MA_USER_AKTIV = 1
|
||||||
|
ORDER BY MA_USER_NAME
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<Stamp>> GetStampsAsync(string user, DateTime from, DateTime to)
|
||||||
|
{
|
||||||
|
await using var con = await OpenAsync("ZeitConsens");
|
||||||
|
return await con.QueryAsync<Stamp>("""
|
||||||
|
SELECT
|
||||||
|
MA_NR
|
||||||
|
,BU_BU
|
||||||
|
FROM dbo.BU
|
||||||
|
INNER JOIN dbo.MA_DATEN on MA_NR = BU_MA_NR
|
||||||
|
WHERE
|
||||||
|
MA_USER_NAME = @user AND
|
||||||
|
BU_BU >= @from AND BU_BU < @to
|
||||||
|
""", new { user, from, to });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
"Microsoft.Hosting.Lifetime": "Information"
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Db": {
|
"ConnectionStrings": {
|
||||||
"ConnectionString": "",
|
"Tapi": "",
|
||||||
"ConnectionStringZc": ""
|
"ZeitConsens": ""
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*"
|
"AllowedHosts": "*"
|
||||||
}
|
}
|
||||||
|
|||||||
19
server/src/CPATapi.Server/publish.bat
Normal file
19
server/src/CPATapi.Server/publish.bat
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
cd /d %~dp0
|
||||||
|
|
||||||
|
docker build -t source.cp-austria.at/cpatrd/3cx_tapi:latest -f Dockerfile ..
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo ERROR: Docker build failed!
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
SET /P AREYOUSURE=Publish to source.cp-austria.at? (Y/[N])
|
||||||
|
IF /I "%AREYOUSURE%" NEQ "Y" GOTO END
|
||||||
|
|
||||||
|
docker push source.cp-austria.at/cpatrd/3cx_tapi:latest
|
||||||
|
|
||||||
|
:END
|
||||||
|
endlocal
|
||||||
Reference in New Issue
Block a user