using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using InternshipSystem.Api.Queries; using InternshipSystem.Api.Queries.SearchQuery; using InternshipSystem.Api.Security; using InternshipSystem.Core; using InternshipSystem.Repository; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using static System.String; namespace InternshipSystem.Api.Controllers { [ApiController] [Route("companies")] public class CompaniesController : ControllerBase { public CompaniesController(InternshipDbContext context) { Context = context; } private InternshipDbContext Context { get; } /// /// Get companies matching provided paginated query /// /// Paginated query description /// Successfully retrieved Companies /// Search query was malformed /// Part of companies collection [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [Authorize] public async Task>> SearchByNameAsync([FromQuery] CompanySearchQuery searchQuery, [FromServices] User user, CancellationToken cancellationToken) => await Context.Companies .Where(c => c.Name.ToLower().Contains(searchQuery.Name.ToLower())) .Where(c => c.Provider == 0 || c.Provider == user.PersonNumber) .OrderBy(o => o.Name) .Skip(searchQuery.Page * searchQuery.PerPage) .Take(searchQuery.PerPage) .ToListAsync(cancellationToken); /// /// Get company branches matching provided paginated query /// /// Paginated query description /// /// Successfully retrieved matching offices /// Search query was malformed /// Part of companies collection [HttpGet("{companyId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [Authorize] public async Task>> SearchBranchesByAddress([FromQuery] BranchOfficeSearchQuery searchQuery, long companyId, [FromServices] User user, CancellationToken token) { var company = await Context.Companies.Where(c => c.Id == companyId).FirstAsync(token); return await Context.Entry(company) .Collection(c => c.Branches) .Query() .Where(office => office.Address.City.ToLower().Contains(searchQuery.City.ToLower())) .Where(office => office.Provider == 0 || office.Provider == user.PersonNumber) .Skip(searchQuery.Page * searchQuery.PerPage) .Take(searchQuery.PerPage) .ToListAsync(token); } /// /// Updates or add new company (if not new than contains id) /// /// /// Successfully updated company /// Company form was malformed /// This action is only available for authorized internship admin /// Company not found /// [HttpPut] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize] public async Task UpsertCompany([FromBody] CompanyForm companyForm, CancellationToken cancellationToken) { var validator = new CompanyForm.Validator(); var validationResult = await validator.ValidateAsync(companyForm, cancellationToken); if (!validationResult.IsValid) { return BadRequest(validationResult.ToString()); } if (companyForm.Id.HasValue) { var companyToUpdate = await Context.Companies.FindAsync(companyForm.Id.Value); if (companyToUpdate == null) { return NotFound(); } companyToUpdate.Name = IsNullOrEmpty(companyForm.Name) ? companyToUpdate.Name : companyForm.Name; companyToUpdate.Nip = IsNullOrEmpty(companyForm.Nip) ? companyToUpdate.Nip : companyForm.Nip; } else { var newCompany = Company.CreateCompany(companyForm.Nip, companyForm.Name); await Context.Companies.AddAsync(newCompany, cancellationToken); } await Context.SaveChangesAsync(cancellationToken); return Ok(); } /// /// Deletes existing company by id /// /// /// Successfully deleted company /// Company id is empty /// This action is only available for authorized internship admin /// Company not found /// [HttpDelete("{companyId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize] public async Task DeleteCompany(long companyId, CancellationToken cancellationToken) { var companyToDelete = await Context.Companies .Include(c => c.Branches) .FirstOrDefaultAsync(c => c.Id == companyId, cancellationToken); if (companyToDelete == null) { return NotFound(); } Context.Companies.Remove(companyToDelete); await Context.SaveChangesAsync(cancellationToken); return Ok(); } /// /// Updates or add new branchOffice (if not new than contains id) /// /// /// /// Successfully updated company branch office /// Branch office was malformed /// This action is only available for authorized internship admin /// Company or branch office not found /// [HttpPut("{companyId}/branchOffices")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize] public async Task UpdateBranch([FromBody] BranchOfficeForm branchOfficeForm, long companyId, CancellationToken cancellationToken) { var validator = new BranchOfficeForm.Validator(); var validationResult = await validator.ValidateAsync(branchOfficeForm, cancellationToken); if (!validationResult.IsValid) { return BadRequest(validationResult.ToString()); } var company = await Context.Companies .Include(c => c.Branches) .FirstOrDefaultAsync(c => c.Id == companyId, cancellationToken); if (company == null) { return NotFound(); } if (branchOfficeForm.Id.HasValue) { var branchOffice = company.Branches.First(b => b.Id == branchOfficeForm.Id); if (branchOffice == null) { return NotFound(); } branchOffice.Address.Country = IsNullOrEmpty(branchOfficeForm.Country) ? branchOffice.Address.Country : branchOfficeForm.Country; branchOffice.Address.City = IsNullOrEmpty(branchOfficeForm.City) ? branchOffice.Address.City : branchOfficeForm.City; branchOffice.Address.PostalCode = IsNullOrEmpty(branchOfficeForm.PostalCode) ? branchOffice.Address.PostalCode : branchOfficeForm.PostalCode; branchOffice.Address.Street = IsNullOrEmpty(branchOfficeForm.Street) ? branchOffice.Address.Street : branchOfficeForm.Street; branchOffice.Address.Building = IsNullOrEmpty(branchOfficeForm.Building) ? branchOffice.Address.Building : branchOfficeForm.Building; } else { var newBranchOffice = new BranchOffice { Address = new BranchAddress { Country = branchOfficeForm.Country, City = branchOfficeForm.City, PostalCode = branchOfficeForm.PostalCode, Street = branchOfficeForm.Street, Building = branchOfficeForm.Building, } }; company.Branches.Add(newBranchOffice); } await Context.SaveChangesAsync(cancellationToken); return Ok(); } /// /// Deletes existing branchOffice /// /// /// Successfully deleted company branch office /// Branch office id is empty /// This action is only available for authorized internship admin /// Company or branch office not found [HttpDelete("{companyId}/branchOffice/{branchOfficeId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize] public async Task DeleteBranch(long companyId, long branchOfficeId, CancellationToken cancellationToken) { var company = await Context.Companies .Include(c => c.Branches) .Where(c => c.Id == companyId) .FirstOrDefaultAsync(cancellationToken); if (company == null) { return NotFound(); } var branchOffice = company.Branches.RemoveAll(b => b.Id == branchOfficeId); await Context.SaveChangesAsync(cancellationToken); return Ok(); } } }