From 86203c79581a3c52530992190d182425696632e8 Mon Sep 17 00:00:00 2001
From: Michal Bohdanowicz <m.w.bohdanowicz@gmail.com>
Date: Mon, 11 Jan 2021 20:44:08 +0100
Subject: [PATCH] Add approvals

---
 .../DocumentManagementController.cs           | 22 ++++++++-
 .../InternshipRegistrationController.cs       |  9 ++--
 .../Controllers/ReportController.cs           |  3 +-
 .../UpdateInternshipRegistrationUseCase.cs    | 36 +++++++++++++--
 src/InternshipSystem.Core/Entity/Edition.cs   |  4 +-
 .../Entity/Internship/Internship.cs           | 45 ++++++++++---------
 .../Internship/InternshipRegistration.cs      |  4 --
 .../ValueObject/DocumentType.cs               |  9 ++--
 .../DatabaseFiller.cs                         |  1 +
 .../InternshipSystem.cs                       |  2 -
 10 files changed, 92 insertions(+), 43 deletions(-)

diff --git a/src/InternshipSystem.Api/Controllers/DocumentManagementController.cs b/src/InternshipSystem.Api/Controllers/DocumentManagementController.cs
index 6b617fa..d48e21a 100644
--- a/src/InternshipSystem.Api/Controllers/DocumentManagementController.cs
+++ b/src/InternshipSystem.Api/Controllers/DocumentManagementController.cs
@@ -22,6 +22,26 @@ namespace InternshipSystem.Api.Controllers
         {
             Context = context;
         }
+        
+        [HttpDelete("delete/{documentId}")]
+        [Authorize(Policy = Policies.IsOverseer)]
+        public async Task<ActionResult> DeleteDocument(long documentId, CancellationToken ct)
+        {
+            var internship = await Context.Internships
+                .Include(i => i.Documentation)
+                .FirstOrDefaultAsync(i => i.Documentation.Any(d => d.Id.Equals(documentId)), ct);
+
+            if (internship == null)
+            {
+                return NotFound();
+            }
+            
+            internship.RemoveDocument(documentId);
+
+            await Context.SaveChangesAsync(ct);
+            
+            return Ok();
+        }
 
         [HttpPut("accept/{documentId}")]
         [ProducesResponseType(StatusCodes.Status200OK)]
@@ -60,7 +80,7 @@ namespace InternshipSystem.Api.Controllers
         [ProducesResponseType(StatusCodes.Status401Unauthorized)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
         [Authorize(Policy = Policies.IsOverseer)]
-        public async Task<ActionResult> RejectInternship(long documentId, [FromBody] string comment, CancellationToken token)
+        public async Task<ActionResult> RejectDocument(long documentId, [FromBody] string comment, CancellationToken token)
         {
             var internship = await Context.Internships
                 .Include(i => i.Documentation)
diff --git a/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs b/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs
index 6032c1b..a903f60 100644
--- a/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs
+++ b/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs
@@ -47,7 +47,7 @@ namespace InternshipSystem.Api.Controllers
                     .ThenInclude(t => t.Subject)
                 .FirstAsync(e => e.Id == user.EditionId, cancellationToken);
 
-            var internshipRegistration =
+            var internship =
                 await _context
                     .Entry(edition)
                     .Collection(e => e.Internships)
@@ -62,12 +62,11 @@ namespace InternshipSystem.Api.Controllers
                         .ThenInclude(c => c.Type)
                     .Include(i => i.InternshipRegistration)
                         .ThenInclude(c => c.Subjects)
+                    .Include(i => i.Documentation)
                     .Where(i => i.Student.Id == user.PersonNumber)
-                    .Select(i => i.InternshipRegistration)
                     .FirstAsync(cancellationToken);
-            
-            
-            var useCase = new UpdateInternshipRegistrationUseCase(_context, internshipRegistration, edition, user);
+
+            var useCase = new UpdateInternshipRegistrationUseCase(_context, internship, edition, user);
 
             try
             {
diff --git a/src/InternshipSystem.Api/Controllers/ReportController.cs b/src/InternshipSystem.Api/Controllers/ReportController.cs
index 6adf4e3..0e3bfed 100644
--- a/src/InternshipSystem.Api/Controllers/ReportController.cs
+++ b/src/InternshipSystem.Api/Controllers/ReportController.cs
@@ -1,6 +1,7 @@
 using System.Threading;
 using System.Threading.Tasks;
 using InternshipSystem.Api.Security;
+using InternshipSystem.Core.ValueObject;
 using InternshipSystem.Repository;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
@@ -35,7 +36,7 @@ namespace InternshipSystem.Api.Controllers
                 .SingleAsync(i => i.Student.Id == user.PersonNumber, ct);
 
             internship.Report.UpdateReport(reportValue.ToString(Formatting.None));
-            internship.AddInternshipEvaluation();
+            internship.AddNewDocument("", DocumentType.InternshipEvaluation);
             
             await _context.SaveChangesAsync(ct);
 
diff --git a/src/InternshipSystem.Api/UseCases/UpdateInternshipRegistrationUseCase.cs b/src/InternshipSystem.Api/UseCases/UpdateInternshipRegistrationUseCase.cs
index 9f68e67..ea50e3a 100644
--- a/src/InternshipSystem.Api/UseCases/UpdateInternshipRegistrationUseCase.cs
+++ b/src/InternshipSystem.Api/UseCases/UpdateInternshipRegistrationUseCase.cs
@@ -9,6 +9,7 @@ using InternshipSystem.Api.Security;
 using InternshipSystem.Core;
 using InternshipSystem.Core.Entity.Internship;
 using InternshipSystem.Core.UglyOrmArtifacts;
+using InternshipSystem.Core.ValueObject;
 using InternshipSystem.Repository;
 using Microsoft.EntityFrameworkCore;
 
@@ -17,25 +18,27 @@ namespace InternshipSystem.Api.UseCases
     public class UpdateInternshipRegistrationUseCase
     {
         private readonly InternshipDbContext _dbContext;
+        private readonly Internship _internship;
         private readonly Edition _edition;
         private readonly User _user;
         private readonly InternshipRegistration subjectRegistration;
 
         public UpdateInternshipRegistrationUseCase(InternshipDbContext dbContext,
-            InternshipRegistration internshipRegistration, Edition edition, User user)
+            Internship internship, Edition edition, User user)
         {
             _dbContext = dbContext;
+            _internship = internship;
             _edition = edition;
             _user = user;
-            subjectRegistration = internshipRegistration;
+            _internship = internship;
+            subjectRegistration = internship.InternshipRegistration;
         }
 
         public async Task<(DocumentState State, IEnumerable<ErrorDescription>)> UpdateInternshipRegistration(
             UpdateRegistrationForm registrationCommand,
             CancellationToken cancellationToken)
         {
-            subjectRegistration.Start = registrationCommand.Start ?? subjectRegistration.Start;
-            subjectRegistration.End = registrationCommand.End ?? subjectRegistration.End;
+            UpdateTimeFrame(registrationCommand);
             subjectRegistration.DeclaredHours = registrationCommand.Hours ?? subjectRegistration.DeclaredHours;
 
             if (registrationCommand.Type.HasValue)
@@ -61,9 +64,34 @@ namespace InternshipSystem.Api.UseCases
             return subjectRegistration.ValidateStatus(_edition);
         }
 
+        private void UpdateTimeFrame(UpdateRegistrationForm registrationCommand)
+        {
+            subjectRegistration.Start = registrationCommand.Start ?? subjectRegistration.Start;
+            subjectRegistration.End = registrationCommand.End ?? subjectRegistration.End;
+
+            if (!_edition.IsDateDuringEdition(subjectRegistration.Start, subjectRegistration.End))
+            {
+                _internship.AddNewDocument("", DocumentType.OutsideTermApproval);
+            }
+            else
+            {
+                _internship.RemoveDocument(DocumentType.OutsideTermApproval);
+            }
+        }
+
         private void UpdateInternshipType(long typeId)
         {
             var editionInternshipType = _edition.AvailableInternshipTypes.FirstOrDefault(i => i.InternshipTypeId == typeId);
+
+            if (editionInternshipType?.InternshipType.RequireDeansApproval == true)
+            {
+                _internship.AddNewDocument("", DocumentType.InternshipTypeApproval);
+            }
+            else
+            {
+                _internship.RemoveDocument(DocumentType.InternshipTypeApproval);
+            }
+            
             subjectRegistration.Type = editionInternshipType?.InternshipType ?? subjectRegistration.Type;
         }
 
diff --git a/src/InternshipSystem.Core/Entity/Edition.cs b/src/InternshipSystem.Core/Entity/Edition.cs
index 5e32f31..35b6020 100644
--- a/src/InternshipSystem.Core/Entity/Edition.cs
+++ b/src/InternshipSystem.Core/Entity/Edition.cs
@@ -120,9 +120,7 @@ namespace InternshipSystem.Core
             }
             
             var internship = Internship.CreateStudentsInternship(student);
-            
-            
-            
+
             Internships.Add(internship);
         }
 
diff --git a/src/InternshipSystem.Core/Entity/Internship/Internship.cs b/src/InternshipSystem.Core/Entity/Internship/Internship.cs
index 84334a3..d03aab3 100644
--- a/src/InternshipSystem.Core/Entity/Internship/Internship.cs
+++ b/src/InternshipSystem.Core/Entity/Internship/Internship.cs
@@ -26,14 +26,19 @@ namespace InternshipSystem.Core.Entity.Internship
             internship.Report = Report.Create();
             internship.Documentation = new List<Document>();
 
+            if (student.Semester != 6)
+            {
+                internship.AddNewDocument("", DocumentType.OutsideSemesterApproval);
+            }
+            
             return internship;
         }
 
         public void AddNewDocument(string description, DocumentType type)
         {
-            if (Documentation.Any(d => d.Type == type))
+            if (type != DocumentType.Other && Documentation.Any(d => d.Type == type))
             {
-                throw new ArgumentException("Internship already has a document of given type");                
+                return;
             }
             
             var document = new Document
@@ -46,29 +51,29 @@ namespace InternshipSystem.Core.Entity.Internship
             Documentation.Add(document);
         }
 
-        public void UpdateDocumentScan(long documentId, byte[] documentScan)
+        public void RemoveDocument(DocumentType documentType)
         {
-            var document = Documentation.First(d => d.Id == documentId);
-
-            // document.Scan = documentScan;
-            // document.State = DocumentState.Submitted;
-        }
-
-        public void AddInternshipEvaluation()
-        {
-            if (Documentation.Any(d => d.Type == DocumentType.InternshipEvaluation))
+            if (documentType == DocumentType.Other)
             {
                 return;
             }
             
-            var document = new Document
-            {
-                Description = "",
-                Type = DocumentType.InternshipEvaluation,
-                State = DocumentState.Draft
-            };
-            
-            Documentation.Add(document);
+            var doc = Documentation.FirstOrDefault(d => d.Type == documentType);
+
+            if (doc != null)
+            { 
+                Documentation.Remove(doc);
+            }
+        }
+
+        public void RemoveDocument(long id)
+        {
+            var doc = Documentation.FirstOrDefault(d => d.Id == id);
+
+            if (doc != null)
+            { 
+                Documentation.Remove(doc);
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs b/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs
index cde137e..a938951 100644
--- a/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs
+++ b/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs
@@ -62,13 +62,9 @@ namespace InternshipSystem.Core.Entity.Internship
                     .Must(edition.IsTypeAvailable)
                     .WithMessage("error.type.not_available");
                 RuleFor(x => x.Start)
-                    .GreaterThanOrEqualTo(edition.EditionStart)
-                    .LessThan(x => x.End)
                     .NotEmpty()
                     .WithMessage("error.start_date.empty");
                 RuleFor(x => x.End)
-                    .LessThanOrEqualTo(edition.EditionFinish)
-                    .GreaterThan(x => x.Start)
                     .NotEmpty()
                     .WithMessage("error.end_date.empty");
                 RuleFor(x => x.DeclaredHours)
diff --git a/src/InternshipSystem.Core/ValueObject/DocumentType.cs b/src/InternshipSystem.Core/ValueObject/DocumentType.cs
index 3651c43..6b29915 100644
--- a/src/InternshipSystem.Core/ValueObject/DocumentType.cs
+++ b/src/InternshipSystem.Core/ValueObject/DocumentType.cs
@@ -3,8 +3,11 @@
     public enum DocumentType
     {
         IppScan,
-        DeanConsent,
-        NnwIsurance,
-        InternshipEvaluation
+        OutsideTermApproval,
+        InternshipTypeApproval,
+        OutsideSemesterApproval,
+        NnwInsurance,
+        InternshipEvaluation,
+        Other
     }
 }
\ No newline at end of file
diff --git a/src/InternshipSystem.Repository/DatabaseFiller.cs b/src/InternshipSystem.Repository/DatabaseFiller.cs
index f79e3b6..8d1c7d6 100644
--- a/src/InternshipSystem.Repository/DatabaseFiller.cs
+++ b/src/InternshipSystem.Repository/DatabaseFiller.cs
@@ -159,6 +159,7 @@ namespace InternshipSystem.Repository
                 {
                     Label = "Umowa zlecenia (w tym B2B)",
                     LabelEng = "Contract of mandate (including B2B)",
+                    RequireDeansApproval = true
                 },  
             };
             await Context.InternshipTypes.AddRangeAsync(internshipTypes);
diff --git a/test/InternshipSystem.Api.Test/InternshipSystem.cs b/test/InternshipSystem.Api.Test/InternshipSystem.cs
index 8801e35..719c63e 100644
--- a/test/InternshipSystem.Api.Test/InternshipSystem.cs
+++ b/test/InternshipSystem.Api.Test/InternshipSystem.cs
@@ -123,7 +123,6 @@ namespace InternshipSystem.Api.Test
                 .Include(i => i.InternshipRegistration)
                     .ThenInclude(c => c.Subjects)
                 .Where(i => i.Student.Id == user.PersonNumber)
-                .Select(i => i.InternshipRegistration)
                 .First();
 
             var useCase = new UpdateInternshipRegistrationUseCase(db, ir, ed, user);
@@ -161,7 +160,6 @@ namespace InternshipSystem.Api.Test
                 .Include(i => i.InternshipRegistration)
                 .ThenInclude(c => c.Subjects)
                 .Where(i => i.Student.Id == user.PersonNumber)
-                .Select(i => i.InternshipRegistration)
                 .First();
         };