initial commit

This commit is contained in:
Frede Hundewadt 2023-06-12 10:26:01 +02:00
commit a3c59cf3c3
57 changed files with 2974 additions and 0 deletions

467
.gitignore vendored Normal file
View file

@ -0,0 +1,467 @@
appsettings.json
# ---> JetBrains
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# ---> VisualStudio
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Nuget personal access tokens and Credentials
nuget.config
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
.idea/
*.sln.iml

View file

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Entities\Entities.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,36 @@
// ***********************************************************************
// Assembly : Contracts
// Author : frede
// Created : 2023 06 10 14:20
//
// Last Modified By : frede
// Last Modified On : 2023 06 10 14:20
// ***********************************************************************
// <copyright file="ICompanyRepository.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Entities;
namespace Contracts;
public interface ICompanyRepository
{
IEnumerable<Company> GetAllCompanies(bool trackChanges);
Company GetCompany(Guid companyId, bool trackChanges);
}

View file

@ -0,0 +1,35 @@
// ***********************************************************************
// Assembly : Contracts
// Author : frede
// Created : 2023 06 11 10:30
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 10:30
// ***********************************************************************
// <copyright file="IEmployeeRepository.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Entities;
namespace Contracts;
public interface IEmployeeRepository
{
IEnumerable<Employee> GetEmployees(Guid companyId, bool trackChanges);
Employee GetEmployee(Guid companyId, Guid employeeId, bool trackChanges);
}

View file

@ -0,0 +1,35 @@
// ***********************************************************************
// Assembly : Contracts
// Author : frede
// Created : 2023 06 10 10:25
//
// Last Modified By : frede
// Last Modified On : 2023 06 10 10:25
// ***********************************************************************
// <copyright file="ILoggerManager.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Contracts;
public interface ILoggerManager
{
void LogInfo(string message);
void LogWarn(string message);
void LogDebug(string message);
void LogError(string message);
}

View file

@ -0,0 +1,42 @@
// ***********************************************************************
// Assembly : Contracts
// Author : frede
// Created : 2023 06 10 14:16
//
// Last Modified By : frede
// Last Modified On : 2023 06 10 14:16
// ***********************************************************************
// <copyright file="IRepositoryBase.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using System.Linq.Expressions;
namespace Contracts;
public interface IRepositoryBase<T>
{
IQueryable<T> FindAll(bool trackChanges);
IQueryable<T> FindByCondition(Expression<Func<T, bool>> expression, bool trackChanges);
void Create(T entity);
void Update(T entity);
void Delete(T entity);
}

View file

@ -0,0 +1,36 @@
// ***********************************************************************
// Assembly : Contracts
// Author : frede
// Created : 2023 06 11 08:31
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 10:50
// ***********************************************************************
// <copyright file="IRepositoryManager.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Contracts;
public interface IRepositoryManager
{
ICompanyRepository Company { get; }
IEmployeeRepository Employee { get; }
void Save();
}

48
Entities/Company.cs Normal file
View file

@ -0,0 +1,48 @@
// ***********************************************************************
// Assembly : Entities
// Author : frede
// Created : 2023 06 11 10:01
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 10:01
// ***********************************************************************
// <copyright file="Company.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Entities;
public class Company
{
[Key]
public Guid CompanyId { get; set; }
[Required(ErrorMessage = "Company name is a required field.")]
[MaxLength(60, ErrorMessage = "Maximum length for the Name is 60 characters.")]
public string? Name { get; set; }
[Required(ErrorMessage = "Company address is a required field.")]
[MaxLength(60, ErrorMessage = "Maximum length for the Address is 60 characters")]
public string? Address { get; set; }
public string? Country { get; set; }
public ICollection<Employee>? Employees { get; set; }
}

51
Entities/Employee.cs Normal file
View file

@ -0,0 +1,51 @@
// ***********************************************************************
// Assembly : Entities
// Author : frede
// Created : 2023 06 11 10:02
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 10:02
// ***********************************************************************
// <copyright file="Employee.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Entities;
public class Employee
{
[Key]
public Guid EmployeeId { get; set; }
[Required(ErrorMessage = "Employee name is a required field.")]
[MaxLength(30, ErrorMessage = "Maximum length for the Name is 30 characters.")]
public string? Name { get; set; }
[Required(ErrorMessage = "Age is a required field.")]
public int Age { get; set; }
[Required(ErrorMessage = "Position is a required field.")]
[MaxLength(20, ErrorMessage = "Maximum length for the Position is 20 characters.")]
public string? Position { get; set; }
[ForeignKey(nameof(Company))]
public Guid CompanyId { get; set; }
public Company? Company { get; set; }
}

17
Entities/Entities.csproj Normal file
View file

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
</ItemGroup>
<ItemGroup>
<Folder Include="ErrorModel\" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,36 @@
// ***********************************************************************
// Assembly : Entities
// Author : frede
// Created : 2023 06 11 14:33
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 14:33
// ***********************************************************************
// <copyright file="ErrorDetails.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using System.Text.Json;
namespace Entities.ErrorModel;
public class ErrorDetails
{
public int StatusCode { get; set; }
public string Message { get; set; } = "";
public override string ToString() => JsonSerializer.Serialize(this);
}

View file

@ -0,0 +1,34 @@
// ***********************************************************************
// Assembly : Entities
// Author : frede
// Created : 2023 06 11 14:58
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 14:58
// ***********************************************************************
// <copyright file="CompanyNotFoundException.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Entities.Exceptions;
public class CompanyNotFoundException : NotFoundException
{
public CompanyNotFoundException(Guid companyId) : base($"The company with id {companyId} vas not found.")
{
}
}

View file

@ -0,0 +1,35 @@
// ***********************************************************************
// Assembly : Entities
// Author : frede
// Created : 2023 06 11 15:33
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 15:33
// ***********************************************************************
// <copyright file="EmployeeNotFoundException.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Entities.Exceptions;
public class EmployeeNotFoundException : NotFoundException
{
public EmployeeNotFoundException(Guid employeeId)
: base($"Employee with id: {employeeId} doesn't exist in the database.")
{
}
}

View file

@ -0,0 +1,34 @@
// ***********************************************************************
// Assembly : Entities
// Author : frede
// Created : 2023 06 11 14:57
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 14:57
// ***********************************************************************
// <copyright file="NotFoundException.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Entities.Exceptions;
public abstract class NotFoundException : Exception
{
protected NotFoundException(string message) : base(message)
{
}
}

View file

@ -0,0 +1,44 @@
// ***********************************************************************
// Assembly : LoggerService
// Author : frede
// Created : 2023 06 10 10:27
//
// Last Modified By : frede
// Last Modified On : 2023 06 10 10:27
// ***********************************************************************
// <copyright file="LoggerManager.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Contracts;
using NLog;
namespace LoggerService;
public class LoggerManager :ILoggerManager
{
private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
public LoggerManager()
{
}
public void LogDebug(string message) => logger.Debug(message);
public void LogError(string message) => logger.Error(message);
public void LogInfo(string message) => logger.Info(message);
public void LogWarn(string message) => logger.Warn(message);
}

View file

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NLog" Version="5.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,47 @@
// ***********************************************************************
// Assembly : Repository
// Author : frede
// Created : 2023 06 10 15:06
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 10:50
// ***********************************************************************
// <copyright file="CompanyRepository.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Contracts;
using Entities;
namespace Repository;
internal class CompanyRepository : RepositoryBase<Company>, ICompanyRepository
{
public CompanyRepository(RepositoryContext repositoryContext) : base(repositoryContext)
{
}
public IEnumerable<Company> GetAllCompanies(bool trackChanges)
{
return FindAll(trackChanges).OrderBy(c => c.Name).ToList();
}
public Company GetCompany(Guid companyId, bool trackChanges)
{
return FindByCondition(c => c.CompanyId.Equals(companyId), trackChanges).SingleOrDefault();
}
}

View file

@ -0,0 +1,55 @@
// ***********************************************************************
// Assembly : Repository
// Author : frede
// Created : 2023 06 11 09:54
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 09:54
// ***********************************************************************
// <copyright file="CompanyConfiguration.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Repository.Configuration;
public class CompanyConfiguration : IEntityTypeConfiguration<Company>
{
public void Configure(EntityTypeBuilder<Company> builder)
{
builder.HasData
(
new Company
{
CompanyId = new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"),
Name = "IT_Solutions Ltd",
Address = "583 Wall Dr. Gwynn Oak, MD 21207",
Country = "USA"
},
new Company
{
CompanyId = new Guid("56785678-aaaa-eeee-eeee-aaaabbbbcccc"),
Name = "Admin_Solutions Ltd",
Address = "312 Forest Avenue, BF 923",
Country = "USA"
}
);
}
}

View file

@ -0,0 +1,65 @@
// ***********************************************************************
// Assembly : Repository
// Author : frede
// Created : 2023 06 11 10:00
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 10:00
// ***********************************************************************
// <copyright file="EmployeeConfiguration.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Repository.Configuration;
public class EmployeeConfiguration : IEntityTypeConfiguration<Employee>
{
public void Configure(EntityTypeBuilder<Employee> builder)
{
builder.HasData
(
new Employee
{
EmployeeId = new Guid("12341234-1111-eeee-eeee-aaaabbbbcccc"),
Name = "Sam Raiden",
Age = 26,
Position = "Software developer",
CompanyId = new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc")
},
new Employee
{
EmployeeId = new Guid("12341234-2222-eeee-eeee-aaaabbbbcccc"),
Name = "Jana McLeaf",
Age = 30,
Position = "Software developer",
CompanyId = new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc")
},
new Employee
{
EmployeeId = new Guid("56785678-1111-eeee-eeee-aaaabbbbcccc"),
Name = "Kane Miller",
Age = 35,
Position = "Administrator",
CompanyId = new Guid("56785678-aaaa-eeee-eeee-aaaabbbbcccc")
}
);
}
}

View file

@ -0,0 +1,46 @@
// ***********************************************************************
// Assembly : Repository
// Author : frede
// Created : 2023 06 11 10:31
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 10:31
// ***********************************************************************
// <copyright file="EmployeeRepository.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Contracts;
using Entities;
namespace Repository;
public class EmployeeRepository : RepositoryBase<Employee>, IEmployeeRepository
{
public EmployeeRepository(RepositoryContext repositoryContext) : base(repositoryContext)
{
}
public IEnumerable<Employee> GetEmployees(Guid companyId, bool trackChanges) =>
FindByCondition(e => e.CompanyId.Equals(companyId), trackChanges)
.OrderBy(e => e.Name)
.ToList();
public Employee GetEmployee(Guid companyId, Guid employeeId, bool trackChanges) =>
FindByCondition(e => e.CompanyId.Equals(companyId) && e.EmployeeId.Equals(employeeId), trackChanges)
.SingleOrDefault();
}

View file

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\Entities\Entities.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Configuration\" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,62 @@
// ***********************************************************************
// Assembly : Repository
// Author : frede
// Created : 2023 06 10 14:18
//
// Last Modified By : frede
// Last Modified On : 2023 06 10 14:18
// ***********************************************************************
// <copyright file="RepositoryBase.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using System.Linq.Expressions;
using Contracts;
using Microsoft.EntityFrameworkCore;
namespace Repository;
public abstract class RepositoryBase<T> : IRepositoryBase<T> where T : class
{
protected RepositoryContext RepositoryContext;
protected RepositoryBase(RepositoryContext repositoryContext)
=> RepositoryContext = repositoryContext;
public IQueryable<T> FindAll(bool trackChanges) =>
!trackChanges ?
RepositoryContext.Set<T>().AsNoTracking() :
RepositoryContext.Set<T>();
public IQueryable<T> FindByCondition(Expression<Func<T, bool>> expression, bool trackChanges) =>
!trackChanges ?
RepositoryContext.Set<T>() .Where(expression) .AsNoTracking() :
RepositoryContext.Set<T>() .Where(expression);
public void Create(T entity) => RepositoryContext.Set<T>().Add(entity);
public void Update(T entity) => RepositoryContext.Set<T>().Update(entity);
public void Delete(T entity) => RepositoryContext.Set<T>().Remove(entity);
}

View file

@ -0,0 +1,49 @@
// ***********************************************************************
// Assembly : Repository
// Author : frede
// Created : 2023 06 10 10:50
//
// Last Modified By : frede
// Last Modified On : 2023 06 10 10:50
// ***********************************************************************
// <copyright file="RepositoryContext.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Entities;
using Microsoft.EntityFrameworkCore;
using Repository.Configuration;
namespace Repository;
public class RepositoryContext : DbContext
{
public RepositoryContext(DbContextOptions options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new CompanyConfiguration());
modelBuilder.ApplyConfiguration(new EmployeeConfiguration());
}
public DbSet<Company>? Companies { get; set; }
public DbSet<Employee>? Employees { get; set; }
}

View file

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Contracts;
namespace Repository
{
public sealed class RepositoryManager : IRepositoryManager
{
private readonly RepositoryContext _repositoryContext;
private readonly Lazy<ICompanyRepository> _companyRepository;
private readonly Lazy<IEmployeeRepository> _employeeRepository;
public RepositoryManager(RepositoryContext repositoryContext)
{
_repositoryContext = repositoryContext;
_companyRepository = new Lazy<ICompanyRepository>(() => new CompanyRepository(repositoryContext));
_employeeRepository = new Lazy<IEmployeeRepository>(() => new EmployeeRepository(repositoryContext));
}
public ICompanyRepository Company => _companyRepository.Value;
public IEmployeeRepository Employee => _employeeRepository.Value;
public void Save() => _repositoryContext.SaveChanges();
}
}

View file

@ -0,0 +1,36 @@
// ***********************************************************************
// Assembly : Service.Contracts
// Author : frede
// Created : 2023 06 11 08:42
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 08:42
// ***********************************************************************
// <copyright file="IServiceManager.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Shared.DataTransferObjects;
namespace Service.Contracts
{
public interface ICompanyService
{
IEnumerable<CompanyDto> GetAllCompanies(bool trackChanges);
CompanyDto GetCompany(Guid companyId, bool trackChanges);
}
}

View file

@ -0,0 +1,35 @@
// ***********************************************************************
// Assembly : Service.Contracts
// Author : frede
// Created : 2023 06 11 10:39
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 10:39
// ***********************************************************************
// <copyright file="IEmployeeService.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Shared.DataTransferObjects;
namespace Service.Contracts;
public interface IEmployeeService
{
IEnumerable<EmployeeDto> GetEmployees(Guid companyId, bool trackChanges);
EmployeeDto GetEmployee(Guid companyId, Guid employeeId, bool trackChanges);
}

View file

@ -0,0 +1,33 @@
// ***********************************************************************
// Assembly : Service.Contracts
// Author : frede
// Created : 2023 06 11 08:42
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 08:42
// ***********************************************************************
// <copyright file="IServiceManager.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Service.Contracts;
public interface IServiceManager
{
ICompanyService CompanyService { get; }
IEmployeeService EmployeeService { get; }
}

View file

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
</Project>

66
Service/CompanyService.cs Normal file
View file

@ -0,0 +1,66 @@
// ***********************************************************************
// Assembly : Service
// Author : frede
// Created : 2023 06 11 08:44
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 08:44
// ***********************************************************************
// <copyright file="CompanyService.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using AutoMapper;
using Contracts;
using Entities.Exceptions;
using Service.Contracts;
using Shared.DataTransferObjects;
namespace Service;
internal sealed class CompanyService : ICompanyService
{
private readonly IRepositoryManager _repository;
private readonly ILoggerManager _logger;
private readonly IMapper _mapper;
public CompanyService(IRepositoryManager repository, ILoggerManager logger, IMapper mapper)
{
_repository = repository;
_logger = logger;
_mapper = mapper;
}
public IEnumerable<CompanyDto> GetAllCompanies(bool trackChanges)
{
var companies = _repository.Company.GetAllCompanies(trackChanges);
var companiesDto = _mapper.Map<IEnumerable<CompanyDto>>(companies);
return companiesDto;
}
public CompanyDto GetCompany(Guid companyId, bool trackChanges)
{
var company = _repository.Company.GetCompany(companyId, trackChanges);
if (company == null) throw new CompanyNotFoundException(companyId);
var companyDto = _mapper.Map<CompanyDto>(company);
return companyDto;
}
}

View file

@ -0,0 +1,77 @@
// ***********************************************************************
// Assembly : Service
// Author : frede
// Created : 2023 06 11 10:40
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 10:40
// ***********************************************************************
// <copyright file="EmployeeService.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using AutoMapper;
using Contracts;
using Entities.Exceptions;
using Service.Contracts;
using Shared.DataTransferObjects;
namespace Service;
internal sealed class EmployeeService : IEmployeeService
{
public readonly IRepositoryManager _repository;
public readonly ILoggerManager _logger;
public readonly IMapper _mapper;
public EmployeeService(IRepositoryManager repository, ILoggerManager logger, IMapper mapper)
{
_repository = repository;
_logger = logger;
_mapper = mapper;
}
public IEnumerable<EmployeeDto> GetEmployees(Guid companyId, bool trackChanges)
{
var company = _repository.Company.GetCompany(companyId, trackChanges);
if (company == null)
{
throw new CompanyNotFoundException(companyId);
}
var employeesFromDb = _repository.Employee.GetEmployees(companyId, trackChanges);
var employeesDto = _mapper.Map<IEnumerable<EmployeeDto>>(employeesFromDb);
return employeesDto;
}
public EmployeeDto GetEmployee(Guid companyId, Guid employeeId, bool trackChanges)
{
var company = _repository.Company.GetCompany(companyId, trackChanges);
if (company == null)
{
throw new CompanyNotFoundException(companyId);
}
var employeeDb = _repository.Employee.GetEmployee(companyId, employeeId, trackChanges);
if (employeeDb == null)
{
throw new EmployeeNotFoundException(employeeId);
}
var employee = _mapper.Map<EmployeeDto>(employeeDb);
return employee;
}
}

18
Service/Service.csproj Normal file
View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\Service.Contracts\Service.Contracts.csproj" />
</ItemGroup>
</Project>

46
Service/ServiceManager.cs Normal file
View file

@ -0,0 +1,46 @@
// ***********************************************************************
// Assembly : Service
// Author : frede
// Created : 2023 06 11 08:46
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 08:46
// ***********************************************************************
// <copyright file="ServiceManager.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using AutoMapper;
using Contracts;
using Service.Contracts;
namespace Service;
public sealed class ServiceManager : IServiceManager
{
private readonly Lazy<ICompanyService> _companyService;
private readonly Lazy<IEmployeeService> _employeeService;
public ServiceManager(IRepositoryManager repositoryManager, ILoggerManager logger, IMapper mapper)
{
_companyService = new Lazy<ICompanyService>(() => new CompanyService(repositoryManager, logger, mapper));
_employeeService = new Lazy<IEmployeeService>(() => new EmployeeService(repositoryManager, logger, mapper));
}
public ICompanyService CompanyService => _companyService.Value;
public IEmployeeService EmployeeService => _employeeService.Value;
}

View file

@ -0,0 +1,35 @@
// ***********************************************************************
// Assembly : Shared
// Author : frede
// Created : 2023 06 11 12:44
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 12:44
// ***********************************************************************
// <copyright file="CompanyDto.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Shared.DataTransferObjects
{
public record CompanyDto
{
public Guid CompanyId { get; init; }
public string Name { get; init; } = "";
public string FullAddress { get; init; } = "";
};
}

View file

@ -0,0 +1,29 @@
// ***********************************************************************
// Assembly : Shared
// Author : frede
// Created : 2023 06 11 16:21
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 16:21
// ***********************************************************************
// <copyright file="CompanyCreateDto.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Shared.DataTransferObjects;
public record CompanyInputDto(string Name, string Address, string Country);

View file

@ -0,0 +1,29 @@
// ***********************************************************************
// Assembly : Shared
// Author : frede
// Created : 2023 06 11 16:40
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 16:40
// ***********************************************************************
// <copyright file="EmployeeInputDto.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Shared.DataTransferObjects;
public record EmployeeInputDto();

View file

@ -0,0 +1,35 @@
// ***********************************************************************
// Assembly : Shared
// Author : frede
// Created : 2023 06 11 15:20
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 15:20
// ***********************************************************************
// <copyright file="EmployeeDto.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Shared.DataTransferObjects;
public record EmployeeDto
{
public Guid EmployeeId { get; init; }
public string Name { get; init; } = "";
public int Age { get; init; }
public string Position { get; init; } = "";
}

9
Shared/Shared.csproj Normal file
View file

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,32 @@
// ***********************************************************************
// Assembly : Ultimate.Presentation
// Author : frede
// Created : 2023 06 11 12:15
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 12:15
// ***********************************************************************
// <copyright file="AssemblyReference.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
namespace Ultimate.Presentation;
public class AssemblyReference
{
}

View file

@ -0,0 +1,33 @@

using Microsoft.AspNetCore.Mvc;
using Service.Contracts;
namespace Ultimate.Presentation.Controllers
{
[Route("api/v3/companies")]
public class CompaniesController : ControllerBase
{
private readonly IServiceManager _service;
public CompaniesController(IServiceManager service)
{
_service = service;
}
[HttpGet]
public IActionResult GetCompanies()
{
var companies = _service.CompanyService.GetAllCompanies(trackChanges: false);
return Ok(companies);
}
[HttpGet("{id:guid}")]
public IActionResult GetCompany(Guid id) {
{
var company = _service.CompanyService.GetCompany(id, trackChanges: false);
return Ok(company);
}}
}
}

View file

@ -0,0 +1,55 @@
// ***********************************************************************
// Assembly : Ultimate.Presentation
// Author : frede
// Created : 2023 06 11 15:25
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 15:25
// ***********************************************************************
// <copyright file="EmployeesController.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Microsoft.AspNetCore.Mvc;
using Service.Contracts;
namespace Ultimate.Presentation.Controllers;
[Route("api/v3/companies/{companyId}/employees")]
public class EmployeesController : ControllerBase
{
private readonly IServiceManager _service;
public EmployeesController(IServiceManager service)
{
_service = service;
}
[HttpGet]
public IActionResult GetEmployeesForCompany(Guid companyId)
{
var employees = _service.EmployeeService.GetEmployees(companyId, trackChanges: false);
return Ok(employees);
}
[HttpGet("{employeeId:guid}")]
public IActionResult GetEmployeeForCompany(Guid companyId, Guid employeeId)
{
var employee = _service.EmployeeService.GetEmployee(companyId, employeeId, trackChanges: false);
return Ok(employee);
}
}

View file

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Service.Contracts\Service.Contracts.csproj" />
</ItemGroup>
</Project>

73
Ultimate.sln Normal file
View file

@ -0,0 +1,73 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.6.33723.286
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ultimate", "Ultimate\Ultimate.csproj", "{838294FF-34F8-4EFB-9E21-8F55C0AF8AFC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contracts", "Contracts\Contracts.csproj", "{3B7E1C6A-CAB2-434B-A42C-A1CBDA709623}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggerService", "LoggerService\LoggerService.csproj", "{FAFD41C0-1E2E-4FB7-BBB7-3332E736E008}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Entities", "Entities\Entities.csproj", "{64621CAB-A8BA-4C27-928E-891EB10ABBBA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Repository", "Repository\Repository.csproj", "{238995A6-3F97-4C2E-85DD-589E1C7C2A80}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Service.Contracts", "Service.Contracts\Service.Contracts.csproj", "{78FA267B-3CA5-4A6F-B1A5-6AD05D37F7A6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Service", "Service\Service.csproj", "{55E22590-4906-4BA0-9DE7-9F41FAE21301}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ultimate.Presentation", "Ultimate.Presentation\Ultimate.Presentation.csproj", "{AA7CCE8B-4F6A-485A-A113-3013FC22153E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{93203459-4B7A-49CB-B9F2-FDBF667F75FE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{838294FF-34F8-4EFB-9E21-8F55C0AF8AFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{838294FF-34F8-4EFB-9E21-8F55C0AF8AFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{838294FF-34F8-4EFB-9E21-8F55C0AF8AFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{838294FF-34F8-4EFB-9E21-8F55C0AF8AFC}.Release|Any CPU.Build.0 = Release|Any CPU
{3B7E1C6A-CAB2-434B-A42C-A1CBDA709623}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B7E1C6A-CAB2-434B-A42C-A1CBDA709623}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B7E1C6A-CAB2-434B-A42C-A1CBDA709623}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B7E1C6A-CAB2-434B-A42C-A1CBDA709623}.Release|Any CPU.Build.0 = Release|Any CPU
{FAFD41C0-1E2E-4FB7-BBB7-3332E736E008}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FAFD41C0-1E2E-4FB7-BBB7-3332E736E008}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FAFD41C0-1E2E-4FB7-BBB7-3332E736E008}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FAFD41C0-1E2E-4FB7-BBB7-3332E736E008}.Release|Any CPU.Build.0 = Release|Any CPU
{64621CAB-A8BA-4C27-928E-891EB10ABBBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64621CAB-A8BA-4C27-928E-891EB10ABBBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64621CAB-A8BA-4C27-928E-891EB10ABBBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64621CAB-A8BA-4C27-928E-891EB10ABBBA}.Release|Any CPU.Build.0 = Release|Any CPU
{238995A6-3F97-4C2E-85DD-589E1C7C2A80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{238995A6-3F97-4C2E-85DD-589E1C7C2A80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{238995A6-3F97-4C2E-85DD-589E1C7C2A80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{238995A6-3F97-4C2E-85DD-589E1C7C2A80}.Release|Any CPU.Build.0 = Release|Any CPU
{78FA267B-3CA5-4A6F-B1A5-6AD05D37F7A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{78FA267B-3CA5-4A6F-B1A5-6AD05D37F7A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{78FA267B-3CA5-4A6F-B1A5-6AD05D37F7A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{78FA267B-3CA5-4A6F-B1A5-6AD05D37F7A6}.Release|Any CPU.Build.0 = Release|Any CPU
{55E22590-4906-4BA0-9DE7-9F41FAE21301}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55E22590-4906-4BA0-9DE7-9F41FAE21301}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55E22590-4906-4BA0-9DE7-9F41FAE21301}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55E22590-4906-4BA0-9DE7-9F41FAE21301}.Release|Any CPU.Build.0 = Release|Any CPU
{AA7CCE8B-4F6A-485A-A113-3013FC22153E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA7CCE8B-4F6A-485A-A113-3013FC22153E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA7CCE8B-4F6A-485A-A113-3013FC22153E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA7CCE8B-4F6A-485A-A113-3013FC22153E}.Release|Any CPU.Build.0 = Release|Any CPU
{93203459-4B7A-49CB-B9F2-FDBF667F75FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93203459-4B7A-49CB-B9F2-FDBF667F75FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93203459-4B7A-49CB-B9F2-FDBF667F75FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93203459-4B7A-49CB-B9F2-FDBF667F75FE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D0DCD307-1473-4B0C-8922-D815E802709B}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,50 @@
// ***********************************************************************
// Assembly : Ultimate1
// Author : frede
// Created : 2023 06 10 10:59
//
// Last Modified By : frede
// Last Modified On : 2023 06 10 10:59
// ***********************************************************************
// <copyright file="RepositoryContextFactory.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Repository;
namespace Ultimate.ContextFactory;
public class RepositoryContextFactory : IDesignTimeDbContextFactory<RepositoryContext>
{
public RepositoryContext CreateDbContext(string[] args)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var builder = new DbContextOptionsBuilder<RepositoryContext>()
.UseMySql(
configuration.GetConnectionString("mysqlCrmData")!,
new MariaDbServerVersion(configuration.GetValue("MariaDbServerVersion", "11.0.2")),
b => b.MigrationsAssembly(nameof(Ultimate)));
return new RepositoryContext(builder.Options);
}
}

View file

@ -0,0 +1,75 @@
// ***********************************************************************
// Assembly : Ultimate
// Author : frede
// Created : 2023 06 11 15:57
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 15:57
// ***********************************************************************
// <copyright file="CsvOutputFormatter.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using System.Text;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Net.Http.Headers;
using Shared.DataTransferObjects;
namespace Ultimate;
public class CsvOutputFormatter : TextOutputFormatter
{
public CsvOutputFormatter()
{
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/csv"));
SupportedEncodings.Add(Encoding.UTF8);
SupportedEncodings.Add(Encoding.Unicode);
}
protected override bool CanWriteType(Type? type)
{
if (typeof(CompanyDto).IsAssignableFrom(type) || typeof(IEnumerable<CompanyDto>).IsAssignableFrom(type))
{
return base.CanWriteType(type);
}
return false;
}
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
var response = context.HttpContext.Response;
var buffer = new StringBuilder();
if (context.Object is IEnumerable<CompanyDto>)
{
foreach (var company in (IEnumerable<CompanyDto>) context.Object)
{
FormatCsv(buffer, company);
}
}
else
{
FormatCsv(buffer, (CompanyDto) context.Object);
}
await response.WriteAsync(buffer.ToString());
}
private static void FormatCsv(StringBuilder buffer, CompanyDto company)
{
buffer.AppendLine($"{company.CompanyId},\"{company.Name}\",\"{company.FullAddress}\"");
}
}

View file

@ -0,0 +1,64 @@
// ***********************************************************************
// Assembly : Ultimate
// Author : frede
// Created : 2023 06 11 14:22
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 14:22
// ***********************************************************************
// <copyright file="ExceptionMiddlewareExtensions.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using System.Net;
using Contracts;
using Entities.ErrorModel;
using Entities.Exceptions;
using Microsoft.AspNetCore.Diagnostics;
namespace Ultimate.Extensions;
public static class ExceptionMiddlewareExtensions
{
public static void ConfigureExceptionHandler(this WebApplication app, ILoggerManager logger)
{
app.UseExceptionHandler(appError =>
{
appError.Run(async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.ContentType = "application/json";
var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
if (contextFeature != null)
{
context.Response.StatusCode = contextFeature.Error switch
{
NotFoundException => StatusCodes.Status404NotFound,
_ => StatusCodes.Status500InternalServerError
};
logger.LogError($"Exception occurred: {contextFeature.Error}");
await context.Response.WriteAsync(new ErrorDetails
{
StatusCode = context.Response.StatusCode,
Message = contextFeature.Error.Message
}.ToString());
}
});
});
}
}

View file

@ -0,0 +1,70 @@
// ***********************************************************************
// Assembly : Ultimate1
// Author : frede
// Created : 2023 06 10 10:03
//
// Last Modified By : frede
// Last Modified On : 2023 06 10 10:03
// ***********************************************************************
// <copyright file="ServiceExtensions.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using Contracts;
using LoggerService;
using Microsoft.EntityFrameworkCore;
using Repository;
using Service;
using Service.Contracts;
namespace Ultimate.Extensions;
public static class ServiceExtensions
{
public static void ConfigureCors(this IServiceCollection services) =>
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder =>
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
}
);
public static void ConfigureIisIntegration(this IServiceCollection services) =>
services.Configure<IISOptions>(options => { });
public static void ConfigureLoggerService(this IServiceCollection services) =>
services.AddSingleton<ILoggerManager, LoggerManager>();
public static void ConfigureRepositoryManager(this IServiceCollection services) =>
services.AddScoped<IRepositoryManager, RepositoryManager>();
public static void ConfigureServiceManager(this IServiceCollection services) =>
services.AddScoped<IServiceManager, ServiceManager>();
public static void ConfigureSqlContext(this IServiceCollection services, IConfiguration configuration) =>
services.AddDbContext<RepositoryContext>(options =>
options.UseMySql(
configuration.GetConnectionString("mysqlCrmData"),
new MariaDbServerVersion(configuration.GetValue("MariaDbVersion", "11.0.2")))
);
public static IMvcBuilder AddCustomCsvFormatter(this IMvcBuilder builder) =>
builder.AddMvcOptions(config =>
config.OutputFormatters.Add(new CsvOutputFormatter()));
}

View file

@ -0,0 +1,42 @@
// ***********************************************************************
// Assembly : Ultimate
// Author : frede
// Created : 2023 06 11 12:58
//
// Last Modified By : frede
// Last Modified On : 2023 06 11 12:58
// ***********************************************************************
// <copyright file="MappingProfile.cs" company="FCS">
// Copyright (C) 2023-2023 FCS Frede's Computer Services.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see [https://www.gnu.org/licenses]
// </copyright>
// <summary></summary>
// ***********************************************************************
using AutoMapper;
using Entities;
using Shared.DataTransferObjects;
namespace Ultimate;
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Company, CompanyDto>().ForMember(c => c.FullAddress, opt =>
opt.MapFrom(x => string.Join(' ', x.Address, x.Country)));
CreateMap<Employee, EmployeeDto>();
}
}

View file

@ -0,0 +1,96 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Repository;
#nullable disable
namespace Ultimate.Migrations
{
[DbContext(typeof(RepositoryContext))]
[Migration("20230611100310_DatabaseCreate")]
partial class DatabaseCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Entities.Company", b =>
{
b.Property<Guid>("CompanyId")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Address")
.IsRequired()
.HasMaxLength(60)
.HasColumnType("varchar(60)");
b.Property<string>("Country")
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(60)
.HasColumnType("varchar(60)");
b.HasKey("CompanyId");
b.ToTable("Companies");
});
modelBuilder.Entity("Entities.Employee", b =>
{
b.Property<Guid>("EmployeeId")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<int>("Age")
.HasColumnType("int");
b.Property<Guid>("CompanyId")
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<string>("Position")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("varchar(20)");
b.HasKey("EmployeeId");
b.HasIndex("CompanyId");
b.ToTable("Employees");
});
modelBuilder.Entity("Entities.Employee", b =>
{
b.HasOne("Entities.Company", "Company")
.WithMany("Employees")
.HasForeignKey("CompanyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Company");
});
modelBuilder.Entity("Entities.Company", b =>
{
b.Navigation("Employees");
});
#pragma warning restore 612, 618
}
}
}

View file

@ -0,0 +1,75 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Ultimate.Migrations
{
/// <inheritdoc />
public partial class DatabaseCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "Companies",
columns: table => new
{
CompanyId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "varchar(60)", maxLength: 60, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Address = table.Column<string>(type: "varchar(60)", maxLength: 60, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Country = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_Companies", x => x.CompanyId);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "Employees",
columns: table => new
{
EmployeeId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "varchar(30)", maxLength: 30, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Age = table.Column<int>(type: "int", nullable: false),
Position = table.Column<string>(type: "varchar(20)", maxLength: 20, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CompanyId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_Employees", x => x.EmployeeId);
table.ForeignKey(
name: "FK_Employees_Companies_CompanyId",
column: x => x.CompanyId,
principalTable: "Companies",
principalColumn: "CompanyId",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_Employees_CompanyId",
table: "Employees",
column: "CompanyId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Employees");
migrationBuilder.DropTable(
name: "Companies");
}
}
}

View file

@ -0,0 +1,138 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Repository;
#nullable disable
namespace Ultimate.Migrations
{
[DbContext(typeof(RepositoryContext))]
[Migration("20230611104028_SeedTestData")]
partial class SeedTestData
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Entities.Company", b =>
{
b.Property<Guid>("CompanyId")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Address")
.IsRequired()
.HasMaxLength(60)
.HasColumnType("varchar(60)");
b.Property<string>("Country")
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(60)
.HasColumnType("varchar(60)");
b.HasKey("CompanyId");
b.ToTable("Companies");
b.HasData(
new
{
CompanyId = new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"),
Address = "583 Wall Dr. Gwynn Oak, MD 21207",
Country = "USA",
Name = "IT_Solutions Ltd"
},
new
{
CompanyId = new Guid("56785678-aaaa-eeee-eeee-aaaabbbbcccc"),
Address = "312 Forest Avenue, BF 923",
Country = "USA",
Name = "Admin_Solutions Ltd"
});
});
modelBuilder.Entity("Entities.Employee", b =>
{
b.Property<Guid>("EmployeeId")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<int>("Age")
.HasColumnType("int");
b.Property<Guid>("CompanyId")
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<string>("Position")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("varchar(20)");
b.HasKey("EmployeeId");
b.HasIndex("CompanyId");
b.ToTable("Employees");
b.HasData(
new
{
EmployeeId = new Guid("12341234-1111-eeee-eeee-aaaabbbbcccc"),
Age = 26,
CompanyId = new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"),
Name = "Sam Raiden",
Position = "Software developer"
},
new
{
EmployeeId = new Guid("12341234-2222-eeee-eeee-aaaabbbbcccc"),
Age = 30,
CompanyId = new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"),
Name = "Jana McLeaf",
Position = "Software developer"
},
new
{
EmployeeId = new Guid("56785678-1111-eeee-eeee-aaaabbbbcccc"),
Age = 35,
CompanyId = new Guid("56785678-aaaa-eeee-eeee-aaaabbbbcccc"),
Name = "Kane Miller",
Position = "Administrator"
});
});
modelBuilder.Entity("Entities.Employee", b =>
{
b.HasOne("Entities.Company", "Company")
.WithMany("Employees")
.HasForeignKey("CompanyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Company");
});
modelBuilder.Entity("Entities.Company", b =>
{
b.Navigation("Employees");
});
#pragma warning restore 612, 618
}
}
}

View file

@ -0,0 +1,65 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
namespace Ultimate.Migrations
{
/// <inheritdoc />
public partial class SeedTestData : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.InsertData(
table: "Companies",
columns: new[] { "CompanyId", "Address", "Country", "Name" },
values: new object[,]
{
{ new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"), "583 Wall Dr. Gwynn Oak, MD 21207", "USA", "IT_Solutions Ltd" },
{ new Guid("56785678-aaaa-eeee-eeee-aaaabbbbcccc"), "312 Forest Avenue, BF 923", "USA", "Admin_Solutions Ltd" }
});
migrationBuilder.InsertData(
table: "Employees",
columns: new[] { "EmployeeId", "Age", "CompanyId", "Name", "Position" },
values: new object[,]
{
{ new Guid("12341234-1111-eeee-eeee-aaaabbbbcccc"), 26, new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"), "Sam Raiden", "Software developer" },
{ new Guid("12341234-2222-eeee-eeee-aaaabbbbcccc"), 30, new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"), "Jana McLeaf", "Software developer" },
{ new Guid("56785678-1111-eeee-eeee-aaaabbbbcccc"), 35, new Guid("56785678-aaaa-eeee-eeee-aaaabbbbcccc"), "Kane Miller", "Administrator" }
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "Employees",
keyColumn: "EmployeeId",
keyValue: new Guid("12341234-1111-eeee-eeee-aaaabbbbcccc"));
migrationBuilder.DeleteData(
table: "Employees",
keyColumn: "EmployeeId",
keyValue: new Guid("12341234-2222-eeee-eeee-aaaabbbbcccc"));
migrationBuilder.DeleteData(
table: "Employees",
keyColumn: "EmployeeId",
keyValue: new Guid("56785678-1111-eeee-eeee-aaaabbbbcccc"));
migrationBuilder.DeleteData(
table: "Companies",
keyColumn: "CompanyId",
keyValue: new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"));
migrationBuilder.DeleteData(
table: "Companies",
keyColumn: "CompanyId",
keyValue: new Guid("56785678-aaaa-eeee-eeee-aaaabbbbcccc"));
}
}
}

View file

@ -0,0 +1,135 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Repository;
#nullable disable
namespace Ultimate.Migrations
{
[DbContext(typeof(RepositoryContext))]
partial class RepositoryContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Entities.Company", b =>
{
b.Property<Guid>("CompanyId")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Address")
.IsRequired()
.HasMaxLength(60)
.HasColumnType("varchar(60)");
b.Property<string>("Country")
.HasColumnType("longtext");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(60)
.HasColumnType("varchar(60)");
b.HasKey("CompanyId");
b.ToTable("Companies");
b.HasData(
new
{
CompanyId = new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"),
Address = "583 Wall Dr. Gwynn Oak, MD 21207",
Country = "USA",
Name = "IT_Solutions Ltd"
},
new
{
CompanyId = new Guid("56785678-aaaa-eeee-eeee-aaaabbbbcccc"),
Address = "312 Forest Avenue, BF 923",
Country = "USA",
Name = "Admin_Solutions Ltd"
});
});
modelBuilder.Entity("Entities.Employee", b =>
{
b.Property<Guid>("EmployeeId")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<int>("Age")
.HasColumnType("int");
b.Property<Guid>("CompanyId")
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<string>("Position")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("varchar(20)");
b.HasKey("EmployeeId");
b.HasIndex("CompanyId");
b.ToTable("Employees");
b.HasData(
new
{
EmployeeId = new Guid("12341234-1111-eeee-eeee-aaaabbbbcccc"),
Age = 26,
CompanyId = new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"),
Name = "Sam Raiden",
Position = "Software developer"
},
new
{
EmployeeId = new Guid("12341234-2222-eeee-eeee-aaaabbbbcccc"),
Age = 30,
CompanyId = new Guid("12341234-aaaa-eeee-eeee-aaaabbbbcccc"),
Name = "Jana McLeaf",
Position = "Software developer"
},
new
{
EmployeeId = new Guid("56785678-1111-eeee-eeee-aaaabbbbcccc"),
Age = 35,
CompanyId = new Guid("56785678-aaaa-eeee-eeee-aaaabbbbcccc"),
Name = "Kane Miller",
Position = "Administrator"
});
});
modelBuilder.Entity("Entities.Employee", b =>
{
b.HasOne("Entities.Company", "Company")
.WithMany("Employees")
.HasForeignKey("CompanyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Company");
});
modelBuilder.Entity("Entities.Company", b =>
{
b.Navigation("Employees");
});
#pragma warning restore 612, 618
}
}
}

50
Ultimate/Program.cs Normal file
View file

@ -0,0 +1,50 @@
using Contracts;
using Microsoft.AspNetCore.HttpOverrides;
using NLog;
using Ultimate.Extensions;
var builder = WebApplication.CreateBuilder(args);
LogManager.Setup().LoadConfigurationFromXml(string.Concat(Directory.GetCurrentDirectory(), "nlog.config"));
builder.Services.ConfigureCors();
builder.Services.ConfigureIisIntegration();
builder.Services.ConfigureLoggerService();
builder.Services.ConfigureRepositoryManager();
builder.Services.ConfigureServiceManager();
builder.Services.ConfigureSqlContext(builder.Configuration);
builder.Services.AddAutoMapper(typeof(Program));
builder.Services.AddControllers(config =>
{
config.RespectBrowserAcceptHeader = true;
config.ReturnHttpNotAcceptable = true;
})
.AddXmlDataContractSerializerFormatters()
.AddCustomCsvFormatter()
.AddApplicationPart(typeof(Ultimate.Presentation.AssemblyReference).Assembly);
var app = builder.Build();
var logger = app.Services.GetRequiredService<ILoggerManager>();
app.ConfigureExceptionHandler(logger);
// Configure the HTTP request pipeline.
if (app.Environment.IsProduction())
app.UseHsts();
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseStaticFiles();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.All
});
app.UseCors("CorsPolicy");
app.UseAuthorization();
app.MapControllers();
app.Run();

View file

@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:14838",
"sslPort": 44346
}
},
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"launchUrl": "weatherforecast",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": false,
"launchUrl": "weatherforecast",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

29
Ultimate/Ultimate.csproj Normal file
View file

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Folder Include="ContextFactory\" />
<Folder Include="Migrations\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LoggerService\LoggerService.csproj" />
<ProjectReference Include="..\Repository\Repository.csproj" />
<ProjectReference Include="..\Service\Service.csproj" />
<ProjectReference Include="..\Ultimate.Presentation\Ultimate.Presentation.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

15
Ultimate/nlog.config Normal file
View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Trace"
internalLogFile="\internal_logs\internallog.txt">
<targets>
<target name="logfile" xsi:type="File"
fileName="\logs\${shortdate}_logfile.txt"
layout="${longdate} ${level:uppercase=true} ${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>