@Transactional
  @Override
  public void saveScheduleForProfessional(
      int idProfessional, int idCareSession, List<ScheduleEntity> schedules) {
    CareSessionEntity careSession = careSessionDao.findById(idCareSession);
    ProfessionalEntity professional = professionalDao.findById(idProfessional);

    Validator.shouldBeFound(careSession);
    Validator.shouldBeFound(professional);

    List<ScheduleEntity> alreadyInDB =
        scheduleDao.findByProfessionalByCareSession(idProfessional, idCareSession);

    // Remove the schedules (with its appointments) no longer present
    List<Integer> idsToRemove = getIdsFromAnotContainedInB(alreadyInDB, schedules);
    if (!idsToRemove.isEmpty()) {
      scheduleDao.deleteSchedulesWithAppointments(idsToRemove);
      scheduleDao.flush();
    }

    // get list of IDs on alreadyInDB but schedules, to erase them
    for (ScheduleEntity se : schedules) {
      se.setProfessional(professional);
      se.setCareSession(careSession);
    }
    // create or update
    scheduleDao.saveAll(schedules);
    scheduleDao.flush();
  }
 private List<ScheduleEntity> makeList(String allSchedules) {
   List<ScheduleEntity> schedules = new ArrayList<ScheduleEntity>();
   String[] parts = allSchedules.split(";");
   for (String p : parts) {
     p = p.trim();
     if (!p.isEmpty()) {
       String[] tokens = p.split(",");
       if (tokens.length == 3) {
         try {
           ScheduleEntity se = new ScheduleEntity();
           String strId = tokens[0].trim();
           if (!strId.isEmpty()) {
             se.setId(Integer.parseInt(strId));
           }
           se.setStartDate(DateUtils.tryParse(tokens[1]));
           se.setEndDate(DateUtils.tryParse(tokens[2]));
           schedules.add(se);
         } catch (ParseException e) {
           // Omit malformed schedule dates
         } catch (NumberFormatException nfe) {
           // Omit malformed schedule id
         }
       }
     }
   }
   return schedules;
 }
  private ProfessionalCalendarBO buildProfessionalCalendar(
      int idProfessional, Integer idCareSession) {
    ProfessionalEntity professional = professionalDao.findById(idProfessional);
    Validator.shouldBeFound(professional);

    CareSessionEntity careSession = null;

    if (idCareSession != null) {
      careSession = careSessionDao.findById(idCareSession);
      Validator.shouldBeFound(careSession);
    }

    List<ScheduleEntity> frees = new ArrayList();
    List<Pair<ScheduleEntity, AppointmentEntity>> taken = new ArrayList();

    List<ScheduleEntity> allSchedules =
        (idCareSession == null
            ? scheduleDao.findByProfessional(idProfessional)
            : scheduleDao.findByProfessionalByCareSession(idProfessional, idCareSession));
    List<AppointmentEntity> allAppointments =
        (idCareSession == null
            ? appointmentDao.findByProfessional(idProfessional)
            : appointmentDao.findByProfessionalByCareSession(idProfessional, idCareSession));

    // allAppointments should be a subset of allSchedules

    // put all the schedules into a hashmap (by id)
    HashMap<Integer, ScheduleEntity> sch = new HashMap();
    for (ScheduleEntity se : allSchedules) {
      sch.put(se.getId(), se);
    }

    // get the schedules related to appointments and put them in taken
    for (AppointmentEntity ae : allAppointments) {
      ScheduleEntity se = sch.remove(ae.getSchedule().getId());
      Pair<ScheduleEntity, AppointmentEntity> pair = new Pair(se, ae);
      taken.add(pair);
    }

    // put the remaining schedules from the hash into frees
    for (Map.Entry<Integer, ScheduleEntity> entry : sch.entrySet()) {
      frees.add(entry.getValue());
    }

    return new ProfessionalCalendarBO(careSession, professional, frees, taken);
  }
 private List<Integer> getIdsFromAnotContainedInB(
     List<ScheduleEntity> listA, List<ScheduleEntity> listB) {
   // To quickly know whether it exists an id in B
   HashMap<Integer, Boolean> bMap = new HashMap();
   for (ScheduleEntity se : listB) {
     if (se.getId() != null) {
       bMap.put(se.getId(), true);
     }
   }
   // only let pass the ids of A that are not in B (result = A\B)
   List<Integer> result = new ArrayList();
   for (ScheduleEntity se : listA) {
     if (se.getId() != null) {
       Boolean isInB = bMap.get(se.getId());
       if (isInB == null || !isInB.booleanValue()) {
         result.add(se.getId());
       }
     }
   }
   return result;
 }