From 56dd42574ce7c01b84197e880f5f90fea719ab28 Mon Sep 17 00:00:00 2001 From: Dewmin Deniyegedara Date: Thu, 11 Dec 2025 17:50:06 +0530 Subject: [PATCH 1/3] fix:yml issue fixed --- .github/workflows/maven.yml | 107 ++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 59 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 1fcf497..262c948 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,11 +1,3 @@ -# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven - -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - name: Java CI for Embula with Maven on: @@ -16,57 +8,54 @@ on: jobs: build: - runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Set up JDK 21 - uses: actions/setup-java@v4 - with: - java-version: '21' - distribution: 'temurin' - cache: maven - - name: Build with Maven - run: mvn clean install - - - name: Log in to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Build & push Docker image - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile - push: true - tags: docker.io/dewmink/embula-backend:latest - - - name: Deploy to EC2 - uses: appleboy/ssh-action@v0.1.7 - with: - host : ${{secrets.EC2_HOST}} - username : ${{secrets.EC2_USER}} - key: ${{secrets.EC2_KEY}} - script: - docker pull dewmink/embula-backend:latest - docker stop embula-backend || true - docker rm embula-backend || true - docker run -d \ - --name embula-backend \ - -p 8081:8081 \ - -e MYSQL_URL=${{ secrets.MYSQL_URL }} \ - -e Username=${{ secrets.DB_USERNAME }} \ - -e Password=${{ secrets.DB_PASSWORD }} \ - -e JWT_SECRET=${{ secrets.JWT_SECRET }} \ - -e TOKEN_VALIDITY=${{ secrets.TOKEN_VALIDITY }} \ - -e REFRESH_TOKEN_VALIDITY=${{ secrets.REFRESH_TOKEN_VALIDITY }} \ - -e STRIPE_SECRET=${{ secrets.STRIPE_SECRET }} \ - -e EMAIL_USERNAME=${{ secrets.EMAIL_USERNAME }} \ - -e EMAIL_PASSWORD=${{ secrets.EMAIL_PASSWORD }} \ - -e ADMIN_EMAIL=${{ secrets.ADMIN_EMAIL }} \ - dewmink/embula-backend:latest - - + - uses: actions/checkout@v4 + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: maven + + - name: Build with Maven + run: mvn clean install + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build & push Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: true + tags: docker.io/dewmink/embula-backend:latest + + - name: Deploy to EC2 + uses: appleboy/ssh-action@v0.1.7 + with: + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USER }} + key: ${{ secrets.EC2_KEY }} + script: | + docker pull dewmink/embula-backend:latest + docker stop embula-backend || true + docker rm embula-backend || true + docker run -d \ + --name embula-backend \ + -p 8081:8081 \ + -e MYSQL_URL=${{ secrets.MYSQL_URL }} \ + -e Username=${{ secrets.DB_USERNAME }} \ + -e Password=${{ secrets.DB_PASSWORD }} \ + -e JWT_SECRET=${{ secrets.JWT_SECRET }} \ + -e TOKEN_VALIDITY=${{ secrets.TOKEN_VALIDITY }} \ + -e REFRESH_TOKEN_VALIDITY=${{ secrets.REFRESH_TOKEN_VALIDITY }} \ + -e STRIPE_SECRET=${{ secrets.STRIPE_SECRET }} \ + -e EMAIL_USERNAME=${{ secrets.EMAIL_USERNAME }} \ + -e EMAIL_PASSWORD=${{ secrets.EMAIL_PASSWORD }} \ + -e ADMIN_EMAIL=${{ secrets.ADMIN_EMAIL }} \ + dewmink/embula-backend:latest From 69f1077b96df7f327370754aec527b8f489e0e5b Mon Sep 17 00:00:00 2001 From: Dewmin Deniyegedara Date: Sat, 13 Dec 2025 13:12:33 +0530 Subject: [PATCH 2/3] feat:parallel save as an admin for user --- .../controller/AdminController.java | 14 ++++++++++ .../controller/UserController.java | 17 ++++++++++++ .../embula/embula_backend/dto/UserDTO.java | 4 +++ .../repository/AdminRepository.java | 12 +++++++++ .../embula_backend/services/AdminService.java | 3 +++ .../services/impl/AdminServiceIMPL.java | 27 +++++++++++++++++++ .../util/mappers/AdminMappers.java | 13 +++++++++ 7 files changed, 90 insertions(+) create mode 100644 src/main/java/com/embula/embula_backend/controller/AdminController.java create mode 100644 src/main/java/com/embula/embula_backend/repository/AdminRepository.java create mode 100644 src/main/java/com/embula/embula_backend/services/impl/AdminServiceIMPL.java create mode 100644 src/main/java/com/embula/embula_backend/util/mappers/AdminMappers.java diff --git a/src/main/java/com/embula/embula_backend/controller/AdminController.java b/src/main/java/com/embula/embula_backend/controller/AdminController.java new file mode 100644 index 0000000..2509fdb --- /dev/null +++ b/src/main/java/com/embula/embula_backend/controller/AdminController.java @@ -0,0 +1,14 @@ +package com.embula.embula_backend.controller; + +import com.embula.embula_backend.util.StandardResponse; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/admin") +public class AdminController { + +} diff --git a/src/main/java/com/embula/embula_backend/controller/UserController.java b/src/main/java/com/embula/embula_backend/controller/UserController.java index 601f910..cb1548a 100644 --- a/src/main/java/com/embula/embula_backend/controller/UserController.java +++ b/src/main/java/com/embula/embula_backend/controller/UserController.java @@ -1,9 +1,11 @@ package com.embula.embula_backend.controller; +import com.embula.embula_backend.dto.AdminDTO; import com.embula.embula_backend.dto.CustomerDTO; import com.embula.embula_backend.dto.UserDTO; import com.embula.embula_backend.entity.User; import com.embula.embula_backend.repository.UserRepository; +import com.embula.embula_backend.services.AdminService; import com.embula.embula_backend.services.CustomerService; import com.embula.embula_backend.util.StandardResponse; import com.embula.embula_backend.util.mappers.UserMappers; @@ -32,6 +34,9 @@ public class UserController { @Autowired private CustomerService customerService; + @Autowired + private AdminService adminService; + @PostMapping("/register-user") public ResponseEntity saveUser(@RequestBody UserDTO userDTO){ @@ -61,6 +66,17 @@ public ResponseEntity saveUser(@RequestBody UserDTO userDTO){ customerService.saveCustomer(customerDTO); } + // If the user role is ADMIN, also create an admin record + if(userDTO.getRole() != null && userDTO.getRole().equalsIgnoreCase("ADMIN")) { + AdminDTO adminDTO = new AdminDTO(); + adminDTO.setId(String.valueOf(savedUser.getId())); // Same ID as User + adminDTO.setAdminName(userDTO.getAdminName()); + adminDTO.setAdminNumber(userDTO.getAdminNumber()); + + // Save admin + adminService.saveAdmin(adminDTO); + } + responseEntity= new ResponseEntity<>( new StandardResponse(200,"Created", savedUser ), HttpStatus.CREATED @@ -89,4 +105,5 @@ public String forAdmins(){ return "This is Only for Admin"; } + } diff --git a/src/main/java/com/embula/embula_backend/dto/UserDTO.java b/src/main/java/com/embula/embula_backend/dto/UserDTO.java index 55e3b46..bbe618e 100644 --- a/src/main/java/com/embula/embula_backend/dto/UserDTO.java +++ b/src/main/java/com/embula/embula_backend/dto/UserDTO.java @@ -20,4 +20,8 @@ public class UserDTO { private String address; private String phone; private byte[] image; + + // Admin specific fields (optional - only needed when role is ADMIN) + private String adminName; + private String adminNumber; } diff --git a/src/main/java/com/embula/embula_backend/repository/AdminRepository.java b/src/main/java/com/embula/embula_backend/repository/AdminRepository.java new file mode 100644 index 0000000..29bda16 --- /dev/null +++ b/src/main/java/com/embula/embula_backend/repository/AdminRepository.java @@ -0,0 +1,12 @@ +package com.embula.embula_backend.repository; + +import com.embula.embula_backend.entity.Admin; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.stereotype.Repository; + +@Repository +@EnableJpaRepositories +public interface AdminRepository extends JpaRepository { +} + diff --git a/src/main/java/com/embula/embula_backend/services/AdminService.java b/src/main/java/com/embula/embula_backend/services/AdminService.java index 8ba1bf7..a78ac36 100644 --- a/src/main/java/com/embula/embula_backend/services/AdminService.java +++ b/src/main/java/com/embula/embula_backend/services/AdminService.java @@ -1,4 +1,7 @@ package com.embula.embula_backend.services; +import com.embula.embula_backend.dto.AdminDTO; + public interface AdminService { + public String saveAdmin(AdminDTO adminDTO); } diff --git a/src/main/java/com/embula/embula_backend/services/impl/AdminServiceIMPL.java b/src/main/java/com/embula/embula_backend/services/impl/AdminServiceIMPL.java new file mode 100644 index 0000000..5fd70aa --- /dev/null +++ b/src/main/java/com/embula/embula_backend/services/impl/AdminServiceIMPL.java @@ -0,0 +1,27 @@ +package com.embula.embula_backend.services.impl; + +import com.embula.embula_backend.dto.AdminDTO; +import com.embula.embula_backend.entity.Admin; +import com.embula.embula_backend.repository.AdminRepository; +import com.embula.embula_backend.services.AdminService; +import com.embula.embula_backend.util.mappers.AdminMappers; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class AdminServiceIMPL implements AdminService { + + @Autowired + private AdminRepository adminRepository; + + @Autowired + private AdminMappers adminMappers; + + @Override + public String saveAdmin(AdminDTO adminDTO){ + Admin admin = adminMappers.saveAdmin(adminDTO); + adminRepository.save(admin); + return "Admin saved successfully with Id: " + adminDTO.getId(); + } +} + diff --git a/src/main/java/com/embula/embula_backend/util/mappers/AdminMappers.java b/src/main/java/com/embula/embula_backend/util/mappers/AdminMappers.java new file mode 100644 index 0000000..4e0baa1 --- /dev/null +++ b/src/main/java/com/embula/embula_backend/util/mappers/AdminMappers.java @@ -0,0 +1,13 @@ +package com.embula.embula_backend.util.mappers; + +import com.embula.embula_backend.dto.AdminDTO; +import com.embula.embula_backend.entity.Admin; +import org.mapstruct.Mapper; + +@Mapper(componentModel="spring") +public interface AdminMappers { + + Admin saveAdmin(AdminDTO adminDTO); + +} + From ebe245f2390bdf482089a6a58b97f01f2eec76a7 Mon Sep 17 00:00:00 2001 From: Dewmin Deniyegedara Date: Sat, 13 Dec 2025 22:58:29 +0530 Subject: [PATCH 3/3] feat:admin endpoints --- fix_customer_status.sql | 1 + .../advisor/AppWideExceptionHandler.java | 8 ++- .../controller/AdminController.java | 1 - .../controller/FoodItemController.java | 42 +++++++++++++- .../controller/OrderController.java | 17 ++---- .../controller/PaymentController.java | 18 ++++-- .../controller/UserController.java | 56 +++++++++++++++---- .../embula_backend/dto/CustomerDTO.java | 3 +- .../dto/request/AllPaymentDTO.java | 21 +++++++ .../dto/response/ViewCustomerDTO.java | 20 +++++++ .../dto/response/ViewOrderDTO.java | 3 + .../embula_backend/entity/Customer.java | 4 +- .../embula/embula_backend/entity/User.java | 1 - .../converter/CustomerStatusConverter.java | 1 + .../entity/enums/CustomerStatus.java | 5 ++ .../repository/CustomerRepository.java | 3 + .../repository/OrderRepository.java | 2 +- .../repository/UserRepository.java | 4 +- .../services/CustomerService.java | 6 +- .../services/FoodItemService.java | 3 +- .../embula_backend/services/OrderService.java | 3 +- .../services/PaymentService.java | 3 + .../embula_backend/services/UserService.java | 1 + .../services/impl/CustomerServiceIMPL.java | 22 ++++++++ .../services/impl/FoodItemServiceIMPL.java | 45 +++++++++++++-- .../services/impl/OrderServiceIMPL.java | 20 +++---- .../services/impl/PaymentServiceIMPL.java | 12 +++- .../services/impl/UserServiceIMPL.java | 41 +++++++++++++- .../util/mappers/OrderMappers.java | 7 ++- .../util/mappers/PaymentMappers.java | 4 ++ 30 files changed, 318 insertions(+), 59 deletions(-) create mode 100644 fix_customer_status.sql create mode 100644 src/main/java/com/embula/embula_backend/dto/request/AllPaymentDTO.java create mode 100644 src/main/java/com/embula/embula_backend/dto/response/ViewCustomerDTO.java create mode 100644 src/main/java/com/embula/embula_backend/entity/converter/CustomerStatusConverter.java create mode 100644 src/main/java/com/embula/embula_backend/entity/enums/CustomerStatus.java diff --git a/fix_customer_status.sql b/fix_customer_status.sql new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/fix_customer_status.sql @@ -0,0 +1 @@ + diff --git a/src/main/java/com/embula/embula_backend/advisor/AppWideExceptionHandler.java b/src/main/java/com/embula/embula_backend/advisor/AppWideExceptionHandler.java index 570031e..bf28910 100644 --- a/src/main/java/com/embula/embula_backend/advisor/AppWideExceptionHandler.java +++ b/src/main/java/com/embula/embula_backend/advisor/AppWideExceptionHandler.java @@ -43,8 +43,14 @@ protected ResponseEntity handleMethodArgumentNotValid( @ExceptionHandler(Exception.class) public ResponseEntity handleGlobalException(Exception ex, WebRequest request) { + // Log the actual exception for debugging + System.err.println("=== Global Exception Handler ==="); + System.err.println("Exception Type: " + ex.getClass().getName()); + System.err.println("Exception Message: " + ex.getMessage()); + ex.printStackTrace(); + return new ResponseEntity<>( - new StandardResponse(500, "Internal Server Error", "An unexpected error occurred"), + new StandardResponse(500, "Internal Server Error", ex.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR ); } diff --git a/src/main/java/com/embula/embula_backend/controller/AdminController.java b/src/main/java/com/embula/embula_backend/controller/AdminController.java index 2509fdb..fc4b9da 100644 --- a/src/main/java/com/embula/embula_backend/controller/AdminController.java +++ b/src/main/java/com/embula/embula_backend/controller/AdminController.java @@ -1,6 +1,5 @@ package com.embula.embula_backend.controller; -import com.embula.embula_backend.util.StandardResponse; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; diff --git a/src/main/java/com/embula/embula_backend/controller/FoodItemController.java b/src/main/java/com/embula/embula_backend/controller/FoodItemController.java index ceb3887..cf3dcd4 100644 --- a/src/main/java/com/embula/embula_backend/controller/FoodItemController.java +++ b/src/main/java/com/embula/embula_backend/controller/FoodItemController.java @@ -6,6 +6,7 @@ import com.embula.embula_backend.dto.response.FoodItemToMenuDTO; import com.embula.embula_backend.dto.response.ViewFoodItemDTO; import com.embula.embula_backend.entity.FoodItem; +import com.embula.embula_backend.exception.NotFoundException; import com.embula.embula_backend.services.FoodItemService; import com.embula.embula_backend.util.StandardResponse; import org.apache.coyote.Response; @@ -28,11 +29,9 @@ public class FoodItemController { @Autowired private FoodItemService foodItemService; private HandlerMapping resourceHandlerMapping; - - ResponseEntity responseEntity; - @PostMapping(path="saveItem" , consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PreAuthorize("hasRole('ADMIN')") public ResponseEntity saveFoodItem (@RequestPart FoodItemDTO foodItemDTO, @RequestPart MultipartFile imageFile @@ -100,4 +99,41 @@ public ResponseEntity viewFoodItemDetails (@RequestParam long return responseEntity; } + @PutMapping(value = "/{itemId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity updateFoodItem( + @PathVariable long itemId, + @RequestPart(required = false) FoodItemUpdateDTO foodItemUpdateDTO, + @RequestPart(required = false) MultipartFile imageFile + ) { + try { + String message = foodItemService.updateFoodItem(itemId, foodItemUpdateDTO, imageFile); + return new ResponseEntity<>( + new StandardResponse(200, "Success", message), + HttpStatus.OK + ); + } catch (NotFoundException e) { + return new ResponseEntity<>( + new StandardResponse(404, "Not Found", e.getMessage()), + HttpStatus.NOT_FOUND + ); + } catch (Exception e) { + return new ResponseEntity<>( + new StandardResponse(500, "Error", e.getMessage()), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + } + + @DeleteMapping("/{itemId}") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity deleteFoodItem(@PathVariable long itemId){ + String message = foodItemService.deleteFoodItem(itemId); + ResponseEntity responseEntity = new ResponseEntity<>( + new StandardResponse(200,"Success", message), + HttpStatus.OK + ); + return responseEntity; + } + } diff --git a/src/main/java/com/embula/embula_backend/controller/OrderController.java b/src/main/java/com/embula/embula_backend/controller/OrderController.java index 1597343..5f9f152 100644 --- a/src/main/java/com/embula/embula_backend/controller/OrderController.java +++ b/src/main/java/com/embula/embula_backend/controller/OrderController.java @@ -5,6 +5,7 @@ import com.embula.embula_backend.dto.paginated.PaginatedStatusCustomerOrders; import com.embula.embula_backend.dto.request.RequestOrderSaveDTO; import com.embula.embula_backend.dto.response.ViewOrderDTO; +import com.embula.embula_backend.entity.enums.OrderStatus; import com.embula.embula_backend.services.OrderService; import com.embula.embula_backend.util.StandardResponse; import org.apache.coyote.Response; @@ -38,17 +39,12 @@ public ResponseEntity saveOrder (@RequestBody RequestOrderSave } - @GetMapping( - path="viewAllOrders", - params={"page","size"} - ) + @GetMapping(params={"page","size"}) // @Secured({"ROLE_CUSTOMER", "ROLE_ADMIN"}) @PreAuthorize("hasRole('ADMIN')") public ResponseEntity viewOrder( @RequestParam(value="page") int page, @RequestParam(value="size") int size - - ){ // List viewOrderDTO = orderService.viewAllOrders(); PaginatedAllOrders paginatedAllOrders = orderService.viewAllOrders(page,size); @@ -61,14 +57,11 @@ public ResponseEntity viewOrder( } - @PutMapping( - path="cancelOrder", - params="orderId" - ) + @PutMapping(params={"orderId","orderStatus"}) // @Secured("ROLE_CUSTOMER") @PreAuthorize("hasRole('CUSTOMER')") - public ResponseEntity cancelorder(@RequestParam String orderId){ - String message= orderService.cancelOrder(orderId); + public ResponseEntity updateOrderStatus(@RequestParam Long orderId, @RequestParam OrderStatus orderStatus){ + String message= orderService.updateOrderStatus(orderId, orderStatus); ResponseEntity responseEntity = new ResponseEntity<>( new StandardResponse(200,"Success", message), HttpStatus.OK diff --git a/src/main/java/com/embula/embula_backend/controller/PaymentController.java b/src/main/java/com/embula/embula_backend/controller/PaymentController.java index 83a1b85..7949743 100644 --- a/src/main/java/com/embula/embula_backend/controller/PaymentController.java +++ b/src/main/java/com/embula/embula_backend/controller/PaymentController.java @@ -2,6 +2,7 @@ import com.embula.embula_backend.dto.PaymentDTO; +import com.embula.embula_backend.dto.request.AllPaymentDTO; import com.embula.embula_backend.services.PaymentService; import com.embula.embula_backend.util.StandardResponse; import org.apache.coyote.Response; @@ -10,10 +11,9 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.List; @RestController @CrossOrigin @@ -34,4 +34,14 @@ public ResponseEntity savePayments (PaymentDTO paymentDTO) { return responseEntity; } + @GetMapping + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity getAllPayments(){ + List allPaymentDTO = paymentService.getAllPayments(); + ResponseEntity responseEntity = new ResponseEntity<>( + new StandardResponse(200,"Success", allPaymentDTO), + HttpStatus.OK + ); + return responseEntity; + } } diff --git a/src/main/java/com/embula/embula_backend/controller/UserController.java b/src/main/java/com/embula/embula_backend/controller/UserController.java index cb1548a..6e161ac 100644 --- a/src/main/java/com/embula/embula_backend/controller/UserController.java +++ b/src/main/java/com/embula/embula_backend/controller/UserController.java @@ -3,10 +3,12 @@ import com.embula.embula_backend.dto.AdminDTO; import com.embula.embula_backend.dto.CustomerDTO; import com.embula.embula_backend.dto.UserDTO; +import com.embula.embula_backend.dto.response.ViewCustomerDTO; import com.embula.embula_backend.entity.User; import com.embula.embula_backend.repository.UserRepository; import com.embula.embula_backend.services.AdminService; import com.embula.embula_backend.services.CustomerService; +import com.embula.embula_backend.services.UserService; import com.embula.embula_backend.util.StandardResponse; import com.embula.embula_backend.util.mappers.UserMappers; import org.springframework.beans.factory.annotation.Autowired; @@ -17,6 +19,7 @@ import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; +import java.util.List; @RestController @@ -37,6 +40,25 @@ public class UserController { @Autowired private AdminService adminService; + @Autowired + private UserService userService; + + @GetMapping("/customers") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity getAllCustomers(){ + try{ + List customers = customerService.getAllCustomers(); + return new ResponseEntity<>( + new StandardResponse(200,"Success", customers), + HttpStatus.OK + ); + }catch(Exception e){ + return new ResponseEntity<>( + new StandardResponse(500,"Error", e.getMessage()), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + } @PostMapping("/register-user") public ResponseEntity saveUser(@RequestBody UserDTO userDTO){ @@ -59,7 +81,7 @@ public ResponseEntity saveUser(@RequestBody UserDTO userDTO){ customerDTO.setAddress(userDTO.getAddress()); customerDTO.setPhone(userDTO.getPhone()); customerDTO.setImage(userDTO.getImage()); - customerDTO.setStatus("Active"); // Set status to Active + customerDTO.setStatus(com.embula.embula_backend.entity.enums.CustomerStatus.ACTIVE); // Set status to ACTIVE enum customerDTO.setCreatedAt(LocalDateTime.now()); // Save customer @@ -93,17 +115,27 @@ public ResponseEntity saveUser(@RequestBody UserDTO userDTO){ } - @GetMapping("/for-customer") - @PreAuthorize("hasAnyRole('CUSTOMER','ADMIN')") - public String forCustomer(){ - return "This is Only for Customers"; - } - - @GetMapping("/for-admins") + @PatchMapping("/setStatus/{userId}") @PreAuthorize("hasRole('ADMIN')") - public String forAdmins(){ - return "This is Only for Admin"; + public ResponseEntity setUserInactive(@PathVariable String userId){ + try { + String message = userService.setUserInactive(userId); + if(message.contains("updated to Inactive")) { + return new ResponseEntity<>( + new StandardResponse(200, "Success", message), + HttpStatus.OK + ); + } else { + return new ResponseEntity<>( + new StandardResponse(404, "Not Found", message), + HttpStatus.NOT_FOUND + ); + } + } catch (Exception e) { + return new ResponseEntity<>( + new StandardResponse(500, "Error", e.getMessage()), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } } - - } diff --git a/src/main/java/com/embula/embula_backend/dto/CustomerDTO.java b/src/main/java/com/embula/embula_backend/dto/CustomerDTO.java index f85a7a0..92cec22 100644 --- a/src/main/java/com/embula/embula_backend/dto/CustomerDTO.java +++ b/src/main/java/com/embula/embula_backend/dto/CustomerDTO.java @@ -1,4 +1,5 @@ package com.embula.embula_backend.dto; +import com.embula.embula_backend.entity.enums.CustomerStatus; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -16,7 +17,7 @@ public class CustomerDTO { private String firstName; private String lastName; private String email; - private String status; + private CustomerStatus status; private String address; private String phone; private byte[] image; diff --git a/src/main/java/com/embula/embula_backend/dto/request/AllPaymentDTO.java b/src/main/java/com/embula/embula_backend/dto/request/AllPaymentDTO.java new file mode 100644 index 0000000..4e3a3f0 --- /dev/null +++ b/src/main/java/com/embula/embula_backend/dto/request/AllPaymentDTO.java @@ -0,0 +1,21 @@ +package com.embula.embula_backend.dto.request; + +import com.embula.embula_backend.entity.Order; +import com.embula.embula_backend.entity.enums.PaymentMethod; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class AllPaymentDTO { + private PaymentMethod paymentMethod; + private double paymentAmount; + private LocalDateTime paymentDate; +} diff --git a/src/main/java/com/embula/embula_backend/dto/response/ViewCustomerDTO.java b/src/main/java/com/embula/embula_backend/dto/response/ViewCustomerDTO.java new file mode 100644 index 0000000..2d8fa70 --- /dev/null +++ b/src/main/java/com/embula/embula_backend/dto/response/ViewCustomerDTO.java @@ -0,0 +1,20 @@ +package com.embula.embula_backend.dto.response; + +import com.embula.embula_backend.entity.enums.CustomerStatus; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ViewCustomerDTO { + private String id; + private String firstName; + private String lastName; + private String email; + private CustomerStatus status; + private String address; + private String phone; +} + diff --git a/src/main/java/com/embula/embula_backend/dto/response/ViewOrderDTO.java b/src/main/java/com/embula/embula_backend/dto/response/ViewOrderDTO.java index 0d6503d..fde7fa5 100644 --- a/src/main/java/com/embula/embula_backend/dto/response/ViewOrderDTO.java +++ b/src/main/java/com/embula/embula_backend/dto/response/ViewOrderDTO.java @@ -3,6 +3,7 @@ import com.embula.embula_backend.entity.enums.OrderStatus; import com.embula.embula_backend.entity.enums.OrderType; +import com.embula.embula_backend.entity.enums.PaymentMethod; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -21,4 +22,6 @@ public class ViewOrderDTO { private LocalTime orderTime; private OrderStatus orderStatus; //fulfilled or unfulfilled need an enum private OrderType orderType; //pick up or dine-in need an enum + private PaymentMethod orderPaymentMethod; + private double orderPaymentAmount; } diff --git a/src/main/java/com/embula/embula_backend/entity/Customer.java b/src/main/java/com/embula/embula_backend/entity/Customer.java index 596c49b..61ecf82 100644 --- a/src/main/java/com/embula/embula_backend/entity/Customer.java +++ b/src/main/java/com/embula/embula_backend/entity/Customer.java @@ -1,5 +1,6 @@ package com.embula.embula_backend.entity; +import com.embula.embula_backend.entity.enums.CustomerStatus; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; @@ -29,8 +30,9 @@ public class Customer { @Column(name = "email", length = 100) private String email; + @Enumerated(EnumType.STRING) @Column(name = "status", length = 20) - private String status; + private CustomerStatus status; @Column(name = "address", length = 255) private String address; diff --git a/src/main/java/com/embula/embula_backend/entity/User.java b/src/main/java/com/embula/embula_backend/entity/User.java index 6de05ca..73858d6 100644 --- a/src/main/java/com/embula/embula_backend/entity/User.java +++ b/src/main/java/com/embula/embula_backend/entity/User.java @@ -13,7 +13,6 @@ @Table(name="user") public class User { - @Column(name="user_id") private Long id; diff --git a/src/main/java/com/embula/embula_backend/entity/converter/CustomerStatusConverter.java b/src/main/java/com/embula/embula_backend/entity/converter/CustomerStatusConverter.java new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/main/java/com/embula/embula_backend/entity/converter/CustomerStatusConverter.java @@ -0,0 +1 @@ + diff --git a/src/main/java/com/embula/embula_backend/entity/enums/CustomerStatus.java b/src/main/java/com/embula/embula_backend/entity/enums/CustomerStatus.java new file mode 100644 index 0000000..f5b10b5 --- /dev/null +++ b/src/main/java/com/embula/embula_backend/entity/enums/CustomerStatus.java @@ -0,0 +1,5 @@ +package com.embula.embula_backend.entity.enums; + +public enum CustomerStatus { + ACTIVE, INACTIVE +} diff --git a/src/main/java/com/embula/embula_backend/repository/CustomerRepository.java b/src/main/java/com/embula/embula_backend/repository/CustomerRepository.java index d214f3b..f6cfeed 100644 --- a/src/main/java/com/embula/embula_backend/repository/CustomerRepository.java +++ b/src/main/java/com/embula/embula_backend/repository/CustomerRepository.java @@ -5,7 +5,10 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository @EnableJpaRepositories public interface CustomerRepository extends JpaRepository { + Optional findByEmail(String email); } diff --git a/src/main/java/com/embula/embula_backend/repository/OrderRepository.java b/src/main/java/com/embula/embula_backend/repository/OrderRepository.java index 233efdf..3566b5b 100644 --- a/src/main/java/com/embula/embula_backend/repository/OrderRepository.java +++ b/src/main/java/com/embula/embula_backend/repository/OrderRepository.java @@ -13,7 +13,7 @@ @Repository @EnableJpaRepositories -public interface OrderRepository extends JpaRepository { +public interface OrderRepository extends JpaRepository { @Query( value = "SELECT c.first_name AS firstName, c.last_name AS lastName, c.phone AS phone, c.email AS email, " + diff --git a/src/main/java/com/embula/embula_backend/repository/UserRepository.java b/src/main/java/com/embula/embula_backend/repository/UserRepository.java index 03d8610..56fa52d 100644 --- a/src/main/java/com/embula/embula_backend/repository/UserRepository.java +++ b/src/main/java/com/embula/embula_backend/repository/UserRepository.java @@ -5,8 +5,10 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository @EnableJpaRepositories public interface UserRepository extends JpaRepository { - + Optional findById(Long userId); } diff --git a/src/main/java/com/embula/embula_backend/services/CustomerService.java b/src/main/java/com/embula/embula_backend/services/CustomerService.java index 8e62b8e..db4d269 100644 --- a/src/main/java/com/embula/embula_backend/services/CustomerService.java +++ b/src/main/java/com/embula/embula_backend/services/CustomerService.java @@ -1,10 +1,14 @@ package com.embula.embula_backend.services; import com.embula.embula_backend.dto.CustomerDTO; -import com.embula.embula_backend.entity.Customer; +import com.embula.embula_backend.dto.response.ViewCustomerDTO; + +import java.util.List; public interface CustomerService { public String saveCustomer(CustomerDTO customerDTO); + public List getAllCustomers(); + } diff --git a/src/main/java/com/embula/embula_backend/services/FoodItemService.java b/src/main/java/com/embula/embula_backend/services/FoodItemService.java index f68d14a..23dc730 100644 --- a/src/main/java/com/embula/embula_backend/services/FoodItemService.java +++ b/src/main/java/com/embula/embula_backend/services/FoodItemService.java @@ -15,7 +15,8 @@ public interface FoodItemService { public String saveFoodItem(FoodItemDTO foodItemDTO, MultipartFile imageFile) throws IOException; public List getAllFoodItems(); - public String updateFoodItem(long ItemId, FoodItemUpdateDTO foodItemUpdateDTO); + public String updateFoodItem(long itemId, FoodItemUpdateDTO foodItemUpdateDTO, MultipartFile imageFile) throws IOException; public PaginatedAllFoodItems getAllFoodItemsPaginated (int page, int size); public ViewFoodItemDTO viewFoodItem(long itemId); + public String deleteFoodItem(Long itemId); } diff --git a/src/main/java/com/embula/embula_backend/services/OrderService.java b/src/main/java/com/embula/embula_backend/services/OrderService.java index 90d7f3b..28cf400 100644 --- a/src/main/java/com/embula/embula_backend/services/OrderService.java +++ b/src/main/java/com/embula/embula_backend/services/OrderService.java @@ -6,6 +6,7 @@ import com.embula.embula_backend.dto.request.RequestOrderSaveDTO; import com.embula.embula_backend.dto.response.ViewOrderDTO; import com.embula.embula_backend.entity.Payment; +import com.embula.embula_backend.entity.enums.OrderStatus; import java.util.List; @@ -16,6 +17,6 @@ public interface OrderService { public String saveOrderWithPayment(RequestOrderSaveDTO requestOrderSaveDTO, Payment payment); public PaginatedAllOrders viewAllOrders(int page, int size); - public String cancelOrder(String orderId); + public String updateOrderStatus(Long orderId, OrderStatus orderStatus); public PaginatedStatusCustomerOrders statusCustomerOrders(String status, int page , int size); } diff --git a/src/main/java/com/embula/embula_backend/services/PaymentService.java b/src/main/java/com/embula/embula_backend/services/PaymentService.java index c6fc218..ef78111 100644 --- a/src/main/java/com/embula/embula_backend/services/PaymentService.java +++ b/src/main/java/com/embula/embula_backend/services/PaymentService.java @@ -1,8 +1,10 @@ package com.embula.embula_backend.services; import com.embula.embula_backend.dto.PaymentDTO; +import com.embula.embula_backend.dto.request.AllPaymentDTO; import com.embula.embula_backend.entity.Payment; +import java.util.List; import java.util.Optional; public interface PaymentService { @@ -13,4 +15,5 @@ public interface PaymentService { public Optional findByStripePaymentIntentId(String stripePaymentIntentId); + public List getAllPayments(); } diff --git a/src/main/java/com/embula/embula_backend/services/UserService.java b/src/main/java/com/embula/embula_backend/services/UserService.java index 65f677c..902b825 100644 --- a/src/main/java/com/embula/embula_backend/services/UserService.java +++ b/src/main/java/com/embula/embula_backend/services/UserService.java @@ -4,4 +4,5 @@ @Repository public interface UserService { + public String setUserInactive(String userId); } diff --git a/src/main/java/com/embula/embula_backend/services/impl/CustomerServiceIMPL.java b/src/main/java/com/embula/embula_backend/services/impl/CustomerServiceIMPL.java index 7313fb6..58a3a9c 100644 --- a/src/main/java/com/embula/embula_backend/services/impl/CustomerServiceIMPL.java +++ b/src/main/java/com/embula/embula_backend/services/impl/CustomerServiceIMPL.java @@ -1,6 +1,7 @@ package com.embula.embula_backend.services.impl; import com.embula.embula_backend.dto.CustomerDTO; +import com.embula.embula_backend.dto.response.ViewCustomerDTO; import com.embula.embula_backend.entity.Customer; import com.embula.embula_backend.repository.CustomerRepository; import com.embula.embula_backend.services.CustomerService; @@ -8,6 +9,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; +import java.util.stream.Collectors; + @Service public class CustomerServiceIMPL implements CustomerService { @@ -23,4 +27,22 @@ public String saveCustomer(CustomerDTO customerDTO){ customerRepository.save(customer); return "Save Successfull with Id"+ customerDTO.getId(); } + + @Override + public List getAllCustomers(){ + List customers = customerRepository.findAll(); + return customers.stream() + .map(customer -> { + ViewCustomerDTO dto = new ViewCustomerDTO(); + dto.setId(customer.getId()); + dto.setFirstName(customer.getFirstName()); + dto.setLastName(customer.getLastName()); + dto.setEmail(customer.getEmail()); + dto.setStatus(customer.getStatus()); + dto.setAddress(customer.getAddress()); + dto.setPhone(customer.getPhone()); + return dto; + }) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/com/embula/embula_backend/services/impl/FoodItemServiceIMPL.java b/src/main/java/com/embula/embula_backend/services/impl/FoodItemServiceIMPL.java index d9eaba8..7c31093 100644 --- a/src/main/java/com/embula/embula_backend/services/impl/FoodItemServiceIMPL.java +++ b/src/main/java/com/embula/embula_backend/services/impl/FoodItemServiceIMPL.java @@ -55,10 +55,37 @@ public List getAllFoodItems(){ } @Override - public String updateFoodItem (long ItemId, FoodItemUpdateDTO foodItemUpdateDTO){ - if(foodItemRepository.existsById(ItemId)){ - FoodItem foodItem = foodItemRepository.findFoodItemsByItemId(ItemId); - foodItemMappers.updateFoodItem(foodItemUpdateDTO , foodItem); + public String updateFoodItem (long itemId, FoodItemUpdateDTO foodItemUpdateDTO, MultipartFile imageFile) throws IOException { + if(foodItemRepository.existsById(itemId)){ + FoodItem foodItem = foodItemRepository.findFoodItemsByItemId(itemId); + + // Update basic fields from DTO + if(foodItemUpdateDTO.getItemName() != null) { + foodItem.setItemName(foodItemUpdateDTO.getItemName()); + } + if(foodItemUpdateDTO.getIngredients() != null) { + foodItem.setIngredients(foodItemUpdateDTO.getIngredients()); + } + if(foodItemUpdateDTO.getType() != null) { + foodItem.setType(foodItemUpdateDTO.getType()); + } + if(foodItemUpdateDTO.getDescription() != null) { + foodItem.setDescription(foodItemUpdateDTO.getDescription()); + } + if(foodItemUpdateDTO.getPrice() > 0) { + foodItem.setPrice(foodItemUpdateDTO.getPrice()); + } + if(foodItemUpdateDTO.getPortionSize() != null) { + foodItem.setPortionSize(foodItemUpdateDTO.getPortionSize()); + } + + // Update image only if a new image file is provided + if(imageFile != null && !imageFile.isEmpty()) { + foodItem.setImageName(imageFile.getOriginalFilename()); + foodItem.setImageType(imageFile.getContentType()); + foodItem.setImageData(imageFile.getBytes()); + } + foodItemRepository.save(foodItem); return foodItem.getItemId() + " Updated Successfully"; }else{ @@ -90,4 +117,14 @@ public ViewFoodItemDTO viewFoodItem(long itemId){ throw new NotFoundException("Item Not Found"); } } + + @Override + public String deleteFoodItem(Long itemId){ + if(foodItemRepository.existsById(itemId)){ + foodItemRepository.deleteById(itemId); + return "Item "+ itemId + " Deleted Successfully"; + }else{ + throw new NotFoundException("Item Not Found"); + } + } } diff --git a/src/main/java/com/embula/embula_backend/services/impl/OrderServiceIMPL.java b/src/main/java/com/embula/embula_backend/services/impl/OrderServiceIMPL.java index 8fc8754..597af7b 100644 --- a/src/main/java/com/embula/embula_backend/services/impl/OrderServiceIMPL.java +++ b/src/main/java/com/embula/embula_backend/services/impl/OrderServiceIMPL.java @@ -15,10 +15,7 @@ import com.embula.embula_backend.entity.enums.OrderStatus; import com.embula.embula_backend.entity.enums.OrderType; import com.embula.embula_backend.exception.NotFoundException; -import com.embula.embula_backend.repository.CustomerRepository; -import com.embula.embula_backend.repository.FoodItemRepository; -import com.embula.embula_backend.repository.OrderFoodItemRepository; -import com.embula.embula_backend.repository.OrderRepository; +import com.embula.embula_backend.repository.*; import com.embula.embula_backend.services.OrderService; import com.embula.embula_backend.util.mappers.OrderMappers; import jakarta.transaction.Transactional; @@ -57,6 +54,9 @@ public class OrderServiceIMPL implements OrderService { @Autowired private OrderFoodItemRepository orderFoodItemRepo; + @Autowired + private PaymentRepository paymentRepository; + @Override public String saveOrder(RequestOrderSaveDTO requestOrderSaveDTO){ Order order= new Order( @@ -71,7 +71,7 @@ public String saveOrder(RequestOrderSaveDTO requestOrderSaveDTO){ ); orderRepository.save(order); - if(orderRepository.existsById(String.valueOf(order.getOrderId()))){ + if(orderRepository.existsById(order.getOrderId())){ List orderFoodItem= modelMapper.map(requestOrderSaveDTO.getOrderFoodItem(),new TypeToken>(){}.getType()); for(int i=0;i getAllPayments(){ + List payment = paymentRepository.findAll(); + List allPaymentDTO = paymentMappers.paymentToAllPaymentDTO(payment); + return allPaymentDTO; + } + } diff --git a/src/main/java/com/embula/embula_backend/services/impl/UserServiceIMPL.java b/src/main/java/com/embula/embula_backend/services/impl/UserServiceIMPL.java index 27f8dd9..ed2323c 100644 --- a/src/main/java/com/embula/embula_backend/services/impl/UserServiceIMPL.java +++ b/src/main/java/com/embula/embula_backend/services/impl/UserServiceIMPL.java @@ -1,4 +1,43 @@ package com.embula.embula_backend.services.impl; -public class UserServiceIMPL { +import com.embula.embula_backend.entity.Customer; +import com.embula.embula_backend.entity.User; +import com.embula.embula_backend.entity.enums.CustomerStatus; +import com.embula.embula_backend.repository.CustomerRepository; +import com.embula.embula_backend.repository.UserRepository; +import com.embula.embula_backend.services.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UserServiceIMPL implements UserService { + + @Autowired + private UserRepository userRepository; + + @Autowired + private CustomerRepository customerRepository; + + @Override + public String setUserInactive(String userId){ + try { + Long userIdLong = Long.parseLong(userId); + User user = userRepository.findById(userIdLong).orElse(null); + if(user == null){ + return "User not found with Id: " + userId; + } else if (user.getRole().name().equals("CUSTOMER")){ + Customer customer = customerRepository.findByEmail(user.getEmail()).orElse(null); + if(customer == null){ + return "Customer not found with email: " + user.getEmail(); + } + customer.setStatus(CustomerStatus.INACTIVE); + customerRepository.save(customer); + return "Customer status updated to Inactive for userId: " + userId; + } else { + return "User is not a customer, role: " + user.getRole().name(); + } + } catch (NumberFormatException e) { + return "Invalid userId format: " + userId; + } + } } diff --git a/src/main/java/com/embula/embula_backend/util/mappers/OrderMappers.java b/src/main/java/com/embula/embula_backend/util/mappers/OrderMappers.java index 86ce3bd..c046a57 100644 --- a/src/main/java/com/embula/embula_backend/util/mappers/OrderMappers.java +++ b/src/main/java/com/embula/embula_backend/util/mappers/OrderMappers.java @@ -7,6 +7,7 @@ import com.embula.embula_backend.dto.response.ViewOrderDTO; import com.embula.embula_backend.entity.Order; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.springframework.data.domain.Page; import java.util.List; @@ -14,6 +15,10 @@ @Mapper(componentModel = "spring") public interface OrderMappers { Order OrderDTOToOrder(OrderDTO orderDTO); - List OrderToViewOrderDTO(Page orders); + + @Mapping(source = "payment.paymentMethod", target = "orderPaymentMethod") + @Mapping(source = "payment.paymentAmount", target = "orderPaymentAmount") + ViewOrderDTO orderToViewOrderDTO(Order order); + List OrderToViewOrderDTO(List orders); List statusCustomerOrderInterfacesToStatusCustomerOrdersDTO (List statusCustomerOrderInterfaces); } diff --git a/src/main/java/com/embula/embula_backend/util/mappers/PaymentMappers.java b/src/main/java/com/embula/embula_backend/util/mappers/PaymentMappers.java index 1266ebc..1e57d3c 100644 --- a/src/main/java/com/embula/embula_backend/util/mappers/PaymentMappers.java +++ b/src/main/java/com/embula/embula_backend/util/mappers/PaymentMappers.java @@ -1,11 +1,15 @@ package com.embula.embula_backend.util.mappers; import com.embula.embula_backend.dto.PaymentDTO; +import com.embula.embula_backend.dto.request.AllPaymentDTO; import com.embula.embula_backend.entity.Payment; import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import java.util.List; + @Mapper(componentModel = "spring") public interface PaymentMappers { Payment savePayments(PaymentDTO paymentDTO); + List paymentToAllPaymentDTO(List payment); }