diff --git a/data/db/update_1_1_0.sql b/data/db/update_1_1_0.sql index be84e36..bdcff28 100644 --- a/data/db/update_1_1_0.sql +++ b/data/db/update_1_1_0.sql @@ -7,16 +7,19 @@ CREATE TABLE `membership` ( `duration` INT(11) NULL DEFAULT NULL, `duration_type` ENUM('free','subscription','lifetime','limited') NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', `duration_unit` ENUM('day','week','month','year') NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', + `training_plan_id` INT(11) NULL DEFAULT '0', + `training_plan_day_ids` CHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', PRIMARY KEY (`membership_id`) USING BTREE -); + INDEX `training_plan_id` (`training_plan_id`) USING BTREE, +) +ENGINE=InnoDB +; CREATE TABLE `customer_membership` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `customer_id` INT(11) NOT NULL DEFAULT '0', `membership_id` INT(11) NOT NULL DEFAULT '0', `start_date` DATETIME NULL DEFAULT NULL, - `training_plan_id` INT(11) NULL DEFAULT NULL, - `days` CHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', PRIMARY KEY (`id`) USING BTREE, INDEX `customer_id` (`customer_id`) USING BTREE, INDEX `membership_id` (`membership_id`) USING BTREE @@ -36,9 +39,9 @@ ALTER TABLE `customer_training_plan` ALTER TABLE `customer` CHANGE COLUMN `firebase_uid` `firebase_uid` CHAR(200) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci' AFTER `body_type`; ALTER TABLE `customer` - ADD COLUMN `id_token` TEXT NULL DEFAULT NULL AFTER `lang_sync`; + CHANGE COLUMN `firebase_reg_token` `firebase_reg_token` TEXT NULL COLLATE 'utf8mb4_general_ci' AFTER `trial_date`; ALTER TABLE `customer` - ADD INDEX `id_token` (`id_token`); + ADD INDEX `firebase_reg_token` (`firebase_reg_token`); UPDATE configuration set config_value = "1.1.0", date_change=CURRENT_DATE WHERE config_key = "db_version"; diff --git a/readme.MD b/readme.MD index bedc7e1..d027165 100644 --- a/readme.MD +++ b/readme.MD @@ -1,8 +1,10 @@ -#aitrainer server API v1.0.57 +#aitrainer server API v1.1 connects the MYSQL Database provide a RESTful API for the mobile app +Workout Test Club + ##finished API * customers diff --git a/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt b/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt index a6f36d6..c6f36cc 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt @@ -190,24 +190,26 @@ class CustomerController ( private val customerRepository: CustomerRepository) { val signupResponse = firebase.signUp(newUser.email, genPassword) ?: return ResponseEntity.badRequest().body("Firebase exception ${firebase.error}") - val saving_customer = Customer() + val savingCustomer = Customer() if ( serviceBeans == null ) { serviceBeans = ServiceBeans() } - with (saving_customer) { + with (savingCustomer) { email = newUser.email password = serviceBeans!!.passwordEncoder().encode(genPassword) - idToken = signupResponse.idToken + firebaseRegToken = signupResponse.idToken firebaseUid = signupResponse.localId dateAdd = nowFormatted firstname = newUser.firstname name = "" goal = newUser.goal fitnessLevel = newUser.fitnessLevel + birthYear = newUser.birthYear + sex = newUser.sex } - val newCustomer = customerRepository.save(saving_customer) + val newCustomer = customerRepository.save(savingCustomer) if ( newUser.weight != 0.0 ) { val property = CustomerPropertyProperty() @@ -225,13 +227,24 @@ class CustomerController ( private val customerRepository: CustomerRepository) { with (property) { propertyId = 2 propertyValue = newUser.height - dateAdd= nowFormatted + dateAdd = nowFormatted goal = false customer = newCustomer } newCustomer.properties.add(property) } + val newMembershipId = newUser.membershipId + if ( newMembershipId != 0L) { + val membership = CustomerMembership() + with(membership) { + customer = newCustomer + membershipId = newMembershipId + startDate = nowFormatted + } + newCustomer.memberships.add(membership) + } + customerRepository.save(newCustomer) // create email link diff --git a/src/main/kotlin/com/aitrainer/api/controller/CustomerMembershipController.kt b/src/main/kotlin/com/aitrainer/api/controller/CustomerMembershipController.kt index a7cdd9e..29ef325 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/CustomerMembershipController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/CustomerMembershipController.kt @@ -2,6 +2,7 @@ package com.aitrainer.api.controller import com.aitrainer.api.model.CustomerMembership import com.aitrainer.api.repository.CustomerMembershipRepository +import com.aitrainer.api.repository.CustomerRepository import org.slf4j.LoggerFactory import org.springframework.http.ResponseEntity import org.springframework.security.access.annotation.Secured @@ -10,7 +11,7 @@ import javax.validation.Valid @RestController @RequestMapping("/api") -class CustomerMembershipController(private val customerMembershipRepository: CustomerMembershipRepository) { +class CustomerMembershipController(private val customerMembershipRepository: CustomerMembershipRepository, private val customerRepository: CustomerRepository) { private val logger = LoggerFactory.getLogger(javaClass) @PostMapping("/customer_membership") @@ -19,25 +20,12 @@ class CustomerMembershipController(private val customerMembershipRepository: Cus return ResponseEntity.ok().body(customerMembershipRepository.save(customerMembership)) } - @Secured - @PostMapping("customer_membership/update/{id}") - fun updateCustomerMembership(@PathVariable(value = "id") membershipId: Long, - @Valid @RequestBody membershipToUpdate: CustomerMembership): ResponseEntity { - val customerMembership = customerMembershipRepository.findById(membershipId).orElse(null) - ?: return ResponseEntity.notFound().build() - - val updatedCustomerMembership = customerMembership.copy( - trainingPlanId = membershipToUpdate.trainingPlanId, - days = membershipToUpdate.days, - - ) - return ResponseEntity.ok().body(customerMembershipRepository.save(updatedCustomerMembership)) - } - @GetMapping("/customer_membership/{customer_id}") fun getAllByCustomerId(@PathVariable(value = "customer_id") customerId: Long): ResponseEntity> { + val customer = customerRepository.findByCustomerIdAndActive(customerId, "Y") + ?: return ResponseEntity.notFound().build() - val membershipList: List = customerMembershipRepository.findAllByCustomerId(customerId) + val membershipList: List = customerMembershipRepository.findAllByCustomer(customer) logger.info("Get all customer_membership by by customerId") return if(membershipList.isNotEmpty()) diff --git a/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt b/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt index aec8423..45dd41b 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt @@ -47,7 +47,7 @@ class CustomerPackageController( private val customerRepository: CustomerReposit val listTrainingPlan = customerTrainingPlanRepository.findAllByCustomerId(customerId) val listTrainingPlanJson = gson.toJson(listTrainingPlan) - val listMembership = customerMembership.findAllByCustomerId(customerId) + val listMembership = customerMembership.findAllByCustomer(customer) val listMembershipJson = gson.toJson(listMembership) val packageJson: String = diff --git a/src/main/kotlin/com/aitrainer/api/model/ClubUser.kt b/src/main/kotlin/com/aitrainer/api/model/ClubUser.kt index 72e67df..da0b809 100644 --- a/src/main/kotlin/com/aitrainer/api/model/ClubUser.kt +++ b/src/main/kotlin/com/aitrainer/api/model/ClubUser.kt @@ -7,10 +7,13 @@ import kotlinx.serialization.json.* data class ClubUser ( var email: String = "", var firstname: String = "", + var sex: String = "m", + var birthYear: Int = 0, var weight: Double = 0.0, var height: Double = 0.0, var goal: String = "", var fitnessLevel: String = "", + var membershipId: Long = 0, ) { fun fromJson(json: String): ClubUser { return Json.decodeFromString(serializer(), json) diff --git a/src/main/kotlin/com/aitrainer/api/model/Customer.kt b/src/main/kotlin/com/aitrainer/api/model/Customer.kt index e82be34..068bb1e 100644 --- a/src/main/kotlin/com/aitrainer/api/model/Customer.kt +++ b/src/main/kotlin/com/aitrainer/api/model/Customer.kt @@ -34,11 +34,14 @@ data class Customer ( @Expose var lang: String? = null, @Expose var phone: String? = null, @Expose var lifeLong: Int? = null, - @Expose var idToken: String? = null, @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose var customerId: Long = 0, ) { @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.EAGER, mappedBy = "customer") @Fetch(value = FetchMode.SUBSELECT) @Expose val properties: MutableList = mutableListOf() + + @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.EAGER, mappedBy = "customer") + @Fetch(value = FetchMode.SUBSELECT) + @Expose val memberships: MutableList = mutableListOf() } \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/model/CustomerMembership.kt b/src/main/kotlin/com/aitrainer/api/model/CustomerMembership.kt index 467fc05..b7409d7 100644 --- a/src/main/kotlin/com/aitrainer/api/model/CustomerMembership.kt +++ b/src/main/kotlin/com/aitrainer/api/model/CustomerMembership.kt @@ -1,5 +1,6 @@ package com.aitrainer.api.model +import com.fasterxml.jackson.annotation.JsonIgnore import com.google.gson.annotations.Expose import org.springframework.lang.NonNull import jakarta.persistence.* @@ -7,9 +8,10 @@ import jakarta.persistence.* @Entity data class CustomerMembership ( @Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @get: NonNull var id: Long = 0, - @Expose @get: NonNull var customerId: Long = 0, @Expose @get: NonNull var membershipId: Long = 0, @Expose @get: NonNull var startDate: String? = null, - @Expose @get: NonNull var trainingPlanId: Long = 0, - @Expose @get: NonNull var days: String? = null -) \ No newline at end of file +) { + @ManyToOne(fetch = FetchType.EAGER, optional = false) + @JoinColumn(name = "customerId", nullable = false) + @JsonIgnore var customer: Customer? = null +} \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/model/Membership.kt b/src/main/kotlin/com/aitrainer/api/model/Membership.kt index 64c7cdb..786163b 100644 --- a/src/main/kotlin/com/aitrainer/api/model/Membership.kt +++ b/src/main/kotlin/com/aitrainer/api/model/Membership.kt @@ -12,4 +12,6 @@ data class Membership ( @Expose @get: NonNull var duration: Int? = null, @Expose @get: NonNull var durationType: String? = null, @Expose @get: NonNull var durationUnit: String? = null, + @Expose @get: NonNull var trainingPlanId: Long = 0, + @Expose @get: NonNull var trainingPlanDayIds: String? = null ) \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/repository/CustomerMembershipRepository.kt b/src/main/kotlin/com/aitrainer/api/repository/CustomerMembershipRepository.kt index f6c4be0..844d27f 100644 --- a/src/main/kotlin/com/aitrainer/api/repository/CustomerMembershipRepository.kt +++ b/src/main/kotlin/com/aitrainer/api/repository/CustomerMembershipRepository.kt @@ -1,5 +1,6 @@ package com.aitrainer.api.repository +import com.aitrainer.api.model.Customer import com.aitrainer.api.model.CustomerMembership import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query @@ -8,7 +9,7 @@ import org.springframework.stereotype.Repository @Repository interface CustomerMembershipRepository : JpaRepository { @Query(" FROM CustomerMembership " + - " WHERE customerId = :customerId" + " WHERE customer = :customer" ) - fun findAllByCustomerId(customerId: Long): List + fun findAllByCustomer(customer: Customer): List } diff --git a/src/main/kotlin/com/aitrainer/api/service/Firebase.kt b/src/main/kotlin/com/aitrainer/api/service/Firebase.kt index f790ae6..b8eaa6c 100644 --- a/src/main/kotlin/com/aitrainer/api/service/Firebase.kt +++ b/src/main/kotlin/com/aitrainer/api/service/Firebase.kt @@ -59,8 +59,6 @@ class Firebase { error = JSONObject(response.body()).getJSONObject("error").getString("message").toString() return error } - - print("Firebase $command response $response") error = "" return response.body() } diff --git a/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt b/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt index 55040b2..a724977 100644 --- a/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt @@ -80,9 +80,6 @@ class AppCustomerPackageTest { val customerMembershipList: List = gson.fromJson(customerMembershipJson, type) assertEquals(customerMembershipList.size, 2) assertEquals(customerMembershipList[0].membershipId, 1) - assertEquals(customerMembershipList[0].trainingPlanId, 99) - assertEquals(customerMembershipList[0].days, "22|23") - assertEquals(customerMembershipList[1].trainingPlanId, 102) } record[0] == CustomerProperty::class.simpleName -> { diff --git a/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt b/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt index fdf58a6..e38d5b5 100644 --- a/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt @@ -100,6 +100,14 @@ class AppPackageTest { assertEquals(listMembership[1].name, "Lifetime") assertEquals(listMembership[3].durationUnit, "month") assertEquals(listMembership[2].durationType, "limited") + + assertEquals(listMembership.size, 5) + assertEquals(listMembership[0].name, "Free") + assertEquals(listMembership[4].name, "Mezomorph Free 1W") + assertEquals(listMembership[4].duration, 1) + assertEquals(listMembership[4].durationUnit, "week") + assertEquals(listMembership[4].trainingPlanId, 99) + assertEquals(listMembership[4].trainingPlanDayIds, "21|22") } } } diff --git a/src/test/kotlin/com/aitrainer/api/test/CustomerMembershipTest.kt b/src/test/kotlin/com/aitrainer/api/test/CustomerMembershipTest.kt index 6729c9c..e5adfe0 100644 --- a/src/test/kotlin/com/aitrainer/api/test/CustomerMembershipTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/CustomerMembershipTest.kt @@ -1,8 +1,10 @@ package com.aitrainer.api.test import com.aitrainer.api.controller.CustomerMembershipController +import com.aitrainer.api.model.Customer import com.aitrainer.api.model.CustomerMembership import com.aitrainer.api.repository.CustomerMembershipRepository +import com.aitrainer.api.repository.CustomerRepository import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.springframework.beans.factory.annotation.Autowired @@ -15,16 +17,15 @@ import kotlin.test.assertTrue @TestInstance(TestInstance.Lifecycle.PER_CLASS) class CustomerMembershipTest { - private var insertedId: Long = 0 - private var deleteInsert: Boolean = true - @Autowired private lateinit var customerMembershipRepository: CustomerMembershipRepository + @Autowired lateinit var customerRepository: CustomerRepository + @Test fun testCustomerMembershipByCustomerId() { - val controller = CustomerMembershipController(customerMembershipRepository ) + val controller = CustomerMembershipController(customerMembershipRepository, customerRepository ) val response = controller.getAllByCustomerId(90) val properties = response.body @@ -32,65 +33,24 @@ class CustomerMembershipTest { assertTrue(properties is List) assertTrue(properties.isNotEmpty()) assertEquals(properties.size, 2) - assertEquals(properties[0].trainingPlanId, 99) - assertEquals(properties[0].days, "22|23") } @Test fun testInsert() { + /* val foundCustomer: Customer? = customerRepository.findByCustomerIdAndActive(90, "Y") val customerMembership = CustomerMembership( - customerId = 90, membershipId = 3, startDate = "2023-01-30", - trainingPlanId = 103 ) + customerMembership.customer = foundCustomer - val controller = CustomerMembershipController(customerMembershipRepository) + val controller = CustomerMembershipController(customerMembershipRepository, customerRepository) val response = controller.createNewCustomerMembership(customerMembership) val newCustomerMembership = response.body assertTrue(newCustomerMembership is CustomerMembership) - assertEquals(newCustomerMembership.trainingPlanId, 103) - - if ( this.deleteInsert ) { - customerMembershipRepository.delete(customerMembership) - } else { - this.insertedId = newCustomerMembership.id - } - + customerMembershipRepository.delete(newCustomerMembership) // does not delete the customer_membership + */ } - - @Test - fun testUpdate() { - this.deleteInsert = false - this.testInsert() - var customerMembership = CustomerMembership( - customerId = 90, - startDate = "2020-11-10", - trainingPlanId = 99 - ) - val controller = CustomerMembershipController(customerMembershipRepository) - - var response = controller.updateCustomerMembership(this.insertedId, customerMembership) - - assertTrue(response.body is CustomerMembership) - val updated = response.body - assertEquals(updated!!.trainingPlanId, 99) - assertEquals(updated.startDate, "2023-01-30 00:00:00" ) - customerMembershipRepository.delete(updated) - - //notFound - customerMembership = CustomerMembership( - id = 10000, - startDate = "2021-02-15", - trainingPlanId = 83 - ) - response = controller.updateCustomerMembership(customerMembership.id, customerMembership) - assertEquals(response.statusCode, HttpStatus.NOT_FOUND) - - - - } - } \ No newline at end of file diff --git a/src/test/kotlin/com/aitrainer/api/test/CustomerTests.kt b/src/test/kotlin/com/aitrainer/api/test/CustomerTests.kt index 7f2bc23..dde9a55 100644 --- a/src/test/kotlin/com/aitrainer/api/test/CustomerTests.kt +++ b/src/test/kotlin/com/aitrainer/api/test/CustomerTests.kt @@ -238,17 +238,6 @@ class CustomerTests { val controller = CustomerController(customerRepository) val response: ResponseEntity<*> = controller.clubRegistration(json) assertEquals(response.statusCode, HttpStatus.BAD_REQUEST) - -/* - json = "{\"firstname\":\"Tib\", \"email\": \"mr@workouttest.com\", \"goal\": \"shape\", \"fitnessLevel\": \"advanced\", \"weight\": 85}"; - response = controller.clubRegistration(json) - assertEquals(response.statusCode, HttpStatus.OK) - val newCustomer: Customer = response.body as Customer - assertTrue(newCustomer.firebaseUid!!.isNotEmpty()) - val firebase = Firebase() - firebase.deleteUser(newCustomer.firebaseUid!!) - customerRepository.delete(newCustomer) -*/ } @Test