DayBookApp.java
package sk.iway.iwcm.components.reservation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ModelAttribute;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import sk.iway.iwcm.Constants;
import sk.iway.iwcm.Identity;
import sk.iway.iwcm.Logger;
import sk.iway.iwcm.PageLng;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.common.CloudToolsForCore;
import sk.iway.iwcm.components.WebjetComponentAbstract;
import sk.iway.iwcm.components.reservation.jpa.ReservationEditorFields;
import sk.iway.iwcm.components.reservation.jpa.ReservationEntity;
import sk.iway.iwcm.components.reservation.jpa.ReservationObjectEntity;
import sk.iway.iwcm.components.reservation.jpa.ReservationObjectPriceRepository;
import sk.iway.iwcm.components.reservation.jpa.ReservationObjectRepository;
import sk.iway.iwcm.components.reservation.jpa.ReservationRepository;
import sk.iway.iwcm.components.reservation.rest.ReservationService;
import sk.iway.iwcm.i18n.Prop;
import sk.iway.iwcm.system.annotations.DefaultHandler;
import sk.iway.iwcm.system.annotations.WebjetAppStore;
import sk.iway.iwcm.system.annotations.WebjetComponent;
import sk.iway.iwcm.system.datatable.DataTableColumnType;
import sk.iway.iwcm.system.datatable.ProcessItemAction;
import sk.iway.iwcm.system.datatable.annotations.DataTableColumn;
import sk.iway.iwcm.system.datatable.annotations.DataTableColumnEditor;
import sk.iway.iwcm.system.datatable.annotations.DataTableColumnEditorAttr;
import sk.iway.iwcm.system.datatable.json.LabelValueInteger;
import sk.iway.iwcm.users.UsersDB;
/**
* App for Booking of rooms, cars, etc. for a whole day.
*/
@WebjetComponent("sk.iway.iwcm.components.reservation.DayBookApp")
@WebjetAppStore(nameKey = "components.reservation.day_book.title", descKey="components.reservation.day_book.desc", imagePath = "ti ti-calendar-dollar text-success bg-light", galleryImages = "/apps/reservation/admin/day-book-screenshot-1.png", commonSettings = true)
@Getter
@Setter
public class DayBookApp extends WebjetComponentAbstract {
@JsonIgnore
private ReservationObjectRepository ror;
@JsonIgnore
private ReservationRepository rr;
@JsonIgnore
private ReservationObjectPriceRepository ropr;
private static final String VIEW_PATH = "/apps/reservation/mvc/day-book"; //NOSONAR
private static final String ERROR_MSG = "components.reservation.reservation_app.save_error";
@Autowired
public DayBookApp(ReservationObjectRepository ror, ReservationRepository rr, ReservationObjectPriceRepository ropr) {
this.ror = ror;
this.rr = rr;
this.ropr = ropr;
}
//Choose reservation object
@DataTableColumn(inputType = DataTableColumnType.MULTISELECT, title = "components.reservation.time_book.reservation_object_ids", tab = "basic", editor = {
@DataTableColumnEditor(
options = {
@DataTableColumnEditorAttr(key = "method:sk.iway.iwcm.components.reservation.rest.ReservationService.getReservationObjectDaysSelectList", value = "label:value")
}
)
})
private String reservationObjectIds;
@Override
public void init(HttpServletRequest request, HttpServletResponse response) {
Logger.debug(TimeBookApp.class, "Init of TimeBookApp app");
}
@DefaultHandler
public String view(Model model, HttpServletRequest request) {
prepareDayBookApp(model, request, null, false);
return VIEW_PATH;
}
public String saveForm(@Valid @ModelAttribute("entity") ReservationEntity entity, BindingResult result, Model model, HttpServletRequest request) {
//result.getAllErrors() IS unmodifiable
List<ObjectError> errors = new ArrayList<>( result.getAllErrors() );
if(!Tools.isEmail(entity.getEmail())) {
errors.add(new FieldError("entity", "email", Prop.getInstance(request).getText("javax.validation.constraints.Email.message")));
}
if(Tools.isEmpty(errors)) {
Prop prop = Prop.getInstance(request);
// ITS GOOD
ReservationEditorFields ref1 = new ReservationEditorFields();
ref1.setArrivingTime( ReservationService.getArrivalTime(entity) );
ref1.setDepartureTime( ReservationService.getDepartureTime(entity) );
entity.setEditorFields(ref1);
ReservationService.prepareDates(entity, true);
try {
ReservationObjectEntity roe = ror.findById(entity.getReservationObjectId()).orElse(null);
if(roe == null) {
//Error
prepareDayBookApp(model, request, entity, true);
model.addAttribute("customError", prop.getText(ERROR_MSG));
return VIEW_PATH;
}
entity.setReservationObjectForReservation(roe);
ReservationEditorFields ref = new ReservationEditorFields();
ref.toReservationEntity(entity, rr, request, true, false, ProcessItemAction.CREATE);
entity.setEditorFields(ref);
} catch (Exception e) {
//Error
prepareDayBookApp(model, request, entity, true);
model.addAttribute("customError", e.getLocalizedMessage());
return VIEW_PATH;
}
//Its CREATE, reservationId is by default -1
int userId = ReservationService.getUserToPay(entity.getEmail(), Long.valueOf(-1), rr, request);
entity.setUserId(userId);
entity.setPrice( ReservationService.calculateReservationPrice(entity, userId, ror, ropr) );
boolean isAccepted = ReservationService.acceptation(entity, request);
rr.save(entity);
//After save send mail
ReservationService reservationService = new ReservationService(prop);
reservationService.sendCreatedReservationEmail(entity, request);
//Add suitable message
if(isAccepted) {
model.addAttribute("saveMsg", prop.getText("components.reservation.reservation_app.save_msg"));
} else {
model.addAttribute("saveMsg", prop.getText("components.reservation.reservation_app.save_msg_acceptation"));
}
//Successfull save
prepareDayBookApp(model, request, entity, false);
return VIEW_PATH;
}
//Error
prepareDayBookApp(model, request, entity, true);
model.addAttribute("errors", Tools.isEmpty(errors) ? null : errors);
return VIEW_PATH;
}
private void prepareDayBookApp(Model model, HttpServletRequest request, ReservationEntity reservation, boolean keepSelection) {
Long selectedReservationId = setSelect(model, request);
model.addAttribute("localization", PageLng.getUserLngIso( Prop.getLng(request, false) ) );
model.addAttribute("currency", Constants.getString("basketProductCurrency") );
model.addAttribute("reservationAllDayStartTime", Constants.getString("reservationAllDayStartTime"));
model.addAttribute("reservationAllDayEndTime", Constants.getString("reservationAllDayEndTime"));
if(reservation == null) {
reservation = new ReservationEntity();
reservation.setReservationObjectId(selectedReservationId);
//User pre-set infos
Identity user = UsersDB.getCurrentUser(request);
if(user != null) {
reservation.setName(user.getFirstName());
reservation.setSurname(user.getLastName());
reservation.setEmail(user.getEmail());
}
} else if(Tools.isNotEmpty(reservation.getActualDate()) || reservation.getDateFrom() != null) {
//Retunrn to same date
Calendar cal = Calendar.getInstance();
//ActualDate prevents a month shift in calendar -> happens when selectwed range in only in right site of calendar (+1 month)
//ActualDate holds allways value of left site of calendar (actual set date)
if(Tools.isNotEmpty(reservation.getActualDate())) {
Date reservationDate = ReservationService.getReservationDate(reservation.getActualDate(), ReservationService.FE_MONTHPICKER_FORMAT);
cal.setTime(reservationDate);
} else {
cal.setTime(reservation.getDateFrom());
}
model.addAttribute("currentYear", cal.get(Calendar.YEAR));
model.addAttribute("currentMonth", cal.get(Calendar.MONTH));
if(keepSelection && reservation.getDateTo() != null) {
//Selected range
model.addAttribute("selectedDateFrom", ReservationService.getDateId(reservation.getDateFrom(), false));
model.addAttribute("selectedDateTo", ReservationService.getDateId(reservation.getDateTo(), false));
}
}
if(!keepSelection) {
//Nullify selection values
reservation.setPrice(null);
reservation.setDateFrom(null);
reservation.setDateTo(null);
reservation.setPurpose(null);
}
model.addAttribute("reservationEntity", reservation);
}
private Long setSelect(Model model, HttpServletRequest request) {
List<LabelValueInteger> reservationObjectSelectOptions = new ArrayList<>();
List<ReservationObjectEntity> reservationObjects;
if(Tools.isNotEmpty(reservationObjectIds)) {
List<Integer> ids = Arrays.stream( Tools.getTokensInt(reservationObjectIds, "+") ).boxed().toList();
reservationObjects = ror.getAllDayReservationsWhereIdsIn(ids);
} else {
// All reservations for full day
reservationObjects = ror.findAllByDomainIdAndReservationForAllDayTrue(CloudToolsForCore.getDomainId());
}
for(ReservationObjectEntity roe : reservationObjects) {
reservationObjectSelectOptions.add(new LabelValueInteger(roe.getName(), roe.getId().intValue()));
}
model.addAttribute("reservationObjects", reservationObjectSelectOptions);
long obtainedReservationId = Tools.getLongValue(request.getParameter("reservation-object-id"), -1);
if(obtainedReservationId != -1) {
boolean isSupported = reservationObjects.stream().anyMatch(ro -> ro.getId().equals(obtainedReservationId));
if(isSupported) {
return obtainedReservationId;
}
}
// Else return default reservation object id)
return reservationObjects.get(0).getId();
}
}