Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3fa9db0
done with basic CRUD operations on Vendor and test cases
sanketh221 Nov 10, 2024
4ab86ec
adding back imports
sanketh221 Nov 10, 2024
72a473f
adding back imports
sanketh221 Nov 10, 2024
c603627
refactoring done to move vendor resources to admin package
sanketh221 Nov 10, 2024
8fdf05c
refactoring done to move vendor resources to admin package
sanketh221 Nov 10, 2024
6bf3ca6
Merge remote-tracking branch 'origin/feature/9-admin-vendor-portal' i…
sanketh221 Nov 10, 2024
50bed85
renaming vendor test helper classes to admin
sanketh221 Nov 10, 2024
3a6cd7a
changes done as per review comments
sanketh221 Nov 11, 2024
ce7e923
renamed Dto classes
sanketh221 Nov 11, 2024
965266a
added JPA specifications for searching and controller test cases
sanketh221 Nov 11, 2024
ebfaccf
done with event on-boarding
sanketh2222 Nov 23, 2024
62af140
added test cases of event onboarding testing and refactored event hel…
sanketh2222 Nov 24, 2024
97ba814
some changes after doing self review
sanketh2222 Nov 25, 2024
0d3e230
few small re-factoring in admin service
sanketh2222 Nov 25, 2024
49611f8
changing back BaseAuditingEntity id generation definition
sanketh2222 Nov 25, 2024
d93eb4a
adding additional edge cases and validation notes
sanketh2222 Nov 25, 2024
8599904
Merge branch 'dev' of github.com:sanketh2222/learn-by-coding-communit…
sanketh2222 Nov 26, 2024
0f585e7
Merge pull request #2 from sanketh2222/dev
sanketh2222 Nov 26, 2024
6d835a6
resolving merge conflicts and corrected few failing failed test cases
sanketh2222 Dec 8, 2024
037c87f
PR comments resolution
sanketh2222 Dec 14, 2024
f1076b7
Merge pull request #3 from sanketh2222/dev
sanketh2222 Dec 14, 2024
8213c08
remaining PR comments with N+1 query fix
sanketh2222 Dec 14, 2024
58686b2
Merge remote-tracking branch 'origin/feature/9-admin-vendor-portal' i…
sanketh2222 Dec 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions book-my-show/backend/java/bms-monolith/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@
<version>2.18.0</version> <!-- Use the latest version compatible with your project -->
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>


</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ public class BmsMonolithApplication {
public static void main(String[] args) {
SpringApplication.run(BmsMonolithApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.lbcc.bms.bms_monolith.admin.constants;

public final class BMSConstants {

private BMSConstants() {
}

public static final String VENDOR_SERVICE_ERROR = "VENDOR_SERVICE_ERROR";
public static final String VENDOR_SUCCESS_MESSAGE = "Vendors fetched successfully";
public static final String VENDOR_UPDATE_SUCCESS_MESSAGE = "Vendor status updated successfully";

public static final String VENDOR_NOT_FOUND = "VENDOR_NOT_FOUND";
public static final String INVALID_REQUEST = "INVALID_REQUEST";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.lbcc.bms.bms_monolith.admin.controller;

import jakarta.annotation.Nullable;
import jakarta.websocket.server.PathParam;
import org.lbcc.bms.bms_monolith.admin.dto.VendorOnboardResponse;
import org.lbcc.bms.bms_monolith.admin.constants.BMSConstants;
import org.lbcc.bms.bms_monolith.admin.dto.VendorSearchRequest;
import org.lbcc.bms.bms_monolith.common.entity.Vendor;
import org.lbcc.bms.bms_monolith.common.enums.VendorStatus;
import org.lbcc.bms.bms_monolith.admin.dto.VendorOnboardRequest;
import org.lbcc.bms.bms_monolith.admin.service.AdminService;
import org.lbcc.bms.bms_monolith.common.response.ApiListResponse;
import org.lbcc.bms.bms_monolith.common.response.ApiResponse;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.SortDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expand


//TODO: all these endpoints will be allowed only by ADMIN

@RequestMapping("/vendors")
@RestController
public class AdminVendorOnboardingController {

private final AdminService adminService;

public AdminVendorOnboardingController(AdminService adminService) {
this.adminService = adminService;
}

@PostMapping()
public ResponseEntity<ApiResponse<VendorOnboardResponse>> onboardNewVendor(@RequestBody VendorOnboardRequest vendorOnboardRequest) {
VendorOnboardResponse response = adminService.onboardNewVendor(vendorOnboardRequest);
ApiResponse<VendorOnboardResponse> apiResponse = ApiResponse.<VendorOnboardResponse>builder()
.success(true)
.message(BMSConstants.VENDOR_SUCCESS_MESSAGE)
.data(response)
.build();
return ResponseEntity.status(HttpStatus.CREATED).body(apiResponse);
}

@PutMapping("/{vendorId}/{status}")
public ResponseEntity<ApiResponse<String>> updateVendorStatus(@PathVariable String vendorId, @PathVariable VendorStatus status) {
Vendor vendor = adminService.updatedVendorStatus(vendorId, status);
ApiResponse<String> response = ApiResponse.<String>builder()
.success(true)
.message(BMSConstants.VENDOR_UPDATE_SUCCESS_MESSAGE)
.data(vendor.getId().toString())
.build();
return ResponseEntity.ok(response);
}

@GetMapping
public ResponseEntity<ApiListResponse<Vendor>> getAllVendors(
@Nullable @ModelAttribute() VendorSearchRequest searchRequest,
@PageableDefault(page = 0, size = 10)
@SortDefault(sort = "name", direction = Sort.Direction.ASC) Pageable pageable) {

Page<Vendor> vendorsPage = adminService.searchVendors(searchRequest, pageable);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

service should return Page

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adminService.searchVendors(searchRequest, pageable); method is already returning a Page right,
not understanding this comment

ApiListResponse<Vendor> response = ApiListResponse.<Vendor>builder()
.setPage(vendorsPage)
.success(true)
.message(BMSConstants.VENDOR_SUCCESS_MESSAGE)
.build();
return ResponseEntity.ok(response);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.lbcc.bms.bms_monolith.admin.controller;

import org.lbcc.bms.bms_monolith.admin.dto.seat.SeatTypeResponse;
import org.lbcc.bms.bms_monolith.admin.dto.seat.SeatTypesRequestDto;
import org.lbcc.bms.bms_monolith.common.entity.SeatType;
import org.lbcc.bms.bms_monolith.common.response.ApiListResponse;
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;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/seat-types")
public class SeatTypeController {

private final SeatTypeService seatTypeService;

public SeatTypeController(SeatTypeService seatTypeService) {
this.seatTypeService = seatTypeService;
}

@PostMapping
public ResponseEntity<ApiListResponse<SeatTypeResponse>> createSeatType(@RequestBody SeatTypesRequestDto seatTypesRequestDto) {
SeatTypeResponse response = seatTypeService.createSeatType(seatTypesRequestDto);
ApiListResponse<SeatTypeResponse> apiResponse = ApiListResponse.<SeatTypeResponse>builder()
.success(true).message("Seat types created successfully")
.data(response.getSeatTypeIds().stream()
.map(id -> new SeatTypeResponse(List.of(id)))
.collect(Collectors.toList())).build();
return ResponseEntity.ok(apiResponse);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.lbcc.bms.bms_monolith.admin.controller;

import lombok.extern.slf4j.Slf4j;
import org.lbcc.bms.bms_monolith.admin.dto.seat.SeatTypeDto;
import org.lbcc.bms.bms_monolith.admin.dto.seat.SeatTypeResponse;
import org.lbcc.bms.bms_monolith.admin.dto.seat.SeatTypesRequestDto;
import org.lbcc.bms.bms_monolith.admin.repository.SeatTypeRepository;
import org.lbcc.bms.bms_monolith.common.entity.SeatType;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SeatTypeService {

private final SeatTypeRepository seatTypeRepository;

SeatTypeService(SeatTypeRepository seatTypeRepository) {
this.seatTypeRepository = seatTypeRepository;
}

public SeatTypeResponse createSeatType(SeatTypesRequestDto seatTypesRequestDto) {
log.info("Creating seat type");
List<SeatTypeDto> seatTypeDtos = seatTypesRequestDto.getSeatTypes();
List<SeatType> seatTypes = seatTypeDtos.stream().map(SeatTypeDto::toEntity).toList();
log.info("Saving seat types: {}", seatTypes);
List<SeatType> savedSeatTypes = seatTypeRepository.saveAll(seatTypes);
log.info("Seat types created successfully");
return SeatTypeResponse.from(savedSeatTypes);
}

public List<SeatType> getSeatTypes(List<String> seatTypeIds) {
List<UUID> uuidList = seatTypeIds.stream()
.map(UUID::fromString)
.collect(Collectors.toList());
return seatTypeRepository.findAllById(uuidList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.lbcc.bms.bms_monolith.admin.controller;

import org.lbcc.bms.bms_monolith.admin.dto.venue.VenueAddSeatsRequest;
import org.lbcc.bms.bms_monolith.admin.dto.venue.VenueDto;
import org.lbcc.bms.bms_monolith.admin.dto.venue.VenueOnboardResponse;
import org.lbcc.bms.bms_monolith.admin.service.VenueService;
import org.lbcc.bms.bms_monolith.common.entity.Venue;
import org.lbcc.bms.bms_monolith.common.response.ApiResponse;
import org.springframework.http.HttpStatus;
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("/venues")
public class VenueController {

private final VenueService venueService;

public VenueController(VenueService venueService) {
this.venueService = venueService;
}

//onboard venue
@PostMapping()
public ResponseEntity<?> onboardVenue(@RequestBody VenueDto venueDto) {
VenueOnboardResponse response = venueService.createVenue(venueDto);
ApiResponse<VenueOnboardResponse> apiResponse = ApiResponse.<VenueOnboardResponse>builder()
.success(true).message("Venue onboarded successfully")
.data(response).build();
return ResponseEntity.status(HttpStatus.CREATED).body(apiResponse);
}

//add seats to venue
@PostMapping("/seats")
public ResponseEntity<ApiResponse<Venue>> addSeatsToVenue(@RequestBody VenueAddSeatsRequest request) {
Venue response = venueService.addSeatsToVenue(request.getVenueId(), request.getSeatDtos());
ApiResponse<Venue> apiResponse = ApiResponse.<Venue>builder()
.success(true).message("Seats added successfully")
.data(response).build();
return ResponseEntity.ok(apiResponse);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.lbcc.bms.bms_monolith.admin.dto;

import lombok.Builder;
import lombok.Data;
import org.lbcc.bms.bms_monolith.common.dto.AddressDto;
import org.lbcc.bms.bms_monolith.common.enums.VendorStatus;

import java.util.UUID;

@Data
@Builder
public class VendorDto {

private UUID id;
private String name;
private String contactNumber;
private String email;
private AddressDto address;
private String website;
private String gstNo;
private String panNo;
private VendorStatus status;
private String registrationDate;
private String logoUrl;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.lbcc.bms.bms_monolith.admin.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Builder;
import lombok.Data;
import org.lbcc.bms.bms_monolith.common.dto.AddressDto;
import org.lbcc.bms.bms_monolith.common.entity.Vendor;
import org.lbcc.bms.bms_monolith.common.enums.VendorStatus;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;

@Data
@Builder
public class VendorOnboardRequest {

@NotBlank(message = "Vendor name is required")
@Size(min = 3, max = 30, message = "Vendor name must be at most 30 characters")
private String name;

@NotBlank(message = "Contact is required")
@Pattern(regexp = "^[0-9]{10}$", message = "Invalid contact number. Please provide a 10 digit number.")
private String contactNumber;

@NotBlank(message = "Email is required")
@Pattern(regexp = "^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$", message = "Invalid email format. Please provide a valid email.")
private String email;

@NotBlank(message = "Address is required")
private AddressDto address;

@NotBlank(message = "Website is required")
private String website;

@NotBlank(message = "GST number is required")
@Pattern(regexp = "^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[0-9]{1}[Z]{1}[0-9]{1}$", message = "Invalid GST number. Please provide a valid GST number.")
private String gstNo;

@NotBlank(message = "PAN number is required")
@Pattern(regexp = "^[A-Z]{5}[0-9]{4}[A-Z]{1}$", message = "Invalid PAN number. Please provide a valid PAN number.")
private String panNo;

@NotBlank(message = "Registration date is required")
@Pattern(regexp = "^[0-9]{2}-[0-9]{2}-[0-9]{4}$", message = "Invalid date format. Please use dd-MM-yyyy.")
private String registrationDate;

// @NotNull(message = "Logo is required")
private MultipartFile logoFile;

public static Vendor buildVendorFromDto(VendorOnboardRequest vendorOnboardRequest) {
return Vendor.builder()
.name(vendorOnboardRequest.getName())
.contactNumber(vendorOnboardRequest.getContactNumber())
.email(vendorOnboardRequest.getEmail())
.address(AddressDto.addressDtoToAddress(vendorOnboardRequest.getAddress()))
.website(vendorOnboardRequest.getWebsite())
.gstNo(vendorOnboardRequest.getGstNo())
.panNo(vendorOnboardRequest.getPanNo())
.registrationDate(LocalDateTime.parse(vendorOnboardRequest.getRegistrationDate()))
.logoUrl("logo-url-logo-url-logo-url-logo-url")
.status(VendorStatus.ACTIVE)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.lbcc.bms.bms_monolith.admin.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.lbcc.bms.bms_monolith.common.enums.VendorStatus;

@Data
@AllArgsConstructor
public class VendorOnboardResponse {

private String vendorId;
private String vendorName;
private VendorStatus vendorStatus;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.lbcc.bms.bms_monolith.admin.dto;

import lombok.Data;
import org.apache.commons.lang3.StringUtils;

@Data
public class VendorSearchRequest {

private String vendorName;
private String vendorStatus;
private String registrationDate;

public boolean hasSearchCriteria() {
return !StringUtils.isBlank(vendorName) ||
!StringUtils.isBlank(vendorStatus) ||
!StringUtils.isBlank(registrationDate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.lbcc.bms.bms_monolith.admin.dto;

import lombok.AllArgsConstructor;
import org.lbcc.bms.bms_monolith.common.dto.AddressDto;
import org.lbcc.bms.bms_monolith.common.entity.Vendor;

import java.util.List;

@AllArgsConstructor
public class VendorSearchResponse {
private List<VendorDto> vendorDtoList;

public static VendorDto buildVendorDtoFromVendor(Vendor vendor) {
return VendorDto.builder()
.id(vendor.getId()).name(vendor.getName())
.contactNumber(vendor.getContactNumber()).email(vendor.getEmail())
.address(AddressDto.addressToAddressDto(vendor.getAddress()))
.website(vendor.getWebsite()).gstNo(vendor.getGstNo())
.panNo(vendor.getPanNo()).status(vendor.getStatus())
.registrationDate(String.valueOf(vendor.getRegistrationDate()))
.logoUrl(vendor.getLogoUrl())
.build();
}

public static List<VendorDto> buildVendorDtoListFromVendorList(List<Vendor> vendorList) {
return vendorList.stream().map(VendorSearchResponse::buildVendorDtoFromVendor).toList();
}
}
Loading