Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions book-my-show/backend/java/bms-monolith/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.lbcc.bms.bms_monolith.common.config;

import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

import java.util.Optional;

@EnableJpaAuditing
public class JpaConfig {

@Bean
public AuditorAware<String> auditorProvider() {
return () -> Optional.of("system"); // TODO: Replace with code to fetch username when spring-security is implemented.
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.lbcc.bms.bms_monolith.common.constants;

public final class BMSConstants {

private BMSConstants() {
}

public static final String STATUS_200 = "200";
public static final String MESSAGE_200 = "Request processed successfully";
public static final String EVENT_SUCCESS_MESSAGE = "Events fetched successfully";

Choose a reason for hiding this comment

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

we could use interface for constants , I am not sure creating constant in class

Copy link
Owner

Choose a reason for hiding this comment

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

@nareshthecoder No, interface can be inherited and usually Interface in Java is used to define API not constants.

public static final String UNEXPECTED_ERROR_MESSAGE = "An unexpected error occurred";
public static final String UNEXPECTED_ERROR_CODE = "UNEXPECTED_ERROR";
public static final String EVENT_SERVICE_ERROR = "EVENT_SERVICE_ERROR";
public static final String INVALID_PAGINATION_PARAMETER = "INVALID_PAGINATION_PARAMETER";
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package org.lbcc.bms.bms_monolith.common.entity;

import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.Instant;
import java.util.UUID;
Expand All @@ -17,14 +26,27 @@
@NoArgsConstructor
@Setter
@SuperBuilder
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseAuditingEntity {

@Id
@GeneratedValue(strategy = GenerationType.UUID)
@Column(columnDefinition = "CHAR(36)")
private UUID id;

@CreatedDate
@Column(updatable = false)
private Instant createdDate;

@LastModifiedDate
@Column(insertable = false)
private Instant lastModifiedDate;

@CreatedBy
@Column(updatable = false)
private String createdBy;

@LastModifiedBy
@Column(insertable = false)
private String lastModifiedBy;
Copy link
Owner

Choose a reason for hiding this comment

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

Add method

@AssertTrue(message = "LastModifiedDate should be after createdDate")
private boolean isLastModifiedDateAfterCreatedDate() {
return createdDate == null || lastModifiedDate== null || lastModifiedDate.isAfter(createdDate);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
public class ApiErrorResponse {
private boolean success;
@Builder.Default
private boolean success = false;
private String message;
private String code;
@Builder.Default
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.lbcc.bms.bms_monolith.controller;

import org.lbcc.bms.bms_monolith.common.constants.BMSConstants;
import org.lbcc.bms.bms_monolith.common.response.ApiListResponse;
import org.lbcc.bms.bms_monolith.entity.Event;
import org.lbcc.bms.bms_monolith.service.IEventService;
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.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(path="/events")
public class EventController {

private final IEventService iEventService;

public EventController(IEventService iEventService) {
this.iEventService = iEventService;
}

@GetMapping
public ResponseEntity<ApiListResponse<Event>> getAllEvents(
@PageableDefault(page = 0, size = 10)
@SortDefault(sort = "startDate", direction = Sort.Direction.DESC) Pageable pageable) {

Page<Event> eventsPage = iEventService.getAllEvents(pageable);

ApiListResponse<Event> response = ApiListResponse.<Event>builder()
.success(true)
.message(BMSConstants.EVENT_SUCCESS_MESSAGE)
.setPage(eventsPage)
.build();

return ResponseEntity.ok(response);
}

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

import jakarta.persistence.Entity;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.CascadeType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.FetchType;
import jakarta.persistence.Column;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;

import java.time.Instant;
import java.util.List;

@Entity
@Getter @Setter
@AllArgsConstructor @NoArgsConstructor
public class Event extends BaseAuditingEntity {

@Size(min=10, max=50, message = "Title must be between 10 and 50 characters.")
@Column(nullable = false, length = 50)
private String title;

@Column(length = 1000)
private String description;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "vendor_id")
private Vendor vendor;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "venue_id")
private Venue venue;

@OneToMany(mappedBy = "event", cascade = CascadeType.ALL)
private List<EventShow> show;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "event_type_id")
private EventType eventType;

@Column(nullable = false)
private Instant startDate;

@Column(length = 255)
private String thumbnailUrl;

@Column(nullable = false)
private Instant endDate;

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

import jakarta.persistence.Entity;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.Enumerated;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.EnumType;
import jakarta.persistence.CascadeType;
import jakarta.persistence.FetchType;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;

import lombok.experimental.SuperBuilder;
import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
import org.lbcc.bms.bms_monolith.entity.enums.Genre;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

@Entity
@SuperBuilder
public class EventShow extends BaseAuditingEntity {

@ElementCollection(targetClass = Genre.class)
@CollectionTable(name = "show_genre", joinColumns = @JoinColumn(name = "show_id"))
@Column(name = "genre")
@Enumerated(EnumType.STRING)
private List<Genre> genres;

@NotNull
private Instant startDate;

@NotNull
Copy link
Owner

Choose a reason for hiding this comment

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

@NotNull will enforce a not null check from the application side, but it will not create a NOT NULL constraint on the database end. Bothe has to be added.

What is missing here is the Request, Response, and DTO layers.
@NotNull and similar spring validation should be in Request layer

Entity should have @column(nullable = false)

private Instant endDate;

@ManyToOne
@JoinColumn(name = "event_id", nullable = false)
private Event event;

@OneToMany(mappedBy = "show", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<SeatInShow> seatInShows;
Copy link
Owner

Choose a reason for hiding this comment

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

@Builder.Default
private List seatInShows = new ArrayList<>();


@OneToMany(mappedBy = "show", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<SeatTypeInShow> seatTypeInShows;
Copy link
Owner

Choose a reason for hiding this comment

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

@Builder.Default
private List seatTypeInShows = new ArrayList<>();

}
Copy link
Owner

Choose a reason for hiding this comment

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

Add these methods to the class

public void addSeatInShow(SeatInShow seatInShow) {
this.seatInShows.add(seatInShow);
seatInShow.setShow(this); // Ensures bidirectional relationship consistency
}

public void removeSeatInShow(SeatInShow seatInShow) {
this.seatInShows.remove(seatInShow);
seatInShow.setShow(null); // Clears the relationship
}

public void addSeatTypeInShow(SeatTypeInShow seatTypeInShow) {
this.seatTypeInShows.add(seatTypeInShow);
seatTypeInShow.setShow(this); // Ensures bidirectional relationship consistency
}
@AssertTrue(message = "End date must be after start date")
private boolean isEndDateAfterStartDate() {
return endDate == null || startDate == null || endDate.isAfter(startDate);
}

public List<Genre> getGenres() {
    return Collections.unmodifiableList(genres);
}

public List<SeatInShow> getSeatInShows() {
    return Collections.unmodifiableList(seatInShows);
}

public List<SeatTypeInShow> getSeatTypeInShows() {
    return Collections.unmodifiableList(seatTypeInShows);
}

public void addGenre(Genre genre) {
    this.genres.add(genre);
}

public void removeGenre(Genre genre) {
    this.genres.remove(genre);
}

public void removeSeatTypeInShow(SeatTypeInShow seatTypeInShow) {
this.seatTypeInShows.remove(seatTypeInShow);
seatTypeInShow.setShow(null); // Clears the relationship
}

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

import jakarta.persistence.Entity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
Copy link
Owner

Choose a reason for hiding this comment

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

same as above for annotations

public class EventType extends BaseAuditingEntity {

private String label;
Copy link
Owner

Choose a reason for hiding this comment

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

@SiZe(min = 4, max = 15)
@column(length = 15, nullable = false)
private String label;

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

import jakarta.persistence.Entity;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Enumerated;
import jakarta.persistence.EnumType;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
import org.lbcc.bms.bms_monolith.entity.enums.OperationalStatus;

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
Copy link
Owner

Choose a reason for hiding this comment

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

same as above for annotations

public class Seat extends BaseAuditingEntity {

@ManyToOne
@JoinColumn(name = "seat_type_id")
Copy link
Owner

Choose a reason for hiding this comment

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

nullable = false

private SeatType seatType;

@ManyToOne
@JoinColumn(name = "venue_id")
Copy link
Owner

Choose a reason for hiding this comment

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

nullable = false

private Venue venue;

@Enumerated(EnumType.STRING)
Copy link
Owner

Choose a reason for hiding this comment

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

@Enumerated(EnumType.STRING)
@column(nullable = false)
@Builder.Default
private OperationalStatus operationalStatus = OperationalStatus.OPERATIONAL;

private OperationalStatus operationalStatus;

Copy link
Owner

Choose a reason for hiding this comment

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

@SiZe(min = 4, max = 15, message = "Label should be between 4 and 15 characters")
@column(length = 15, nullable = false)
private String label;

private String label;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.lbcc.bms.bms_monolith.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Enumerated;
import jakarta.persistence.EnumType;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;
import org.lbcc.bms.bms_monolith.entity.enums.BookingStatus;

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
Copy link
Owner

Choose a reason for hiding this comment

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

same as above for annotations

public class SeatInShow extends BaseAuditingEntity {

@ManyToOne
@JoinColumn(name = "seat_type_in_show_id")
Copy link
Owner

Choose a reason for hiding this comment

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

nullable=false

private SeatTypeInShow seatTypeInShow;

@ManyToOne
@JoinColumn(name = "show_id")
private EventShow show;

@Enumerated(EnumType.STRING)
Copy link
Owner

Choose a reason for hiding this comment

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

@Enumerated(EnumType.STRING)
@column(nullable = false)
@Builder.Default
private BookingStatus bookingStatus = BookingStatus.AVAILABLE;

private BookingStatus bookingStatus;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.lbcc.bms.bms_monolith.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;

import java.math.BigDecimal;

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class SeatType extends BaseAuditingEntity {
Copy link
Owner

Choose a reason for hiding this comment

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

same as above for annotations


Copy link
Owner

Choose a reason for hiding this comment

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

@SiZe(min = 4, max = 15, message = "Label should be between 4 and 15 characters")
@column(length = 15, nullable = false)
private String label;

private String label;

@Column(precision = 10, scale = 2)
private BigDecimal price;
Copy link
Owner

Choose a reason for hiding this comment

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

remove price; Price will be part of SeatTypeInShow


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

import jakarta.persistence.Entity;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Column;
import lombok.experimental.SuperBuilder;
import org.lbcc.bms.bms_monolith.common.entity.BaseAuditingEntity;

import java.math.BigDecimal;

@Entity
@SuperBuilder
public class SeatTypeInShow extends BaseAuditingEntity {

@ManyToOne
@JoinColumn(name = "seat_type_id")
Copy link
Owner

Choose a reason for hiding this comment

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

nullable=false

private SeatType seatType;

@ManyToOne
@JoinColumn(name = "show_id")
Copy link
Owner

Choose a reason for hiding this comment

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

nullable = false

private EventShow show;

@Column(precision = 10, scale = 2)
private BigDecimal price;
}
Loading