RestaurantMenuService.java
package sk.iway.iwcm.components.restaurant_menu.rest;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import sk.iway.iwcm.Constants;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.common.CloudToolsForCore;
import sk.iway.iwcm.components.restaurant_menu.jpa.AlergenBean;
import sk.iway.iwcm.components.restaurant_menu.jpa.RestaurantMenuEditorFields;
import sk.iway.iwcm.components.restaurant_menu.jpa.RestaurantMenuEntity;
import sk.iway.iwcm.components.restaurant_menu.jpa.RestaurantMenuRepository;
import sk.iway.iwcm.i18n.Prop;
public class RestaurantMenuService {
/**
* Set time part of calendar to 00:00:00.000
* @param cal
*/
private static void nullTimePart(Calendar cal) {
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
}
/**
* NULL - return actual date,
* String - parse to date,
* Date - keep date,
* else - return actual date,
*
* ALL DATE ARE WITHOUT TIME PART -> just like in DB
* @param menuDay
* @return
*/
public static Date getMenuDate(Object menuDay) {
Calendar cal = Calendar.getInstance();
if(menuDay == null) {
cal.setTime(new Date());
} else if(menuDay instanceof String) {
if(Tools.isEmpty((String) menuDay)) {
cal.setTime( new Date() );
} else cal.setTimeInMillis( Long.parseLong((String) menuDay) );
} else if(menuDay instanceof Date) {
cal.setTime((Date) menuDay);
} else { cal.setTime(new Date()); }
nullTimePart(cal);
return cal.getTime();
}
/**
* Get list of all alergens as List<AlergenBean>
* @param request
* @return
*/
public static List<AlergenBean> getAlergenBeans(HttpServletRequest request) {
List<AlergenBean> alergens = new ArrayList<>();
Prop prop = Prop.getInstance(request);
for(int i = 1; i <= Constants.getInt("restaurantMenu.alergensCount"); i++) {
alergens.add(
new AlergenBean(i, prop.getText("components.restaurant_menu.alergen" + i))
);
}
return alergens;
}
/**
* Sort menu by dayDate then by mealCathegory then by priority
* @param menuEntities
* @param addStyle - if true, add addRowClass (for FE in week mode)
* @return
*/
public static List<RestaurantMenuEntity> sortMenu(List<RestaurantMenuEntity> menuEntities, boolean addStyle) {
if (menuEntities == null || menuEntities.isEmpty()) return menuEntities;
//Perform sort
menuEntities = menuEntities.stream().sorted(
Comparator.comparing(
(RestaurantMenuEntity entity) -> entity.getDayDate()
).thenComparing(
(RestaurantMenuEntity entity) -> entity.getEditorFields().getMealCathegory()
).thenComparing(
(RestaurantMenuEntity entity) -> entity.getPriority()
)
).collect(Collectors.toList());
//Add style's -> style is changed when we came from one day to another day menuStyle_0 / menuStyle_1
if(addStyle) {
String dayOfWeek = null;
int type = 0;
for(RestaurantMenuEntity menu : menuEntities) {
if(dayOfWeek == null)
dayOfWeek = menu.getEditorFields().getDayOfWeek();
if(dayOfWeek.equals(menu.getEditorFields().getDayOfWeek())) {
menu.getEditorFields().addRowClass("menuStyle_" + type);
} else {
dayOfWeek = menu.getEditorFields().getDayOfWeek();
type = type == 0 ? 1 : 0;
menu.getEditorFields().addRowClass("menuStyle_" + type);
}
}
}
return menuEntities;
}
/**
* Process params and prepare date range based on menuType
* @param params
*/
public static void processParams(Map<String, String> params) {
String dateRange = null;
String menuType = null;
//Get values from params entry
for (Map.Entry<String, String> entry : params.entrySet()) {
if(entry.getKey().equalsIgnoreCase("searchDayDate")) {
dateRange = entry.getValue();
} else if(entry.getKey().equalsIgnoreCase("menuType")) {
menuType = entry.getValue();
}
}
//Cant work with empty date range
if(dateRange == null) return;
//Because records are set in DB without time part, it's enough to add 1 minute, to get records for this date
//Prepare range gonna have 7 days (week menuType) or 1 day
dateRange = prepareDateRange(dateRange, menuType, true); //-> with prefix because its for params map
params.put("searchDayDate", dateRange);
}
/**
* Prepare date range based on menuType.
*
* menuType = null or days -> 1 day range,
* menuType = week -> 7 days range,
*
* Range is allways + 1m (minute) -> because records are set in DB without time part
* @param dateRange - can be with or without prefix ":daterange" MUST BE ALLWAY only FROM value
* @param menuType
* @param withPrefix - true add prefix ":daterange" (its for params map)
* @return - return range FROM - TO based on input value and menuType
*/
private static String prepareDateRange(String dateRange, String menuType, boolean withPrefix) {
//Can contain daterange: prefix + value FROM (only FROM)
dateRange = dateRange.replaceFirst("daterange:", "");
//Prepare calendar instance and set time to 00:00:00.000
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(Long.parseLong( dateRange ));
nullTimePart(cal);
//If type is not set or is set to days -> 1 day range
if(menuType == null || menuType.equalsIgnoreCase("days")) {
//Just one day -> we must do a range with just 1 minute
cal.add(Calendar.MINUTE, 1);
dateRange += "-" + cal.getTimeInMillis();
} else {
//Week range based allways from MONDAY to SUNDAY (allways 7 days) -> doe not matter, what day of weeek was selected
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
//Preapre ranged based on day of week
if(dayOfWeek == 2) { //Monday
dateRange = cal.getTimeInMillis() + "-";
cal.add( Calendar.DAY_OF_YEAR, 6);
cal.add(Calendar.MINUTE, 1); //Must be add
dateRange += cal.getTimeInMillis();
} else if(dayOfWeek == 1) { //Sunday
cal.add(Calendar.DAY_OF_YEAR, -6);
dateRange = cal.getTimeInMillis() + "-";
cal.add(Calendar.DAY_OF_YEAR, 6);
cal.add(Calendar.MINUTE, 1); //Must be add
dateRange += cal.getTimeInMillis();
} else { //Else
int diff = dayOfWeek - 2;
cal.add(Calendar.DAY_OF_YEAR, -diff);
dateRange = cal.getTimeInMillis() + "-";
cal.add(Calendar.DAY_OF_YEAR, 6);
cal.add(Calendar.MINUTE, 1); //Must be add
dateRange += cal.getTimeInMillis();
}
}
if(withPrefix) return "daterange:" + dateRange;
else return dateRange;
}
/**
* Get list of RestaurantMenuEntity's (menu for one day) based on day. EditorFields is iniialized. Values in list are sorted.
* @param day
* @param prop
* @return
*/
public static List<RestaurantMenuEntity> getByDate(Date day, Prop prop) {
//Get data for day
RestaurantMenuRepository rmr = Tools.getSpringBean("restaurantMenuRepository", RestaurantMenuRepository.class);
List<RestaurantMenuEntity> menuEntities = rmr.findAllByDayDateAndDomainId( getMenuDate(day), CloudToolsForCore.getDomainId() );
//Inicialize editor fields
for(RestaurantMenuEntity menuEntity : menuEntities) {
RestaurantMenuEditorFields editorFields = new RestaurantMenuEditorFields();
editorFields.fromRestaurantMenuEntity(menuEntity, prop);
}
//Return sorted list
return sortMenu(menuEntities, false);
}
/**
* Based on input datepickerWeek, get all records in week. EditorFields is iniialized. Values in list are sorted.
* @param datepickerWeek - accepted formats: yyyy-Www, ww-yyyy (for back compatibility)
* @param prop
* @return
*/
private static List<RestaurantMenuEntity> getWeekByDate(String datepickerWeek, Prop prop) {
Calendar cal = Calendar.getInstance();
//Prepare calendar instance based on week-year / year-week string
if(Tools.isEmpty(datepickerWeek)) {
//Default today
cal.setTime(new Date());
} else if(datepickerWeek.matches("[0-9]+-W[0-9]+")) {
//Format yyyy-Www
String yearWeekArr[] = datepickerWeek.split("-W");
if(yearWeekArr.length == 2) {
cal.set(Calendar.YEAR, Integer.parseInt(yearWeekArr[0]));
cal.set(Calendar.WEEK_OF_YEAR, Integer.parseInt(yearWeekArr[1]));
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
} else cal.setTime(new Date());
} else if(datepickerWeek.matches("[0-9]+-[0-9]+")) {
//Format ww-yyyy
String weekYearArr[] = datepickerWeek.split("-");
if(weekYearArr.length == 2) {
cal.set(Calendar.YEAR, Integer.parseInt(weekYearArr[1]));
cal.set(Calendar.WEEK_OF_YEAR, Integer.parseInt(weekYearArr[0]));
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
} else cal.setTime(new Date());
} else cal.setTime(new Date());
//Prepare date range arr
String dateRange = prepareDateRange("" + cal.getTimeInMillis(), "week", false);
String dateRangeArr[] = dateRange.split("-");
//Get all records in date range
RestaurantMenuRepository rmr = Tools.getSpringBean("restaurantMenuRepository", RestaurantMenuRepository.class);
List<RestaurantMenuEntity> weekMenus = rmr.findAllByDayDateBetweenAndDomainId(
new Date(Long.parseLong(dateRangeArr[0])),
new Date(Long.parseLong(dateRangeArr[1])),
CloudToolsForCore.getDomainId()
);
//Inicialize editor fields
for(RestaurantMenuEntity menuEntity : weekMenus) {
RestaurantMenuEditorFields editorFields = new RestaurantMenuEditorFields();
editorFields.fromRestaurantMenuEntity(menuEntity, prop);
}
//Return sorted list
return sortMenu(weekMenus, false);
}
/**
* Based on input datepickerWeek, get all records in week. EditorFields is iniialized. Values in list are sorted.
*
* List of entities is grouped by day. Each day is one list in list.
*
* @param datepickerWeek - accepted formats: yyyy-Www, ww-yyyy (for back compatibility)
* @param prop
* @return
*/
public static List<List<RestaurantMenuEntity>> getParsedWeekByDate(String datepickerWeek, Prop prop) {
//Get data for week taht are sorted and editor fields are inicialized
List<RestaurantMenuEntity> all = getWeekByDate(datepickerWeek, prop);
if(all == null) return new ArrayList<>();
//Group by day (meke list of lists)
List<List<RestaurantMenuEntity>> week = new ArrayList<>();
int actualIndex = 0;
Date actualDate = null;
for(RestaurantMenuEntity entity : all) {
if(actualDate == null) {
actualDate = entity.getDayDate();
week.add(new ArrayList<>());
}
if(actualDate.compareTo(entity.getDayDate()) == 0) {
week.get(actualIndex).add(entity);
} else {
actualDate = entity.getDayDate();
actualIndex++;
week.add(new ArrayList<>());
week.get(actualIndex).add(entity);
}
}
return week;
}
/***************************** FE METHODS *************************************/
/**
* Prepare value for week datpicekr. Accepted formats: yyyy-Www, ww-yyyy (for back compatibility).
*
* If value is null/empty -> return actual week,
* @param value
* @return Allways return yyyy-Www
*/
public static String getWeekDateValue(String value) {
if(Tools.isEmpty(value)) return getDefaulWeekDateValue();
if(value.matches("[0-9]+-[0-9]+")) {
//FROM ww-yyyy (50-2023) to yyyy-Www (2023-W50)
String[] valueArr = value.split("-");
if(valueArr.length == 2)
return valueArr[1] + "-W" + valueArr[0];
} else return value;
//Some problem, return default date
return getDefaulWeekDateValue();
}
/**
* Return actual week in format yyyy-Www
* @return
*/
private static String getDefaulWeekDateValue() {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
return cal.get(Calendar.YEAR) + "-W" + cal.get(Calendar.WEEK_OF_YEAR);
}
}