diff --git a/build.gradle.kts b/build.gradle.kts index 1c540fa..2e15540 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ plugins { } group = "com.aitrainer" -version = "1.0.25" +version = "1.0.26" java.sourceCompatibility = JavaVersion.VERSION_1_8 repositories { diff --git a/data/db/install.sql b/data/db/install.sql index 2a00794..81aa255 100644 --- a/data/db/install.sql +++ b/data/db/install.sql @@ -529,16 +529,18 @@ CREATE TABLE IF NOT EXISTS `exercise_plan` ( `private` tinyint(4) DEFAULT 0, `date_add` datetime DEFAULT NULL, `date_upd` datetime DEFAULT NULL, + `type` ENUM('custom','mini_test_set','special') NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', + `exercise_plan_template_id` INT(11) NULL DEFAULT NULL, PRIMARY KEY (`exercise_plan_id`) ) ENGINE=InnoDB AUTO_INCREMENT=104 DEFAULT CHARSET=utf8mb4; -- Tábla adatainak mentése aitrainer2.exercise_plan: ~4 rows (hozzávetőleg) /*!40000 ALTER TABLE `exercise_plan` DISABLE KEYS */; REPLACE INTO `exercise_plan` (`exercise_plan_id`, `customer_id`, `name`, `description`, `private`, `date_add`, `date_upd`) VALUES - (3, 90, 'Common', 'Common training plan', 0, NULL, NULL), - (4, 90, 'Chuck Norris Plan', '', 0, NULL, NULL), - (6, 90, 'Boss private', '', 1, '2020-09-08 00:06:26', NULL), - (20, 90, 'Boss private 2', NULL, 1, '2020-09-09 00:06:19', NULL); + (3, 90, 'Common', 'Common training plan', 0, NULL, NULL, NULL, NULL), + (4, 90, 'Chuck Norris Plan', '', 0, NULL, NULL, NULL, NULL), + (6, 90, 'Boss private', '', 1, '2020-09-08 00:06:26', NULL, NULL, NULL), + (20, 90, 'Boss private 2', NULL, 1, '2020-09-09 00:06:19', NULL, NULL, NULL); /*!40000 ALTER TABLE `exercise_plan` ENABLE KEYS */; -- Struktúra mentése tábla aitrainer2. exercise_plan_detail @@ -938,6 +940,46 @@ COLLATE='utf8_hungarian_ci' ENGINE=InnoDB ; +CREATE TABLE `exercise_plan_template` ( + `exercise_plan_template_id` INT(11) NOT NULL AUTO_INCREMENT, + `template_type` ENUM('special','mini_test_set') NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + `name` CHAR(50) NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + `description` MEDIUMTEXT NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + PRIMARY KEY (`exercise_plan_template_id`) USING BTREE, + INDEX `template_type` (`template_type`) USING BTREE +) +COLLATE='utf8_hungarian_ci' +ENGINE=InnoDB +; + +CREATE TABLE `exercise_plan_template_detail` ( + `exercise_plan_template_detail_id` INT(11) NOT NULL AUTO_INCREMENT, + `exercise_plan_template_id` INT(11) NOT NULL DEFAULT '0', + `exercise_type_id` INT(11) NOT NULL DEFAULT '0', + `quantity` DOUBLE NULL DEFAULT '0', + `quantity_unit_quantity` DOUBLE NULL DEFAULT '0', + `serie` INT(11) NULL DEFAULT '0', + `resting_time` TIME NULL DEFAULT '00:00:00', + PRIMARY KEY (`exercise_plan_template_detail_id`) USING BTREE, + INDEX `exercise_type_id` (`exercise_type_id`) USING BTREE, + INDEX `exercise_plan_template_id` (`exercise_plan_template_id`) USING BTREE +) +COLLATE='utf8_hungarian_ci' +ENGINE=InnoDB +; + +CREATE TABLE `exercise_plan_template_translation` ( + `translation_id` INT(11) NOT NULL AUTO_INCREMENT, + `exercise_plan_template_id` INT(11) NULL DEFAULT NULL, + `language_code` CHAR(2) NOT NULL DEFAULT '0' COLLATE 'utf8mb4_general_ci', + `name` CHAR(50) NULL DEFAULT '0' COLLATE 'utf8mb4_general_ci', + `description` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', + PRIMARY KEY (`translation_id`) USING BTREE +) +COLLATE='utf8mb4_general_ci' +ENGINE=InnoDB +; + /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; diff --git a/data/db/update_1_0_26.sql b/data/db/update_1_0_26.sql new file mode 100644 index 0000000..b5b11e8 --- /dev/null +++ b/data/db/update_1_0_26.sql @@ -0,0 +1,50 @@ +START TRANSACTION; + +CREATE TABLE `exercise_plan_template` ( + `exercise_plan_template_id` INT(11) NOT NULL AUTO_INCREMENT, + `template_type` ENUM('special','mini_test_set') NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + `name` CHAR(50) NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + `description` TEXT NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + PRIMARY KEY (`exercise_plan_template_id`) USING BTREE, + INDEX `template_type` (`template_type`) USING BTREE +) +COLLATE='utf8_hungarian_ci' +ENGINE=InnoDB +; + +CREATE TABLE `exercise_plan_template_detail` ( + `exercise_plan_template_detail_id` INT(11) NOT NULL AUTO_INCREMENT, + `exercise_plan_template_id` INT(11) NOT NULL DEFAULT '0', + `exercise_type_id` INT(11) NOT NULL DEFAULT '0', + `quantity` DOUBLE NULL DEFAULT '0', + `quantity_unit_quantity` DOUBLE NULL DEFAULT '0', + `serie` INT(11) NULL DEFAULT '0', + `resting_time` TIME NULL DEFAULT '00:00:00', + PRIMARY KEY (`exercise_plan_template_detail_id`) USING BTREE, + INDEX `exercise_type_id` (`exercise_type_id`) USING BTREE, + INDEX `exercise_plan_template_id` (`exercise_plan_template_id`) USING BTREE +) +COLLATE='utf8_hungarian_ci' +ENGINE=InnoDB +; + +CREATE TABLE `exercise_plan_template_translation` ( + `translation_id` INT(11) NOT NULL AUTO_INCREMENT, + `exercise_plan_template_id` INT(11) NULL DEFAULT NULL, + `language_code` CHAR(2) NOT NULL DEFAULT '0' COLLATE 'utf8_hungarian_ci', + `name` CHAR(50) NULL DEFAULT '0' COLLATE 'utf8_hungarian_ci', + `description` TEXT NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + PRIMARY KEY (`translation_id`) USING BTREE +) +COLLATE='utf8_hungarian_ci' +ENGINE=InnoDB +; + +ALTER TABLE `exercise_plan` + ADD COLUMN `type` ENUM('custom','mini_test_set','special') NULL DEFAULT NULL AFTER `date_upd`, + ADD COLUMN `exercise_plan_template_id` INT NULL DEFAULT NULL AFTER `type`; + +UPDATE configuration set config_value = "1.0.26", date_change=CURRENT_DATE WHERE config_key = "db_version"; + +COMMIT; + diff --git a/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt b/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt index 9d0e451..7f27e1a 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt @@ -18,7 +18,8 @@ class PackageController(private val exerciseAbilityRepository: ExerciseAbilityRe private val propertyRepository: PropertyRepository, private val productRepository: ProductRepository, private val exerciseDeviceRepository: ExerciseDeviceRepository, - private val exerciseTreeParentsRepository: ExerciseTreeParentsRepository + private val exerciseTreeParentsRepository: ExerciseTreeParentsRepository, + private val exercisePlanTemplateRepository: ExercisePlanTemplateRepository ) { private val logger = LoggerFactory.getLogger(javaClass) @@ -51,6 +52,9 @@ class PackageController(private val exerciseAbilityRepository: ExerciseAbilityRe val listExerciseTreeParents = exerciseTreeParentsRepository.findAll() val listExerciseTreeParentsJson: String = gson.toJson(listExerciseTreeParents) + val listPlanTemplate = exercisePlanTemplateRepository.findAll() + val listPlanTemplateJson: String = gson.toJson(listPlanTemplate) + val packageJson: String = getClassRecord(ExerciseDevice::class.simpleName, listDevicesJson) + @@ -59,7 +63,8 @@ class PackageController(private val exerciseAbilityRepository: ExerciseAbilityRe "|||" + getClassRecord(ExerciseTree::class.simpleName, listExerciseTreeJson) + "|||" + getClassRecord(ExerciseType::class.simpleName, listExerciseTypeJson) + "|||" + getClassRecord(ExerciseAbility::class.simpleName, listExerciseAbilityJson) + - "|||" + getClassRecord(ExerciseTreeParents::class.simpleName, listExerciseTreeParentsJson) + "|||" + getClassRecord(ExerciseTreeParents::class.simpleName, listExerciseTreeParentsJson) + + "|||" + getClassRecord(ExercisePlanTemplate::class.simpleName, listPlanTemplateJson) return if (packageJson.isEmpty()) ResponseEntity.notFound().build() else ResponseEntity.ok().body(packageJson) diff --git a/src/main/kotlin/com/aitrainer/api/model/ExercisePlanTemplate.kt b/src/main/kotlin/com/aitrainer/api/model/ExercisePlanTemplate.kt new file mode 100644 index 0000000..e19e485 --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/model/ExercisePlanTemplate.kt @@ -0,0 +1,23 @@ +package com.aitrainer.api.model + +import com.google.gson.annotations.Expose +import org.hibernate.annotations.Fetch +import org.hibernate.annotations.FetchMode +import org.springframework.lang.NonNull +import javax.persistence.* + +@Entity +data class ExercisePlanTemplate( + @Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var exercisePlanTemplateId: Int = 0, + @Expose @get: NonNull var name: String? = null, + @Expose @get: NonNull var description: String? = null, + @Expose @get: NonNull var templateType: String? = null +) { + @OneToMany(fetch = FetchType.EAGER, mappedBy = "exercisePlanTemplate") + @Fetch(value = FetchMode.SUBSELECT) + @Expose val translations: List = mutableListOf() + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "exercisePlanTemplate") + @Fetch(value = FetchMode.SUBSELECT) + @Expose val details: List = mutableListOf() +} \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/model/ExercisePlanTemplateDetail.kt b/src/main/kotlin/com/aitrainer/api/model/ExercisePlanTemplateDetail.kt new file mode 100644 index 0000000..cae2058 --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/model/ExercisePlanTemplateDetail.kt @@ -0,0 +1,24 @@ +package com.aitrainer.api.model + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.google.gson.annotations.Expose +import org.springframework.lang.NonNull +import javax.persistence.* +import javax.validation.constraints.Null + +@Entity +data class ExercisePlanTemplateDetail ( + @Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var exercisePlanTemplateDetailId: Long = 0, + @Expose @get: NonNull var exerciseTypeId: Int = 0, + @Expose @get: Null var serie: Int? = 0, + @Expose @get: Null var quantity: Double? = 0.0, + @Expose @get: Null var quantityUnitQuantity: Double? = 0.0, + @Expose @get: NonNull var restingTime: String? = null + + +) { + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "exercisePlanTemplateId", nullable = false) + @JsonIgnore + val exercisePlanTemplate: ExercisePlanTemplate? = null +} \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/model/ExercisePlanTemplateTranslation.kt b/src/main/kotlin/com/aitrainer/api/model/ExercisePlanTemplateTranslation.kt new file mode 100644 index 0000000..39d0cdf --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/model/ExercisePlanTemplateTranslation.kt @@ -0,0 +1,23 @@ +package com.aitrainer.api.model + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.google.gson.annotations.Expose +import javax.persistence.* +import javax.validation.constraints.NotBlank + +@Entity +data class ExercisePlanTemplateTranslation ( + @Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val translationId: Long = 0, + + @Expose @get: NotBlank var languageCode: String?, + @Expose @get: NotBlank var name: String = "", + @Expose @get: NotBlank var description: String = "", + + +) { + @ManyToOne(fetch = FetchType.EAGER, optional = false) + @JoinColumn(name = "exercisePlanTemplateId", nullable = false) + @JsonIgnore + val exercisePlanTemplate: ExercisePlanTemplate? = null + +} diff --git a/src/main/kotlin/com/aitrainer/api/repository/ExercisePlanTemplateRepository.kt b/src/main/kotlin/com/aitrainer/api/repository/ExercisePlanTemplateRepository.kt new file mode 100644 index 0000000..8ba2983 --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/repository/ExercisePlanTemplateRepository.kt @@ -0,0 +1,9 @@ +package com.aitrainer.api.repository + +import com.aitrainer.api.model.ExercisePlanTemplate +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository + +@Repository +interface ExercisePlanTemplateRepository: JpaRepository { +} \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 7f99ae2..db429aa 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -17,6 +17,6 @@ logging.config=classpath:logback-spring.xml logging.file=logs # if the database structure has been changed, increment this version number -application.version=1.0.25 +application.version=1.0.26 jwt.secret=aitrainer \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9e584f4..35f7cfe 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -17,6 +17,6 @@ logging.config=classpath:logback-spring.xml logging.file=logs # if the database structure has been changed, increment this version number -application.version=1.0.25 +application.version=1.0.26 jwt.secret=aitrainer \ No newline at end of file diff --git a/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt b/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt index 4a5c75e..210db1b 100644 --- a/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt @@ -31,6 +31,8 @@ class AppPackageTest { private lateinit var exerciseDeviceRepository: ExerciseDeviceRepository @Autowired private lateinit var exerciseTreeParentsRepository: ExerciseTreeParentsRepository + @Autowired + private lateinit var exercisePlanTemplateRepository: ExercisePlanTemplateRepository @Test fun testAppPackage() { @@ -43,7 +45,8 @@ class AppPackageTest { propertyRepository, productRepository, exerciseDeviceRepository, - exerciseTreeParentsRepository + exerciseTreeParentsRepository, + exercisePlanTemplateRepository ) val response: ResponseEntity<*> = controller.getPackageData() @@ -86,6 +89,16 @@ class AppPackageTest { assertEquals(listParents[2].exerciseTreeParentId, 0) assertEquals(listParents[6].exerciseTreeParentId, 4) assertEquals(listParents[6].exerciseTreeChildId, 9) + } else if (record[0] == ExercisePlanTemplate::class.simpleName) { + val exercisePlanTemplateJson: String = record[1] + val type = object : TypeToken?>() {}.type + val listTemplate: List = gson.fromJson(exercisePlanTemplateJson, type) + assertTrue(listTemplate.isNotEmpty()) + assertEquals(listTemplate[0].name, "Own Body") + assertEquals(listTemplate[0].templateType, "mini_test_set") + assertEquals(listTemplate[0].translations[0].name, "Saját testes tesztek") + assertEquals(listTemplate[0].details[0].exerciseTypeId, 2) + assertEquals(listTemplate[1].details[1].exerciseTypeId, 33) } }