org.openmrs.module.appointmentscheduling.web.controller.AppointmentBlockFormController.java Source code

Java tutorial

Introduction

Here is the source code for org.openmrs.module.appointmentscheduling.web.controller.AppointmentBlockFormController.java

Source

/**
 * The contents of this file are subject to the OpenMRS Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
package org.openmrs.module.appointmentscheduling.web.controller;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.Provider;
import org.openmrs.api.APIException;
import org.openmrs.api.context.Context;
import org.openmrs.module.appointmentscheduling.Appointment;
import org.openmrs.module.appointmentscheduling.Appointment.AppointmentStatus;
import org.openmrs.module.appointmentscheduling.AppointmentBlock;
import org.openmrs.module.appointmentscheduling.AppointmentType;
import org.openmrs.module.appointmentscheduling.AppointmentUtils;
import org.openmrs.module.appointmentscheduling.TimeSlot;
import org.openmrs.module.appointmentscheduling.api.AppointmentService;
import org.openmrs.module.appointmentscheduling.validator.AppointmentBlockValidator;
import org.openmrs.module.appointmentscheduling.web.AppointmentBlockEditor;
import org.openmrs.module.appointmentscheduling.web.AppointmentTypeEditor;
import org.openmrs.module.appointmentscheduling.web.ProviderEditor;
import org.openmrs.web.WebConstants;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Controller for editing appointment types.
 */
@Controller
public class AppointmentBlockFormController {

    /** Logger for this class and subclasses */
    protected final Log log = LogFactory.getLog(getClass());

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(AppointmentType.class, new AppointmentTypeEditor());
        binder.registerCustomEditor(AppointmentBlock.class, new AppointmentBlockEditor());
        binder.registerCustomEditor(Provider.class, new ProviderEditor());
    }

    @RequestMapping(value = "/module/appointmentscheduling/appointmentBlockForm", method = RequestMethod.GET)
    public void showForm(ModelMap model, HttpServletRequest request) throws ParseException {
        if (Context.isAuthenticated()) {
            if (request.getParameter("appointmentBlockId") != null) {
                AppointmentBlock appointmentBlock = getAppointmentBlock(
                        Integer.parseInt(request.getParameter("appointmentBlockId")));
                model.put("appointmentBlock", appointmentBlock);
                model.put("timeSlotLength", getTimeSlotLength(appointmentBlock, null));
            }
            if (request.getParameter("redirectedFrom") != null) {
                String redirectedFrom = (String) request.getParameter("redirectedFrom");
                if (redirectedFrom.equals("appointmentBlockCalendar.list")) {
                    if (request.getParameter("fromDate") != null) {
                        //Update model attribute appointment block
                        AppointmentBlock appointmentBlock = new AppointmentBlock();
                        Date startDate = Context.getDateTimeFormat()
                                .parse((String) request.getParameter("fromDate"));
                        appointmentBlock.setStartDate(startDate);
                        if (request.getParameter("toDate") != null) {
                            Date endDate = Context.getDateTimeFormat()
                                    .parse((String) request.getParameter("toDate"));
                            appointmentBlock.setEndDate(endDate);
                        }
                        model.put("appointmentBlock", appointmentBlock);
                    }
                }
                model.put("redirectedFrom", redirectedFrom);
            }
        }
    }

    @ModelAttribute("appointmentBlock")
    public AppointmentBlock getAppointmentBlock(
            @RequestParam(value = "appointmentBlockId", required = false) Integer appointmentBlockId) {
        AppointmentBlock appointmentBlock = null;

        if (Context.isAuthenticated()) {
            AppointmentService as = Context.getService(AppointmentService.class);
            if (appointmentBlockId != null)
                appointmentBlock = as.getAppointmentBlock(appointmentBlockId);
        }

        if (appointmentBlock == null)
            appointmentBlock = new AppointmentBlock();

        return appointmentBlock;
    }

    @ModelAttribute("timeSlotLength")
    public String getTimeSlotLength(AppointmentBlock appointmentBlock,
            @RequestParam(value = "timeSlotLength", required = false) String timeSlotLength) {
        if (timeSlotLength == null) {
            if (Context.isAuthenticated()) {
                AppointmentService as = Context.getService(AppointmentService.class);
                //If the AppointmentBlock is being Edited than load its slot duration.
                if (appointmentBlock.getCreator() != null) {
                    TimeSlot timeSlot = Context.getService(AppointmentService.class)
                            .getTimeSlotsInAppointmentBlock(appointmentBlock).get(0);
                    return (timeSlot.getEndDate().getTime() - timeSlot.getStartDate().getTime()) / 60000 + "";
                }
                //Else display the default slot length, defined by the global property 'defaultTimeSlotDuration'
                else {
                    String defaultTimeSlotLength = (Context.getAdministrationService()
                            .getGlobalProperty(AppointmentUtils.GP_DEFAULT_TIME_SLOT_DURATION));

                    return defaultTimeSlotLength;
                }
            }
        } else
            return timeSlotLength;

        return "";
    }

    @ModelAttribute("providerList")
    public List<Provider> getProviderList() {
        return Context.getProviderService().getAllProviders();
    }

    @ModelAttribute("appointmentTypeList")
    public List<AppointmentType> getAppointmentTypeList() {
        AppointmentService appointmentService = Context.getService(AppointmentService.class);
        return appointmentService.getAllAppointmentTypesSorted(false);
    }

    @RequestMapping(method = RequestMethod.POST)
    public String onSubmit(HttpServletRequest request, ModelMap model, AppointmentBlock appointmentBlock,
            BindingResult result, @RequestParam(value = "timeSlotLength", required = false) String timeSlotLength,
            @RequestParam(value = "emptyTypes", required = false) String emptyTypes,
            @RequestParam(value = "redirectedFrom", required = false) String redirectedFrom,
            @RequestParam(value = "action", required = false) String action) throws Exception {

        HttpSession httpSession = request.getSession();

        if (Context.isAuthenticated()) {
            if (emptyTypes.equals("yes")) {
                //need to nullify the appointment types.
                appointmentBlock.setTypes(null);
            }
            AppointmentService appointmentService = Context.getService(AppointmentService.class);
            //if the user is voiding the selected appointment block
            if (action != null && action.equals("void")) {
                String voidReason = "Some Reason";//request.getParameter("voidReason");
                if (!(StringUtils.hasText(voidReason))) {
                    httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR,
                            "appointmentscheduling.AppointmentBlock.error.voidReasonEmpty");
                    return null;
                }
                List<TimeSlot> currentTimeSlots = appointmentService
                        .getTimeSlotsInAppointmentBlock(appointmentBlock);
                List<Appointment> appointments = new ArrayList<Appointment>();
                for (TimeSlot timeSlot : currentTimeSlots) {
                    List<Appointment> appointmentsInSlot = appointmentService.getAppointmentsInTimeSlot(timeSlot);
                    for (Appointment appointment : appointmentsInSlot) {
                        appointments.add(appointment);
                    }
                }
                //set appointments statuses from "Scheduled" to "Cancelled".
                for (Appointment appointment : appointments) {
                    if (appointment.getStatus().toString()
                            .equalsIgnoreCase(AppointmentStatus.SCHEDULED.toString())) {
                        appointmentService.changeAppointmentStatus(appointment, AppointmentStatus.CANCELLED);
                    }
                }
                //voiding appointment block
                appointmentService.voidAppointmentBlock(appointmentBlock, voidReason);
                //voiding time slots
                for (TimeSlot timeSlot : currentTimeSlots) {
                    appointmentService.voidTimeSlot(timeSlot, voidReason);

                }
                httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR,
                        "appointmentscheduling.AppointmentBlock.voidedSuccessfully");
            }
            //If the user is purging the AppointmentBlock
            else if (action != null && action.equals("purge")) {
                List<TimeSlot> currentTimeSlots = appointmentService
                        .getTimeSlotsInAppointmentBlock(appointmentBlock);
                //In case there are appointments within the appointment block we don't mind to purge it
                //purging the appointment block
                try {
                    //purging the time slots
                    for (TimeSlot timeSlot : currentTimeSlots) {
                        appointmentService.purgeTimeSlot(timeSlot);
                    }
                    appointmentService.purgeAppointmentBlock(appointmentBlock);
                    httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR,
                            "appointmentscheduling.AppointmentBlock.purgedSuccessfully");
                } catch (DataIntegrityViolationException e) {
                    httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, "error.object.inuse.cannot.purge");
                } catch (APIException e) {
                    httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR,
                            "error.general: " + e.getLocalizedMessage());
                }

            } else if (request.getParameter("save") != null) {
                new AppointmentBlockValidator().validate(appointmentBlock, result);
                if (result.hasErrors()) {
                    return null;
                } else {
                    //Error checking
                    if (appointmentBlock.getStartDate().before(Calendar.getInstance().getTime())) {
                        result.rejectValue("startDate",
                                "appointmentscheduling.AppointmentBlock.error.dateCannotBeInThePast");
                        return null;
                    }
                    if (!appointmentBlock.getStartDate().before(appointmentBlock.getEndDate())) {
                        result.rejectValue("endDate",
                                "appointmentscheduling.AppointmentBlock.error.InvalidDateInterval");
                        return null;
                    }
                    if (timeSlotLength.isEmpty() || Integer.parseInt(timeSlotLength) <= 0) {
                        httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR,
                                "appointmentscheduling.AppointmentBlock.error.selectTimeSlot");
                        return null;
                    }
                    long appointmentBlocklengthInMinutes = (appointmentBlock.getEndDate().getTime()
                            - appointmentBlock.getStartDate().getTime()) / 60000;
                    if (!timeSlotLength.isEmpty()
                            && (Integer.parseInt(timeSlotLength) > appointmentBlocklengthInMinutes)) {
                        httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR,
                                "appointmentscheduling.AppointmentBlock.error.maximalTimeSlot");
                        return null;
                    }
                    List<TimeSlot> currentTimeSlots = null;
                    //if the appointment block is already created and now is being updated
                    if (appointmentBlock.getCreator() != null) {
                        boolean canBeUpdated = true;
                        currentTimeSlots = appointmentService.getTimeSlotsInAppointmentBlock(appointmentBlock);
                        for (TimeSlot timeSlot : currentTimeSlots) {
                            if (appointmentService.getAppointmentsInTimeSlot(timeSlot).size() > 0) {
                                canBeUpdated = false;
                                break;
                            }
                        }
                        if (!canBeUpdated) {
                            httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR,
                                    "appointmentscheduling.AppointmentBlock.error.appointmentsExist");
                            return null;
                        }
                    }
                    //Check if overlapping appointment blocks exist in the system(We will consider Time And Provider only)
                    if (appointmentService.getOverlappingAppointmentBlocks(appointmentBlock).size() > 0) { //Overlapping exists
                        httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR,
                                "appointmentscheduling.AppointmentBlock.error.appointmentBlockOverlap");
                        return null;
                    }
                    //First we need to save the appointment block (before creating the time slot)
                    appointmentService.saveAppointmentBlock(appointmentBlock);
                    //Create the time slots.
                    Integer slotLength = Integer.parseInt(timeSlotLength);
                    int howManyTimeSlotsToCreate = (int) (appointmentBlocklengthInMinutes / slotLength);
                    if (currentTimeSlots == null) {
                        currentTimeSlots = appointmentService.getTimeSlotsInAppointmentBlock(appointmentBlock);
                    }
                    if (currentTimeSlots.size() != howManyTimeSlotsToCreate) { //the time slot length changed therefore we need to update.
                        //First we will purge the current time slots.
                        for (TimeSlot timeSlot : currentTimeSlots) {
                            appointmentService.purgeTimeSlot(timeSlot);
                        }
                        //Then we will add the new time slots corresponding to the new time slot length 
                        Date startDate = appointmentBlock.getStartDate();
                        Date endDate = null;
                        Calendar cal;
                        //Create the time slots except the last one because it might be larger from the rest.
                        for (int i = 0; i < howManyTimeSlotsToCreate - 1; i++) {
                            cal = Context.getDateTimeFormat().getCalendar();
                            cal.setTime(startDate);
                            cal.add(Calendar.MINUTE, slotLength); // add slotLength minutes
                            endDate = cal.getTime();
                            TimeSlot timeSlot = new TimeSlot(appointmentBlock, startDate, endDate);
                            startDate = endDate;
                            appointmentService.saveTimeSlot(timeSlot);
                        }
                        //Create the last time slot that can be larger than the predefined time slot length.
                        TimeSlot timeSlot = new TimeSlot(appointmentBlock, startDate,
                                appointmentBlock.getEndDate());
                        appointmentService.saveTimeSlot(timeSlot);
                    }
                    httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR,
                            "appointmentscheduling.AppointmentBlock.saved");
                }
            }

            // if the user is unvoiding the AppointmentBlock
            else if (request.getParameter("unvoid") != null) {
                appointmentService.unvoidAppointmentBlock(appointmentBlock);
                httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR,
                        "appointmentscheduling.AppointmentBlock.unvoidedSuccessfully");
            }

        }
        return "redirect:" + redirectedFrom;
    }
}