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();
}
}
}