From 584883de41858ed5a3499e34ad23736473f37645 Mon Sep 17 00:00:00 2001
From: Pavel Kirilin <win10@list.ru>
Date: Sat, 14 Dec 2019 01:22:32 +0400
Subject: [PATCH] Refactored code. Descrtiption: - All etities moved in one
 module. - All services moved in one module. - All repos moved in one module.
 - Added cinemas, tickets and users deletion.

Signed-off-by: Pavel Kirilin <win10@list.ru>
---
 .../controllers/CinemasController.kt          | 12 ++--
 .../controllers/TicketsController.kt          | 12 ++--
 .../controllers/UsersController.kt            | 12 ++--
 .../controllers/controllerUtils.kt            | 23 +++++++
 .../controllers/rest/CinemaApiController.kt   | 28 +++++----
 .../controllers/rest/TicketApiController.kt   | 42 +++++++------
 .../controllers/rest/UserApiController.kt     | 21 ++++---
 .../com/s3ai/corporate_app2/entities.kt       | 61 +++++++++++++++++++
 .../s3ai/corporate_app2/entities/Cinema.kt    | 24 --------
 .../s3ai/corporate_app2/entities/Ticket.kt    | 24 --------
 .../com/s3ai/corporate_app2/entities/User.kt  | 21 -------
 .../corporate_app2/repos/TicketRepository.kt  | 11 ----
 .../corporate_app2/repos/UserRepository.kt    | 12 ----
 .../CinemaRepository.kt => repositories.kt}   | 16 ++++-
 .../com/s3ai/corporate_app2/services.kt       | 36 +++++++++++
 .../corporate_app2/services/CinemaService.kt  | 19 ------
 .../corporate_app2/services/TicketService.kt  | 18 ------
 .../corporate_app2/services/UserService.kt    | 18 ------
 .../resources/static/coffee/cinemas.coffee    |  6 +-
 .../resources/static/coffee/tickets.coffee    | 10 ++-
 src/main/resources/static/coffee/users.coffee |  4 +-
 src/main/resources/static/js/cinemas.js       |  7 ++-
 src/main/resources/static/js/tickets.js       | 11 +++-
 src/main/resources/static/js/users.js         |  4 +-
 .../resources/templates/cinemas/list.html     | 12 ++--
 .../resources/templates/tickets/list.html     | 15 ++---
 src/main/resources/templates/users/list.html  | 13 ++--
 27 files changed, 247 insertions(+), 245 deletions(-)
 create mode 100644 src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt
 create mode 100644 src/main/kotlin/com/s3ai/corporate_app2/entities.kt
 delete mode 100644 src/main/kotlin/com/s3ai/corporate_app2/entities/Cinema.kt
 delete mode 100644 src/main/kotlin/com/s3ai/corporate_app2/entities/Ticket.kt
 delete mode 100644 src/main/kotlin/com/s3ai/corporate_app2/entities/User.kt
 delete mode 100644 src/main/kotlin/com/s3ai/corporate_app2/repos/TicketRepository.kt
 delete mode 100644 src/main/kotlin/com/s3ai/corporate_app2/repos/UserRepository.kt
 rename src/main/kotlin/com/s3ai/corporate_app2/{repos/CinemaRepository.kt => repositories.kt} (52%)
 create mode 100644 src/main/kotlin/com/s3ai/corporate_app2/services.kt
 delete mode 100644 src/main/kotlin/com/s3ai/corporate_app2/services/CinemaService.kt
 delete mode 100644 src/main/kotlin/com/s3ai/corporate_app2/services/TicketService.kt
 delete mode 100644 src/main/kotlin/com/s3ai/corporate_app2/services/UserService.kt

diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt
index 7d9e08d..50729cb 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt
@@ -1,8 +1,7 @@
 package com.s3ai.corporate_app2.controllers
 
-import com.s3ai.corporate_app2.entities.Cinema
-import com.s3ai.corporate_app2.repos.CinemaRepository
-import com.s3ai.corporate_app2.services.CinemaService
+import com.s3ai.corporate_app2.Cinema
+import com.s3ai.corporate_app2.CinemaService
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.stereotype.Controller
 import org.springframework.ui.Model
@@ -11,17 +10,16 @@ import org.springframework.web.bind.annotation.RequestMapping
 import org.springframework.web.bind.annotation.RequestParam
 import java.util.UUID.fromString
 import java.util.UUID.randomUUID
-import kotlin.random.Random
 
 @Controller
 @RequestMapping("/cinemas")
 class CinemasController {
     @Autowired
-    var cinemaService: CinemaService? = null
+    lateinit var cinemaService: CinemaService
 
     @GetMapping("/list")
     fun getCinemasBrowsePage(model: Model): String? {
-        model.addAttribute("cinemas", cinemaService?.findAll())
+        model.addAttribute("cinemas", cinemaService.findAll())
         return "cinemas/list"
     }
 
@@ -32,7 +30,7 @@ class CinemasController {
             cinema = Cinema()
             cinema.id = randomUUID()
         } else {
-            cinema = cinemaService?.findOne(fromString(id))
+            cinema = cinemaService.findById(fromString(id))
         }
         model.addAttribute("cinema", cinema)
         return "cinemas/edit"
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt
index b900b4c..01c85f0 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt
@@ -1,9 +1,7 @@
 package com.s3ai.corporate_app2.controllers;
 
-import com.s3ai.corporate_app2.entities.Ticket
-import com.s3ai.corporate_app2.entities.User
-import com.s3ai.corporate_app2.services.TicketService
-import com.s3ai.corporate_app2.services.UserService
+import com.s3ai.corporate_app2.Ticket
+import com.s3ai.corporate_app2.TicketService
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.stereotype.Controller
 import org.springframework.ui.Model
@@ -16,11 +14,11 @@ import java.util.*
 @RequestMapping("/tickets")
 class TicketsController {
     @Autowired
-    var ticketService: TicketService? = null
+    lateinit var ticketService: TicketService
 
     @GetMapping("/list")
     fun getTicketsBrowsePage(model: Model): String? {
-        model.addAttribute("tickets", ticketService?.findAll())
+        model.addAttribute("tickets", ticketService.findAll())
         return "tickets/list"
     }
 
@@ -31,7 +29,7 @@ class TicketsController {
             ticket = Ticket()
             ticket.id = UUID.randomUUID()
         } else {
-            ticket = ticketService?.findOne(UUID.fromString(id))
+            ticket = ticketService.findById(UUID.fromString(id))
         }
         model.addAttribute("ticket", ticket)
         return "tickets/edit"
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt
index 2cd3f89..e77ba34 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt
@@ -1,9 +1,7 @@
 package com.s3ai.corporate_app2.controllers
 
-import com.s3ai.corporate_app2.entities.Cinema
-import com.s3ai.corporate_app2.entities.User
-import com.s3ai.corporate_app2.services.CinemaService
-import com.s3ai.corporate_app2.services.UserService
+import com.s3ai.corporate_app2.User
+import com.s3ai.corporate_app2.UserService
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.stereotype.Controller
 import org.springframework.ui.Model
@@ -16,11 +14,11 @@ import java.util.*
 @RequestMapping("/users")
 class UsersController {
     @Autowired
-    var userService: UserService? = null
+    lateinit var userService: UserService
 
     @GetMapping("/list")
     fun getUsersBrowsePage(model: Model): String? {
-        model.addAttribute("users", userService?.findAll())
+        model.addAttribute("users", userService.findAll())
         return "users/list"
     }
 
@@ -31,7 +29,7 @@ class UsersController {
             user = User()
             user.id = UUID.randomUUID()
         } else {
-            user = userService?.findOne(UUID.fromString(id))
+            user = userService.findById(UUID.fromString(id))
         }
         model.addAttribute("user", user)
         return "users/edit"
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt
new file mode 100644
index 0000000..74018cd
--- /dev/null
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt
@@ -0,0 +1,23 @@
+package com.s3ai.corporate_app2.controllers
+
+import com.s3ai.corporate_app2.CinemaServices
+import org.springframework.ui.Model
+import java.util.*
+import javax.servlet.http.HttpServletResponse
+
+fun <T> deleteInstance(id: String, instanceName: String, jpaService: CinemaServices<T>, response: HttpServletResponse): String? {
+    var responseString: String? = null
+    try {
+        val itemId = UUID.fromString(id)
+        val user = jpaService.findById(itemId)
+        if (null != user) jpaService.delete(user)
+        else {
+            response.status = HttpServletResponse.SC_NOT_FOUND
+            responseString = "$instanceName was not Found"
+        }
+    } catch (e: IllegalArgumentException) {
+        response.status = HttpServletResponse.SC_BAD_REQUEST
+        responseString = e.localizedMessage
+    }
+    return responseString
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiController.kt
index 3eb3eda..c563ba1 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiController.kt
@@ -1,25 +1,25 @@
 package com.s3ai.corporate_app2.controllers.rest
 
-import com.s3ai.corporate_app2.entities.Cinema
-import com.s3ai.corporate_app2.services.CinemaService
+import com.s3ai.corporate_app2.Cinema
+import com.s3ai.corporate_app2.CinemaService
+import com.s3ai.corporate_app2.controllers.deleteInstance
 import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.web.bind.annotation.GetMapping
-import org.springframework.web.bind.annotation.RequestMapping
-import org.springframework.web.bind.annotation.RestController
+import org.springframework.web.bind.annotation.*
 import java.util.*
+import javax.servlet.http.HttpServletResponse
 import kotlin.random.Random
 
 @RestController
 @RequestMapping("/api/cinemas")
-class CinemaApiController{
+class CinemaApiController {
     @Autowired
-    var cinemaService: CinemaService? = null
+    lateinit var cinemaService: CinemaService
 
     @GetMapping("/fill")
     fun fillCinemas(): String? {
-        val locations : List<String> = listOf("Samara", "Izhevsk", "NeoTokyo", "Bangladesh", "Moscow", "Grozny");
-        val names : List<String> = listOf("Nol", "Tcelkoviy", "Polushka", "Chekushka", "Osmushka", "Pudovichok", "Mediachok", "Silverchok", "Goldenchok", "Deviatichek", "Desatichek");
-        var generatedNames: MutableList<String> = mutableListOf()
+        val locations: List<String> = listOf("Samara", "Izhevsk", "NeoTokyo", "Bangladesh", "Moscow", "Grozny");
+        val names: List<String> = listOf("Nol", "Tcelkoviy", "Polushka", "Chekushka", "Osmushka", "Pudovichok", "Mediachok", "Silverchok", "Goldenchok", "Deviatichek", "Desatichek");
+        val generatedNames: MutableList<String> = mutableListOf()
         for (i in 0..300) {
             val cinema = Cinema();
             cinema.id = UUID.randomUUID();
@@ -27,8 +27,14 @@ class CinemaApiController{
             generatedNames.add(cinema.name.toString())
             cinema.seatsCount = Random.nextInt(50, 300);
             cinema.location = locations.random();
-            cinemaService?.save(cinema);
+            cinemaService.save(cinema);
         }
         return generatedNames.toString()
     }
+
+    @DeleteMapping("/delete")
+    fun deleteUser(@RequestParam(name = "id", required = true) id: String, response: HttpServletResponse): String? {
+        return deleteInstance(id, "Cinema", cinemaService, response)
+    }
+
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiController.kt
index a9660d2..439a045 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiController.kt
@@ -1,26 +1,24 @@
 package com.s3ai.corporate_app2.controllers.rest;
 
-import com.s3ai.corporate_app2.entities.Ticket
-import com.s3ai.corporate_app2.entities.User
-import com.s3ai.corporate_app2.services.CinemaService
-import com.s3ai.corporate_app2.services.TicketService
-import com.s3ai.corporate_app2.services.UserService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping
-import org.springframework.web.bind.annotation.RestController
+import com.s3ai.corporate_app2.CinemaService
+import com.s3ai.corporate_app2.Ticket
+import com.s3ai.corporate_app2.TicketService
+import com.s3ai.corporate_app2.UserService
+import com.s3ai.corporate_app2.controllers.deleteInstance
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.web.bind.annotation.*
 import java.util.*
-import kotlin.random.Random
+import javax.servlet.http.HttpServletResponse
 
 @RestController
 @RequestMapping("/api/tickets")
 class TicketApiController {
     @Autowired
-    var userService: UserService? = null
+    lateinit var userService: UserService
     @Autowired
-    var ticketService: TicketService? = null
+    lateinit var ticketService: TicketService
     @Autowired
-    var cinemaService: CinemaService? = null
+    lateinit var cinemaService: CinemaService
 
     @GetMapping("/fill")
     fun fillTickets(): String? {
@@ -28,19 +26,25 @@ class TicketApiController {
         val wordsSecond = arrayOf("of the", "in", "from")
         val wordsThird = arrayOf("Galaxy", "America", "Russia", "Japan", "Ocean", "Deep", "Caribbean", "Matrix", "Internet", "Woods", "Caves")
 
-        val users = userService?.findAll()
-        val cinemas = cinemaService?.findAll()
+        val users = userService.findAll()
+        val cinemas = cinemaService.findAll()
 
-        var generatedNames: MutableList<String> = mutableListOf()
+        val generatedNames: MutableList<String> = mutableListOf()
         for (i in 0..300) {
             val ticket = Ticket();
             ticket.id = UUID.randomUUID();
             ticket.movie = "${wordsFirst.random()} ${wordsSecond.random()} ${wordsThird.random()}";
             generatedNames.add(ticket.movie.toString())
-            ticket.user = users?.random()
-            ticket.cinema = cinemas?.random()
-            ticketService?.save(ticket);
+            ticket.user = users.random()
+            ticket.cinema = cinemas.random()
+            ticketService.save(ticket);
         }
         return generatedNames.toString()
     }
+
+    @DeleteMapping("/delete")
+    fun deleteUser(@RequestParam(name = "id", required = true) id: String, response: HttpServletResponse): String? {
+        return deleteInstance(id, "Ticket", ticketService, response)
+    }
+
 }
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiController.kt
index 7d82662..b9a0a8c 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiController.kt
@@ -1,35 +1,38 @@
 package com.s3ai.corporate_app2.controllers.rest;
 
-import com.s3ai.corporate_app2.entities.Cinema
-import com.s3ai.corporate_app2.entities.User
-import com.s3ai.corporate_app2.services.UserService
+import com.s3ai.corporate_app2.User
+import com.s3ai.corporate_app2.UserService
+import com.s3ai.corporate_app2.controllers.deleteInstance
 import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.web.bind.annotation.GetMapping
-import org.springframework.web.bind.annotation.RequestMapping
-import org.springframework.web.bind.annotation.RestController
+import org.springframework.web.bind.annotation.*
 import java.util.*
+import javax.servlet.http.HttpServletResponse
 import kotlin.random.Random
 
 @RestController
 @RequestMapping("/api/users")
 class UserApiController {
     @Autowired
-    var userService: UserService? = null
+    lateinit var userService: UserService
 
     @GetMapping("/fill")
     fun fillCinemas(): String? {
         val names = arrayOf("Jane", "Mary", "Paul", "Jason", "Keanu", "Andrew", "Joseph", "Jotaro", "Ivan", "Jolyne", "Walther");
         val surnames = arrayOf("Doe", "Reeves", "Statham", "Bourne", "Joestar", "Kujoh", "White", "Van Hallen", "Black", "Smith");
-        var generatedNames: MutableList<String> = mutableListOf()
+        val generatedNames: MutableList<String> = mutableListOf()
         for (i in 0..300) {
             val user = User();
             user.id = UUID.randomUUID();
             user.name = "${names.random()} ${surnames.random()}";
             generatedNames.add(user.name.toString())
             user.age = Random.nextInt(15, 70);
-            userService?.save(user);
+            userService.save(user);
         }
         return generatedNames.toString()
     }
 
+    @DeleteMapping("/delete")
+    fun deleteUser(@RequestParam(name = "id", required = true) id: String, response: HttpServletResponse): String? {
+        return deleteInstance(id, "User", userService, response)
+    }
 }
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/entities.kt b/src/main/kotlin/com/s3ai/corporate_app2/entities.kt
new file mode 100644
index 0000000..9eeb22c
--- /dev/null
+++ b/src/main/kotlin/com/s3ai/corporate_app2/entities.kt
@@ -0,0 +1,61 @@
+package com.s3ai.corporate_app2
+
+import java.util.*
+import javax.persistence.*
+
+@Entity
+@Table(name = "cinema")
+class Cinema {
+    @Id
+    @Column(name = "ID")
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    var id: UUID? = null
+    @Column(name = "name")
+    var name: String? = null
+    @Column(name = "seats_count")
+    var seatsCount: Int? = null
+    @Column(name = "location")
+    var location: String? = null
+
+    override fun toString(): String {
+        return "Cinema{id=$id, name='$name', seatsCount=$seatsCount, location='$location'}"
+    }
+
+}
+
+@Entity
+@Table(name = "cinema_user")
+class User {
+    @Id
+    @Column(name = "ID")
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    var id: UUID? = null
+    @Column(name = "name")
+    var name: String? = null
+    @Column(name = "age")
+    var age: Int? = null
+
+    override fun toString(): String {
+        return "User{id=$id, name='$name', age=$age}"
+    }
+}
+
+@Entity
+@Table(name = "ticket")
+class Ticket {
+    @Id
+    @Column(name = "ID")
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    var id: UUID? = null
+    @OneToOne
+    var user: User? = null
+    @OneToOne
+    var cinema: Cinema? = null
+    @Column(name = "movie")
+    var movie: String? = null
+
+    override fun toString(): String {
+        return "Ticket{id=$id, user=$user, cinema=$cinema, movie='$movie'}"
+    }
+}
+
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/entities/Cinema.kt b/src/main/kotlin/com/s3ai/corporate_app2/entities/Cinema.kt
deleted file mode 100644
index 582729c..0000000
--- a/src/main/kotlin/com/s3ai/corporate_app2/entities/Cinema.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.s3ai.corporate_app2.entities
-
-import java.util.*
-import javax.persistence.*
-
-@Entity
-@Table(name = "cinema")
-class Cinema {
-    @Id
-    @Column(name = "ID")
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    var id: UUID? = null
-    @Column(name = "name")
-    var name: String? = null
-    @Column(name = "seats_count")
-    var seatsCount: Int? = null
-    @Column(name = "location")
-    var location: String? = null
-
-    override fun toString(): String {
-        return "Cinema{id=$id, name='$name', seatsCount=$seatsCount, location='$location'}"
-    }
-
-}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/entities/Ticket.kt b/src/main/kotlin/com/s3ai/corporate_app2/entities/Ticket.kt
deleted file mode 100644
index 4b4c209..0000000
--- a/src/main/kotlin/com/s3ai/corporate_app2/entities/Ticket.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.s3ai.corporate_app2.entities
-
-import java.util.*
-import javax.persistence.*
-
-@Entity
-@Table(name = "ticket")
-class Ticket {
-    @Id
-    @Column(name = "ID")
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    var id: UUID? = null
-    @OneToOne
-    var user: User? = null
-    @OneToOne
-    var cinema: Cinema? = null
-    @Column(name = "movie")
-    var movie: String? = null
-
-    override fun toString(): String {
-        return "Ticket{id=$id, user=$user, cinema=$cinema, movie='$movie'}"
-    }
-}
-
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/entities/User.kt b/src/main/kotlin/com/s3ai/corporate_app2/entities/User.kt
deleted file mode 100644
index a9b7fe0..0000000
--- a/src/main/kotlin/com/s3ai/corporate_app2/entities/User.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.s3ai.corporate_app2.entities
-
-import java.util.*
-import javax.persistence.*
-
-@Entity
-@Table(name = "cinema_user")
-class User {
-    @Id
-    @Column(name = "ID")
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    var id: UUID? = null
-    @Column(name = "name")
-    var name: String? = null
-    @Column(name = "age")
-    var age: Int? = null
-
-    override fun toString(): String {
-        return "User{id=$id, name='$name', age=$age}"
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/repos/TicketRepository.kt b/src/main/kotlin/com/s3ai/corporate_app2/repos/TicketRepository.kt
deleted file mode 100644
index 02b5fda..0000000
--- a/src/main/kotlin/com/s3ai/corporate_app2/repos/TicketRepository.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.s3ai.corporate_app2.repos
-
-import com.s3ai.corporate_app2.entities.Ticket
-import org.springframework.data.jpa.repository.JpaRepository
-import org.springframework.stereotype.Repository
-import java.util.*
-
-@Repository
-interface TicketRepository : JpaRepository<Ticket, UUID> {
-
-}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/repos/UserRepository.kt b/src/main/kotlin/com/s3ai/corporate_app2/repos/UserRepository.kt
deleted file mode 100644
index 3677813..0000000
--- a/src/main/kotlin/com/s3ai/corporate_app2/repos/UserRepository.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.s3ai.corporate_app2.repos
-
-import com.s3ai.corporate_app2.entities.User
-import org.springframework.data.jpa.repository.JpaRepository
-import org.springframework.stereotype.Repository
-import java.util.*
-
-
-@Repository
-interface UserRepository : JpaRepository<User, UUID> {
-
-}
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/repos/CinemaRepository.kt b/src/main/kotlin/com/s3ai/corporate_app2/repositories.kt
similarity index 52%
rename from src/main/kotlin/com/s3ai/corporate_app2/repos/CinemaRepository.kt
rename to src/main/kotlin/com/s3ai/corporate_app2/repositories.kt
index cccc402..6077d0a 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/repos/CinemaRepository.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/repositories.kt
@@ -1,6 +1,5 @@
-package com.s3ai.corporate_app2.repos
+package com.s3ai.corporate_app2
 
-import com.s3ai.corporate_app2.entities.Cinema
 import org.springframework.data.jpa.repository.JpaRepository
 import org.springframework.stereotype.Repository
 import java.util.*
@@ -9,4 +8,15 @@ import java.util.*
 @Repository
 interface CinemaRepository : JpaRepository<Cinema, UUID> {
 
-}
\ No newline at end of file
+}
+
+@Repository
+interface TicketRepository : JpaRepository<Ticket, UUID> {
+
+}
+
+
+@Repository
+interface UserRepository : JpaRepository<User, UUID> {
+
+}
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/services.kt b/src/main/kotlin/com/s3ai/corporate_app2/services.kt
new file mode 100644
index 0000000..51cf0fb
--- /dev/null
+++ b/src/main/kotlin/com/s3ai/corporate_app2/services.kt
@@ -0,0 +1,36 @@
+package com.s3ai.corporate_app2
+
+import org.springframework.stereotype.Service
+import java.util.*
+
+
+interface CinemaServices<T> {
+    fun findAll(): MutableList<T>
+    fun findById(id: UUID): T?
+    fun save(item: T): T
+    fun delete(item: T)
+}
+
+@Service
+class CinemaService(private val cinemaRepository: CinemaRepository) : CinemaServices<Cinema> {
+    override fun findAll(): MutableList<Cinema> = cinemaRepository.findAll()
+    override fun findById(id: UUID): Cinema? = cinemaRepository.findById(id).orElse(null)
+    override fun save(item: Cinema): Cinema = cinemaRepository.save(item)
+    override fun delete(item: Cinema) = cinemaRepository.delete(item)
+}
+
+@Service
+class UserService(private val userRepository: UserRepository) : CinemaServices<User> {
+    override fun findAll(): MutableList<User> = userRepository.findAll()
+    override fun findById(id: UUID): User? = userRepository.findById(id).orElse(null)
+    override fun save(item: User): User = userRepository.save(item)
+    override fun delete(item: User) = userRepository.delete(item)
+}
+
+@Service
+class TicketService(private val ticketRepository: TicketRepository) : CinemaServices<Ticket> {
+    override fun findAll(): MutableList<Ticket> = ticketRepository.findAll()
+    override fun findById(id: UUID): Ticket? = ticketRepository.findById(id).orElse(null)
+    override fun save(item: Ticket): Ticket = ticketRepository.save(item)
+    override fun delete(item: Ticket) = ticketRepository.delete(item)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/services/CinemaService.kt b/src/main/kotlin/com/s3ai/corporate_app2/services/CinemaService.kt
deleted file mode 100644
index 5883081..0000000
--- a/src/main/kotlin/com/s3ai/corporate_app2/services/CinemaService.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.s3ai.corporate_app2.services
-
-import com.s3ai.corporate_app2.entities.Cinema
-import com.s3ai.corporate_app2.repos.CinemaRepository
-import org.springframework.stereotype.Service
-import java.util.*
-
-
-@Service
-class CinemaService(private val cinemaRepository: CinemaRepository) {
-
-    fun findAll(): MutableList<Cinema> = cinemaRepository.findAll()
-
-    fun findOne(id: UUID): Cinema? = cinemaRepository.findById(id).orElse(null)
-
-    fun save(cinema: Cinema) = cinemaRepository.save(cinema)
-
-    fun delete(cinema: Cinema) = cinemaRepository.delete(cinema)
-}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/services/TicketService.kt b/src/main/kotlin/com/s3ai/corporate_app2/services/TicketService.kt
deleted file mode 100644
index 36f2016..0000000
--- a/src/main/kotlin/com/s3ai/corporate_app2/services/TicketService.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.s3ai.corporate_app2.services
-
-import com.s3ai.corporate_app2.entities.Ticket
-import com.s3ai.corporate_app2.repos.TicketRepository
-import org.springframework.stereotype.Service
-import java.util.*
-
-@Service
-class TicketService(private val ticketRepository: TicketRepository) {
-
-    fun findAll(): MutableList<Ticket> = ticketRepository.findAll()
-
-    fun findOne(id: UUID): Ticket? = ticketRepository.findById(id).orElse(null)
-
-    fun save(ticket: Ticket) = ticketRepository.save(ticket)
-
-    fun delete(ticket: Ticket) = ticketRepository.delete(ticket)
-}
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/services/UserService.kt b/src/main/kotlin/com/s3ai/corporate_app2/services/UserService.kt
deleted file mode 100644
index fa212be..0000000
--- a/src/main/kotlin/com/s3ai/corporate_app2/services/UserService.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.s3ai.corporate_app2.services
-
-import com.s3ai.corporate_app2.entities.User
-import com.s3ai.corporate_app2.repos.UserRepository
-import org.springframework.stereotype.Service
-import java.util.*
-
-@Service
-class UserService(private val userRepository: UserRepository) {
-
-    fun findAll(): MutableList<User> = userRepository.findAll()
-
-    fun findOne(id: UUID): User? = userRepository.findById(id).orElse(null)
-
-    fun save(user: User) = userRepository.save(user)
-
-    fun delete(user: User) = userRepository.delete(user)
-}
\ No newline at end of file
diff --git a/src/main/resources/static/coffee/cinemas.coffee b/src/main/resources/static/coffee/cinemas.coffee
index bce38c4..0d9d412 100644
--- a/src/main/resources/static/coffee/cinemas.coffee
+++ b/src/main/resources/static/coffee/cinemas.coffee
@@ -18,7 +18,11 @@ removeCinema = (event) ->
     url: "/api/cinemas/delete?id=#{cinema_id}",
     type: 'DELETE'
     error: (jqXHR, textStatus, errorThrown) ->
-      console.log "AJAX Error: #{textStatus}"
+      $.toast
+        icon: 'error',
+        hideAfter: 5000,
+        heading: "Cannot delete cinema",
+        text: "#{jqXHR.responseText}"
     success: (data, textStatus, jqXHR) ->
       $("tr[cinema_id='#{cinema_id}").remove()
       $("#cinemaModal").modal('toggle')
diff --git a/src/main/resources/static/coffee/tickets.coffee b/src/main/resources/static/coffee/tickets.coffee
index fb73d38..c643493 100644
--- a/src/main/resources/static/coffee/tickets.coffee
+++ b/src/main/resources/static/coffee/tickets.coffee
@@ -10,15 +10,19 @@ fill_modal = (event) ->
 
 hrefToEdit = (event) ->
   ticket_id = $("#modal_id").text()
-  window.location.replace "#{context_url}/ticket/?id=#{ticket_id}"
+  window.location.replace "/tickets/edit?id=#{ticket_id}"
 
 removeCinema = (event) ->
   ticket_id = $("#modal_id").text()
   $.ajax
-    url: "#{context_url}/ticket/?id=#{ticket_id}",
+    url: "/api/tickets/delete?id=#{ticket_id}",
     type: 'DELETE'
     error: (jqXHR, textStatus, errorThrown) ->
-      console.log "AJAX Error: #{textStatus}"
+      $.toast
+        icon: 'error',
+        hideAfter: 5000,
+        heading: "Cannot delete ticket",
+        text: "#{jqXHR.responseText}"
     success: (data, textStatus, jqXHR) ->
       $("tr[ticket_id='#{ticket_id}").remove()
       $("#ticketModal").modal('toggle')
diff --git a/src/main/resources/static/coffee/users.coffee b/src/main/resources/static/coffee/users.coffee
index fb94baa..f9f1879 100644
--- a/src/main/resources/static/coffee/users.coffee
+++ b/src/main/resources/static/coffee/users.coffee
@@ -9,12 +9,12 @@ fill_modal = (event) ->
 
 hrefToEdit = (event) ->
   user_id = $("#modal_id").text()
-  window.location.replace "#{context_url}/user/?id=#{user_id}"
+  window.location.replace "/users/edit?id=#{user_id}"
 
 removeCinema = (event) ->
   user_id = $("#modal_id").text()
   $.ajax
-    url: "#{context_url}/user/?id=#{user_id}",
+    url: "/api/users/delete?id=#{user_id}",
     type: 'DELETE'
     error: (jqXHR, textStatus, errorThrown) ->
       $.toast
diff --git a/src/main/resources/static/js/cinemas.js b/src/main/resources/static/js/cinemas.js
index be966d3..127a899 100644
--- a/src/main/resources/static/js/cinemas.js
+++ b/src/main/resources/static/js/cinemas.js
@@ -28,7 +28,12 @@
       url: `/api/cinemas/delete?id=${cinema_id}`,
       type: 'DELETE',
       error: function(jqXHR, textStatus, errorThrown) {
-        return console.log(`AJAX Error: ${textStatus}`);
+        return $.toast({
+          icon: 'error',
+          hideAfter: 5000,
+          heading: "Cannot delete cinema",
+          text: `${jqXHR.responseText}`
+        });
       },
       success: function(data, textStatus, jqXHR) {
         $(`tr[cinema_id='${cinema_id}`).remove();
diff --git a/src/main/resources/static/js/tickets.js b/src/main/resources/static/js/tickets.js
index 2878d49..14c63cf 100644
--- a/src/main/resources/static/js/tickets.js
+++ b/src/main/resources/static/js/tickets.js
@@ -18,17 +18,22 @@
   hrefToEdit = function(event) {
     var ticket_id;
     ticket_id = $("#modal_id").text();
-    return window.location.replace(`${context_url}/ticket/?id=${ticket_id}`);
+    return window.location.replace(`/tickets/edit?id=${ticket_id}`);
   };
 
   removeCinema = function(event) {
     var ticket_id;
     ticket_id = $("#modal_id").text();
     return $.ajax({
-      url: `${context_url}/ticket/?id=${ticket_id}`,
+      url: `/api/tickets/delete?id=${ticket_id}`,
       type: 'DELETE',
       error: function(jqXHR, textStatus, errorThrown) {
-        return console.log(`AJAX Error: ${textStatus}`);
+        return $.toast({
+          icon: 'error',
+          hideAfter: 5000,
+          heading: "Cannot delete ticket",
+          text: `${jqXHR.responseText}`
+        });
       },
       success: function(data, textStatus, jqXHR) {
         $(`tr[ticket_id='${ticket_id}`).remove();
diff --git a/src/main/resources/static/js/users.js b/src/main/resources/static/js/users.js
index 6bc7f75..c21c7c4 100644
--- a/src/main/resources/static/js/users.js
+++ b/src/main/resources/static/js/users.js
@@ -17,14 +17,14 @@
   hrefToEdit = function(event) {
     var user_id;
     user_id = $("#modal_id").text();
-    return window.location.replace(`${context_url}/user/?id=${user_id}`);
+    return window.location.replace(`/users/edit?id=${user_id}`);
   };
 
   removeCinema = function(event) {
     var user_id;
     user_id = $("#modal_id").text();
     return $.ajax({
-      url: `${context_url}/user/?id=${user_id}`,
+      url: `/api/users/delete?id=${user_id}`,
       type: 'DELETE',
       error: function(jqXHR, textStatus, errorThrown) {
         return $.toast({
diff --git a/src/main/resources/templates/cinemas/list.html b/src/main/resources/templates/cinemas/list.html
index cbcbf4c..3993917 100644
--- a/src/main/resources/templates/cinemas/list.html
+++ b/src/main/resources/templates/cinemas/list.html
@@ -18,11 +18,11 @@
             </tr>
             </thead>
             <tbody>
-            <tr th:each="sb : ${cinemas}" th:with="mycounter = 0">
-                <td th:text="${mycounter}" th:with="mycounter = ${mycounter + 1}">#</td>
-                <td th:text="${sb.getName()}">Name</td>
-                <td th:text="${sb.getLocation()}">Location</td>
-                <td th:text="${sb.getSeatsCount()}">Seats</td>
+            <tr th:attr="cinema_id=${cinema.getId()}" th:each="cinema, counter : ${cinemas}">
+                <td th:text="${counter.count}" >#</td>
+                <td attr_name="name" th:text="${cinema.getName()}">Name</td>
+                <td attr_name="location" th:text="${cinema.getLocation()}">Location</td>
+                <td attr_name="seats" th:text="${cinema.getSeatsCount()}">Seats</td>
             </tr>
             </tbody>
         </table>
@@ -73,5 +73,5 @@
     </div>
 </div>
 </body>
-<script src="js/cinemas.js"></script>
+<script src="/js/cinemas.js"></script>
 </html>
diff --git a/src/main/resources/templates/tickets/list.html b/src/main/resources/templates/tickets/list.html
index d47ffdd..2c8cdd9 100644
--- a/src/main/resources/templates/tickets/list.html
+++ b/src/main/resources/templates/tickets/list.html
@@ -18,11 +18,11 @@
             </tr>
             </thead>
             <tbody th:with="mycounter = 0">
-            <tr th:each="sb : ${tickets}">
-                <td th:text="${mycounter}" th:with="mycounter = ${mycounter + 1}">#</td>
-                <td th:text="${sb.getMovie()}">Movie</td>
-                <td th:text="${sb.getCinema()}">Cinema</td>
-                <td th:text="${sb.getUser()}">User</td>
+            <tr th:attr="ticket_id=${ticket.getId()}" th:each="ticket, counter: ${tickets}">
+                <td th:text="${counter.count}">#</td>
+                <td attr_name="movie" th:text="${ticket.getMovie()}">Movie</td>
+                <td attr_name="cinema_id" th:text="${ticket.getCinema().getName()} + ' in ' + ${ticket.getCinema().getLocation()}">Cinema</td>
+                <td attr_name="user_id" th:text="${ticket.getUser().getName()} + ' aged ' + ${ticket.getUser().getAge()}">User</td>
             </tr>
             </tbody>
         </table>
@@ -73,8 +73,5 @@
     </div>
 </div>
 </body>
-<script>
-    let context_url = "${pageContext.request.contextPath}"
-</script>
-<script src="js/tickets.js"></script>
+<script src="/js/tickets.js"></script>
 </html>
diff --git a/src/main/resources/templates/users/list.html b/src/main/resources/templates/users/list.html
index 7a6ba79..2fe3593 100644
--- a/src/main/resources/templates/users/list.html
+++ b/src/main/resources/templates/users/list.html
@@ -18,10 +18,10 @@
             </tr>
             </thead>
             <tbody>
-            <tr th:each="sb : ${users}" th:with="mycounter = 0">
-                <td th:text="${mycounter}" th:with="mycounter = ${mycounter + 1}">#</td>
-                <td th:text="${sb.getName()}">Name</td>
-                <td th:text="${sb.getAge()}">Age</td>
+            <tr th:attr="user_id=${user.getId()}" th:each="user, counter : ${users}">
+                <td th:text="${counter.count}">#</td>
+                <td attr_name="name" th:text="${user.getName()}">Name</td>
+                <td attr_name="age" th:text="${user.getAge()}">Age</td>
             </tr>
             </tbody>
         </table>
@@ -68,8 +68,5 @@
     </div>
 </div>
 </body>
-<script>
-    let context_url = "${pageContext.request.contextPath}"
-</script>
-<script src="js/users.js"></script>
+<script src="/js/users.js"></script>
 </html>
-- 
GitLab