@Getter
@Setter
public class PieChartData {

    private float[] yData;

    private String[] xData;

    public PieChartData(Integer size) {
        this.yData = new float[size];
        this.xData = new String[size];
    }

    public boolean isEmpty() {
        return yData.length == 0;
    }
} @Getter
@Setter
@AllArgsConstructor(suppressConstructorProperties = true)
@NoArgsConstructor
@ToString
@Builder
public class Dish implements Entity {

    private String id;
    private String name;
    private Double price;
    private String description;

    private Map<String, Object> reviews = new LinkedHashMap<>();


    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

} @Getter
@Setter
@AllArgsConstructor(suppressConstructorProperties = true)
@NoArgsConstructor
@ToString
@Builder
public class Image implements Entity {

    private String id;
    private String imageFile;
    private String description;

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

} @Getter
@Setter
@AllArgsConstructor(suppressConstructorProperties = true)
@NoArgsConstructor
@ToString
@Builder
public class Menu implements Entity {

    private String id;
    private String name;
    private Double price;
    private String description;

    private Map<String, Object> mainDishes = new LinkedHashMap<>();
    private Map<String, Object> secondaryDishes = new LinkedHashMap<>();
    private Map<String, Object> otherDishes = new LinkedHashMap<>();
    private Map<String, Object> reviews = new LinkedHashMap<>();

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

} @Getter
@Setter
@AllArgsConstructor(suppressConstructorProperties = true)
@NoArgsConstructor
@ToString
@Builder
public class OpenTime implements Entity {

    private String id;
    private Date startDate;
    private Date endDate;

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

} @Getter
@Setter
@AllArgsConstructor(suppressConstructorProperties = true)
@NoArgsConstructor
@ToString
@Builder
public class Order implements Entity {

    private String id;
    private Date date;
    private Integer tableNumber;
    private Date lastDate;

    private Map<String, Object> orderItems;

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }
} @Getter
@Setter
@AllArgsConstructor(suppressConstructorProperties = true)
@NoArgsConstructor
@ToString
@Builder
public class OrderItem implements Entity {

    private String id;
    private String differentFeature;
    private boolean paid;
    private boolean ready;
    private boolean delivered;
    private String dishId;
    private String menuId;

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }
} @Getter
@Setter
@AllArgsConstructor(suppressConstructorProperties = true)
@NoArgsConstructor
@ToString
@Builder
public class Restaurant implements Entity {

    private String id;
    private String name;
    private String location;
    private Integer phone;
    private String description;
    private String website;
    private Integer numberOfTables;

    private Map<String, Object> openTimes = new LinkedHashMap<>();
    private Map<String, Object> menus = new LinkedHashMap<>();
    private Map<String, Object> dishes = new LinkedHashMap<>();
    private Map<String, Object> users = new LinkedHashMap<>();
    private Map<String, Object> externalOrders = new LinkedHashMap<>();
    private Map<String, Object> reviews = new LinkedHashMap<>();

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

} @Getter
@Setter
@AllArgsConstructor(suppressConstructorProperties = true)
@NoArgsConstructor
@ToString
@Builder
public class Review implements Entity {

    private String id;
    private double points;
    private String comment;
    private String userId;
    private Date date;

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

} @Getter
@Setter
@AllArgsConstructor(suppressConstructorProperties = true)
@NoArgsConstructor
@ToString
@Builder
public class User implements Entity {

    private String id;
    private String email;
    private String name;
    private String lastName;
    private String location;
    private String imageId;

    private Map<String, Object> myRestaurants;
    private Map<String, Object> myOrders;
    private Map<String, Object> ordersToReview;

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }
} public abstract class Repository<T extends Entity> implements ChildEventListener {

    private OnChangedListener listener;

    /**
     * Just for the Firebase when needed
     */
    public Repository () {

    }

    public interface OnChangedListener {
        enum EventType {Added, Changed, Removed, Moved, Full}

        void onChanged(EventType type);
    }

    public void setOnChangedListener(OnChangedListener listener) {
        this.listener = listener;
    }

    public abstract T insert(T item);

    public abstract T insertInternal(T item);

    public abstract T update(T item);

    public abstract T updateInternal(T item);

    public abstract void delete(String id);

    public abstract void deleteInternal(String id);

    public abstract boolean exists(String id);

    public abstract T get(String id);

    public abstract List<T> all();

    protected void notifyChange(OnChangedListener.EventType type) {
        if (listener != null){
            listener.onChanged(type);
        }
    }

    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        insertInternal(convert(dataSnapshot));
        notifyChange(OnChangedListener.EventType.Added);
    }

    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String s) {
        updateInternal(convert(dataSnapshot));
        notifyChange(OnChangedListener.EventType.Changed);
    }

    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {
        deleteInternal(convert(dataSnapshot).getId());
        notifyChange(OnChangedListener.EventType.Removed);
    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String s) {
        updateInternal(convert(dataSnapshot));
        notifyChange(OnChangedListener.EventType.Moved);
    }

    protected abstract T convert(DataSnapshot data);

} public class Preferences {

    private static final String PACKAGE_NAME = "dev.wisebite.wisebite";
    private static final String EMAIL_KEY = "user_email";

    private static SharedPreferences prefs;

    public static void init(Context context) {
        prefs = context.getSharedPreferences(PACKAGE_NAME, Context.MODE_PRIVATE);
    }

    public static String getCurrentUserEmail() {
        if (prefs == null){
            return "";
        }
        return prefs.getString(EMAIL_KEY, "");
    }

    public static void setCurrentUserEmail(String email) {
        if (prefs != null){
            prefs.edit().putString(EMAIL_KEY, email.split("\\.")[0]).apply();
        }
    }

} public abstract class Service<T extends Entity> {

    protected final Repository<T> repository;

    public Service (Repository<T> repository){
        this.repository = repository;
    }

    public T save(T item) {
        if (repository.exists(item.getId())) return repository.update(item);
        return repository.insert(item);
    }

    public T get(String key) {
        return repository.get(key);
    }

    @SuppressWarnings("unused")
    public void delete(String key){
        repository.delete(key);
    }

    @SuppressWarnings("unused")
    public int getAmount(){
        return repository.all().size();
    }

    public List<T> getAll() {
        return repository.all();
    }

    public void setOnChangedListener(Repository.OnChangedListener listener){
        repository.setOnChangedListener(listener);
    }

} public class Utils {

    private static Menu tempMenu;
    private static Date tempDate;
    private static Integer loaded = 0;

    @SuppressWarnings("deprecation")
    public static String parseStartEndDate(TimePicker firstTimePicker, TimePicker secondTimePicker) {
        int firstHour, firstMinute, secondHour, secondMinute;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            firstHour = firstTimePicker.getHour();
            firstMinute = firstTimePicker.getMinute();
            secondHour = secondTimePicker.getHour();
            secondMinute = secondTimePicker.getMinute();
        } else {
            firstHour = firstTimePicker.getCurrentHour();
            firstMinute = firstTimePicker.getCurrentMinute();
            secondHour = secondTimePicker.getCurrentHour();
            secondMinute = secondTimePicker.getCurrentMinute();
        }

        return datesToString(firstHour, firstMinute, secondHour, secondMinute);
    }

    public static String parseStartEndDate(Date startDate, Date endDate) {
        int firstHour, firstMinute, secondHour, secondMinute;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        firstHour = calendar.get(Calendar.HOUR_OF_DAY);
        firstMinute = calendar.get(Calendar.MINUTE);

        calendar.setTime(endDate);
        secondHour = calendar.get(Calendar.HOUR_OF_DAY);
        secondMinute = calendar.get(Calendar.MINUTE);

        return datesToString(firstHour, firstMinute, secondHour, secondMinute);
    }

    @SuppressWarnings("deprecation")
    public static OpenTime createOpenTimeByTimePicker(TimePicker firstTimePicker, TimePicker secondTimePicker, Integer viewId) {
        int dayOfTheWeek = parseViewIdToDayOfWeek(viewId);

        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTimeInMillis(0);
        startCalendar.set(Calendar.DAY_OF_WEEK, dayOfTheWeek);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            startCalendar.set(Calendar.HOUR_OF_DAY, firstTimePicker.getHour());
            startCalendar.set(Calendar.MINUTE, firstTimePicker.getMinute());
        } else {
            startCalendar.set(Calendar.HOUR_OF_DAY, firstTimePicker.getCurrentHour());
            startCalendar.set(Calendar.MINUTE, firstTimePicker.getCurrentMinute());
        }


        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTimeInMillis(0);
        endCalendar.set(Calendar.DAY_OF_WEEK, dayOfTheWeek);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            endCalendar.set(Calendar.HOUR_OF_DAY, secondTimePicker.getHour());
            endCalendar.set(Calendar.MINUTE, secondTimePicker.getMinute());
        } else {
            endCalendar.set(Calendar.HOUR_OF_DAY, secondTimePicker.getCurrentHour());
            endCalendar.set(Calendar.MINUTE, secondTimePicker.getCurrentMinute());
        }

        return OpenTime.builder()
                    .startDate(startCalendar.getTime())
                    .endDate(endCalendar.getTime())
                    .build();
    }

    public static void setTempMenu(Menu menu) {
        tempMenu = menu;
    }

    public static Menu getTempMenu() {
        return tempMenu;
    }

    public static Integer getLoaded() { return loaded; }

    public static void increaseLoaded() { ++loaded; }

    public static String toStringWithTwoDecimals(double d) {
        d = Math.round(d * 100);
        d = d/100;
        return String.valueOf(d);
    }

    public static String getHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);

        String result = "";
        if (hour < 10) result += '0';
        result += String.valueOf(hour) + ':';
        if (minute < 10) result += '0';
        result += String.valueOf(minute);

        return result;
    }

    private static String datesToString(int firstHour, int firstMinute, int secondHour, int secondMinute) {
        String parsed = "";
        if (firstHour < 10) parsed += '0';
        parsed += String.valueOf(firstHour) + ':';
        if (firstMinute < 10) parsed += '0';
        parsed += String.valueOf(firstMinute);

        parsed += " - ";

        if (secondHour < 10) parsed += '0';
        parsed += String.valueOf(secondHour) + ':';
        if (secondMinute < 10) parsed += '0';
        parsed += String.valueOf(secondMinute);
        return parsed;
    }

    public static int parseViewIdToDayOfWeek(Integer viewId) {
        switch (viewId) {
            case R.id.monday_date_picker:
                return Calendar.MONDAY;
            case R.id.tuesday_date_picker:
                return Calendar.TUESDAY;
            case R.id.wednesday_date_picker:
                return Calendar.WEDNESDAY;
            case R.id.thursday_date_picker:
                return Calendar.THURSDAY;
            case R.id.friday_date_picker:
                return Calendar.FRIDAY;
            case R.id.saturday_date_picker:
                return Calendar.SATURDAY;
            case R.id.sunday_date_picker:
                return Calendar.SUNDAY;
            default:
                return 0;
        }
    }

    public static String skipAts(String email) {
        return email.replaceAll("\\.", "@");
    }

    public static boolean isEmpty(String str) {
        return str == null || str.trim().isEmpty();
    }

    public static void setAnalyticsDate(Date date) {
        tempDate = date;
    }

    public static Date getAnalyticsDate() {
        return tempDate;
    }
}
import android.util.Pair;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import dev.wisebite.wisebite.charts.PieChartData;
import dev.wisebite.wisebite.domain.Dish;
import dev.wisebite.wisebite.domain.Image;
import dev.wisebite.wisebite.domain.Menu;
import dev.wisebite.wisebite.domain.OpenTime;
import dev.wisebite.wisebite.domain.Order;
import dev.wisebite.wisebite.domain.OrderItem;
import dev.wisebite.wisebite.domain.Restaurant;
import dev.wisebite.wisebite.domain.Review;
import dev.wisebite.wisebite.domain.User;
import dev.wisebite.wisebite.firebase.Repository;
import dev.wisebite.wisebite.utils.Preferences;
import dev.wisebite.wisebite.utils.Service;
import dev.wisebite.wisebite.utils.Utils;
package dev.wisebite.wisebite.service;




/**
 * Created by albert on 13/03/17.
 * @author albert
 */
public class RestaurantService extends Service<Restaurant> {

    private final Repository<Menu> menuRepository;
    private final Repository<Dish> dishRepository;