commit 9190add515ed31a3a1e8ebbb8f6832f560d8acea
Author: Vojtěch Bartička <aitakaitov@gmail.com>
Date:   Fri Apr 22 13:25:59 2022 +0200

    Added endpoint for adding notes to tags in AnnotationController

diff --git a/Backend/Backend/Controllers/AnnotationController.cs b/Backend/Backend/Controllers/AnnotationController.cs
index e6e1f98..07bd3e9 100644
--- a/Backend/Backend/Controllers/AnnotationController.cs
+++ b/Backend/Backend/Controllers/AnnotationController.cs
@@ -7,6 +7,9 @@ using System.Net;
 using Serilog;
 using Core.Services.AnnotationService;
 using RestAPI.Exceptions;
+using Models.Tags;
+using Core.Services.TagService;
+
 
 namespace RestAPI.Controllers
 {
@@ -14,11 +17,13 @@ namespace RestAPI.Controllers
     {
         private readonly Serilog.ILogger logger;
         private readonly IAnnotationService annotationService;
+        private readonly ITagService tagService;
 
-        public AnnotationController(Serilog.ILogger logger, IAnnotationService annotationService)
+        public AnnotationController(Serilog.ILogger logger, IAnnotationService annotationService, ITagService tagService)
         {
             this.logger = logger;
             this.annotationService = annotationService;
+            this.tagService = tagService;
         }
 
         [HttpPost("/annotations")]
@@ -131,5 +136,35 @@ namespace RestAPI.Controllers
             }
 
         }
+
+        [HttpPost("/annotation/{annotationId}/tag/{occurenceId}/note")]
+        [ProducesResponseType((int)HttpStatusCode.OK)]
+        [ProducesResponseType((int)HttpStatusCode.Forbidden)]
+        public ActionResult AddNoteToTagOccurence([FromServices] ClientInfo clientInfo, Guid annotationId, Guid occurenceId,
+            [FromBody] AddNoteToTagOccurenceRequest request)
+        {
+            if (clientInfo.LoggedUser == null)
+            {
+                logger.Warning("ClientInfo has null LoggerUser in [Authorized] controller /annotations");
+                return Problem();
+            }
+
+            // Take care of - non-admin user requesting not-assigned annotation
+            // non-existent annotation
+            try
+            {
+                tagService.AddAnnotationInstance(annotationId, occurenceId, clientInfo.LoggedUser, request);
+                return Ok();
+            }
+            catch (InvalidOperationException e)
+            {
+                throw new BadRequestException("Could not find specified annotation");
+            }
+            catch (UnauthorizedAccessException)
+            {
+                return Forbid();
+            }
+
+        }
     }
 }
diff --git a/Backend/Core/Services/TagService/ITagService.cs b/Backend/Core/Services/TagService/ITagService.cs
index 0183fe5..8c63cff 100644
--- a/Backend/Core/Services/TagService/ITagService.cs
+++ b/Backend/Core/Services/TagService/ITagService.cs
@@ -1,4 +1,7 @@
-﻿using Models.Tags;
+﻿using Core.Entities;
+using Models.Enums;
+using Models.Tags;
+using Models.Users;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -19,5 +22,6 @@ namespace Core.Services.TagService
         public void CreateSubTag(CreateSubTagRequest request);
         public void DeleteSubTag(Guid subtagId);
         public void UpdateSubTag(ModifySubTagRequest request, Guid subtagId);
+        public void AddAnnotationInstance(Guid annotationId, Guid occurrenceId, User user, AddNoteToTagOccurenceRequest request);
     }
 }
diff --git a/Backend/Core/Services/TagService/TagServiceEF.cs b/Backend/Core/Services/TagService/TagServiceEF.cs
index 6081119..6b20bfd 100644
--- a/Backend/Core/Services/TagService/TagServiceEF.cs
+++ b/Backend/Core/Services/TagService/TagServiceEF.cs
@@ -1,12 +1,16 @@
 ﻿using AutoMapper;
 using Core.Contexts;
+using Core.Entities;
+using Models.Enums;
 using Models.Tags;
+using Models.Users;
 using Serilog;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using System.Linq;
 
 namespace Core.Services.TagService
 {
@@ -188,7 +192,7 @@ namespace Core.Services.TagService
             }
 
             SubTagNameUnusedElseThrow(request.Name);
-            
+
             TagExistsElseThrow(request.TagId);
             var tag = databaseContext.Tags.First(t => t.Id == request.TagId);
 
@@ -219,7 +223,7 @@ namespace Core.Services.TagService
             {
                 SubTagNameUnusedElseThrow(request.Name);
                 subtag.Name = request.Name;
-            }     
+            }
 
             if (request.Description != null)
             {
@@ -229,9 +233,37 @@ namespace Core.Services.TagService
             databaseContext.SaveChanges();
         }
 
+        public void AddAnnotationInstance(Guid annotationId, Guid occurrenceId, User user, AddNoteToTagOccurenceRequest request)
+        {
+            Annotation annotation = null;
+            try
+            {
+                annotation = databaseContext.Annotations.Include(a => a.User).First(a => a.Id == annotationId);
+            }
+            catch (Exception)
+            {
+                throw new InvalidOperationException("Annotation not found");
+            }
 
+            if (user.Role < ERole.ADMINISTRATOR && annotation.User.Id != user.Id)
+            {
+                throw new UnauthorizedAccessException("User does not have access to this annotation");
+            }
 
+            AnnotationTag occurence = null;
+            try
+            {
+                occurence = databaseContext.AnnotationTags.Include(at => at.Annotation)
+                    .First(at => at.Annotation.Id == annotationId && at.Id == occurrenceId);
+            }
+            catch (Exception)
+            {
+                throw new InvalidOperationException("The annotation does not have a tag with specified id");
+            }
 
+            occurence.Note = request.Note;
+            databaseContext.SaveChanges();
+        }
 
         private void CategoryExistsElseThrow(Guid categoryId)
         {
diff --git a/Backend/Models/Tags/AddNoteToTagOccurenceRequest.cs b/Backend/Models/Tags/AddNoteToTagOccurenceRequest.cs
new file mode 100644
index 0000000..f93ab0d
--- /dev/null
+++ b/Backend/Models/Tags/AddNoteToTagOccurenceRequest.cs
@@ -0,0 +1,13 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Models.Tags
+{
+    public class AddNoteToTagOccurenceRequest
+    {
+        public string Note { get; set; }
+    }
+}
