--- /dev/null
+/*******************************************************************************
+ * Copyright � Igor Barma, Alexandre Desoubeaux, Christian Martel, Eric Brun, Mathieu Amblard, Gwenael Gevet, Pierre Guillot, 2012
+ * Copyright Alexandre Desoubeaux, Christian Martel, Cedric Lecarpentier, Alexandre Lefevre, Marc Salvat 2014-2016
+ * Copyright Alexandre Desoubeaux, Christian Martel, Cedric Lecarpentier, Marc Salvat, Marc Suarez, Harifetra Ramamonjy 2017
+ *
+ * This file is part of the work and learning management system Pentila Nero.
+ *
+ * Pentila Nero is free software. You can redistribute it and/or modify since
+ * you respect the terms of either (at least one of the both license) :
+ * - under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * - the CeCILL-C as published by CeCILL-C; either version 1 of the
+ * License, or any later version
+ * - the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the license,
+ * or (at your option) any later version.
+ *
+ * There are special exceptions to the terms and conditions of the
+ * licenses as they are applied to this software. View the full text of
+ * the exception in file LICENSE-PROJECT.txt in the directory of this software
+ * distribution.
+ *
+ * Pentila Nero is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Licenses for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * and the CeCILL-C and the GNU Lesser General Public License along with
+ * Pentila Nero. If not, see :
+ * <http://www.gnu.org/licenses/> and
+ * <http://www.cecill.info/licences.fr.html>.
+ ******************************************************************************/
+package com.pentila.entSavoie.agenda.service.impl;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import com.liferay.contacts.util.OrganizationFilter;
+import com.liferay.portal.kernel.exception.PortalException;
+import com.liferay.portal.kernel.exception.SystemException;
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
+import com.liferay.portal.kernel.search.BooleanClauseOccur;
+import com.liferay.portal.kernel.search.BooleanQuery;
+import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
+import com.liferay.portal.kernel.search.Field;
+import com.liferay.portal.kernel.search.Hits;
+import com.liferay.portal.kernel.search.Indexer;
+import com.liferay.portal.kernel.search.IndexerRegistryUtil;
+import com.liferay.portal.kernel.search.SearchContext;
+import com.liferay.portal.kernel.search.SearchEngineUtil;
+import com.liferay.portal.kernel.search.SearchException;
+import com.liferay.portal.kernel.search.SolrQueryUtil;
+import com.liferay.portal.model.Organization;
+import com.liferay.portal.model.User;
+import com.liferay.portal.service.RoleLocalServiceUtil;
+import com.liferay.portal.service.UserLocalServiceUtil;
+import com.pentila.entSavoie.agenda.model.EventAgenda;
+import com.pentila.entSavoie.agenda.model.Ressource;
+import com.pentila.entSavoie.agenda.model.RessourceRole;
+import com.pentila.entSavoie.agenda.model.RessourceUser;
+import com.pentila.entSavoie.agenda.service.RessourceLocalServiceUtil;
+import com.pentila.entSavoie.agenda.service.RessourceRoleLocalServiceUtil;
+import com.pentila.entSavoie.agenda.service.RessourceUserLocalServiceUtil;
+import com.pentila.entSavoie.agenda.service.base.EventAgendaLocalServiceBaseImpl;
+import com.pentila.entSavoie.agenda.util.EventAgendaIndexer;
+
+
+public class EventAgendaLocalServiceImpl extends EventAgendaLocalServiceBaseImpl {
+
+ public EventAgenda addEventAgenda() throws SystemException {
+ final long evtId = counterLocalService.increment();
+ final EventAgenda eventAgenda = this.createEventAgenda(evtId);
+ return eventAgenda;
+ }
+
+ public EventAgenda addEventAgenda(long companyId, long userId, long calId, Date startDay, Date endDay, String title, String location, String notes, String url, Boolean allDay, String remind, String recuRule, long repeatEvtId) throws SystemException{
+ return addEventAgenda(companyId, userId, calId, startDay, endDay, title, location, notes, url, allDay, remind, recuRule, repeatEvtId, "", true);
+ }
+
+ public EventAgenda addEventAgenda(long companyId, long userId, long calId, Date startDay, Date endDay, String title, String location, String notes, String url, Boolean allDay, String remind, String recuRule, long repeatEvtId, String uid) throws SystemException{
+ return addEventAgenda(companyId, userId, calId, startDay, endDay, title, location, notes, url, allDay, remind, recuRule, repeatEvtId, uid, true);
+ }
+ public EventAgenda addEventAgenda(long companyId, long userId, long calId, Date startDay, Date endDay, String title, String location, String notes, String url, Boolean allDay, String remind, String recuRule, long repeatEvtId, String uid, Boolean visible) throws SystemException{
+
+ EventAgenda newEvt = addEventAgenda();
+
+
+ newEvt.setCompanyId(companyId);
+ newEvt.setCalId(calId);
+ newEvt.setStartEvt(startDay);
+ newEvt.setEndEvt(endDay);
+ newEvt.setTitle(title);
+ newEvt.setLocation(location);
+ newEvt.setNotes(notes);
+ newEvt.setUrl(url);
+ newEvt.setIsAllDay(allDay);
+ newEvt.setIsVisible(visible);
+ newEvt.setRemind(remind);
+ newEvt.setCreatorId(userId);
+ newEvt.setRepeatEvtRRule(recuRule);
+ if (recuRule!=null && !recuRule.isEmpty() && repeatEvtId==0) {
+ // alors il s'agit du premier de la serie donc on lui donne son preproe Id en recuurence!
+ newEvt.setRepeatEvtId(newEvt.getEvtId());
+ }
+ else {
+ newEvt.setRepeatEvtId(repeatEvtId);
+ }
+
+ if(repeatEvtId == 0 && uid.equals("")){
+ newEvt.setUid(newEvt.getEvtId() + "@Nero");
+ }else if(repeatEvtId != 0 && uid.equals("")) {
+ newEvt.setUid(repeatEvtId + "@Nero");
+ }else{
+ newEvt.setUid(uid);
+ }
+
+ newEvt.setModifiedDate(new Date());
+
+ eventAgendaPersistence.update(newEvt, false);
+
+ // Reindex
+ Indexer indexer = IndexerRegistryUtil.getIndexer(EventAgenda.class);
+ try {
+ indexer.reindex(newEvt);
+ } catch (SearchException e) {
+ _log.error(e);
+ }
+
+ return newEvt;
+ }
+
+ public EventAgenda updateEventAgendaAndIndex(EventAgenda eventAgenda) throws SystemException{
+ eventAgenda.setNew(false);
+ eventAgenda.setModifiedDate(new Date());
+ eventAgendaPersistence.update(eventAgenda, true);
+
+ // Reindex
+ Indexer indexer = IndexerRegistryUtil.getIndexer(EventAgenda.class);
+ try {
+ indexer.reindex(eventAgenda);
+ } catch (SearchException e) {
+ _log.error(e);
+ }
+
+ return eventAgenda;
+ }
+
+ public void deleteEvent(EventAgenda eventAgenda) throws PortalException, SystemException {
+
+ // Reindex
+ Indexer indexer = IndexerRegistryUtil.getIndexer(EventAgenda.class);
+ try {
+ indexer.delete(eventAgenda);
+ }
+ catch (SearchException se) {
+ _log.error("Deleting index " + eventAgenda.getEvtId(), se);
+ }
+
+ // Event
+
+ eventAgendaPersistence.remove(eventAgenda);
+ }
+
+
+ /*
+ * Cas de evt individuel
+ */
+
+ public List<EventAgenda> getEventAgendaByUidCallId(String uid, long calId){
+ try{
+ return eventAgendaPersistence.findByuid_calId(uid, calId);
+ }catch(SystemException e){
+ _log.error(e);
+ }
+ return null;
+ }
+
+ public List<EventAgenda> getEventAgendaByCallId(long calId) {
+ try {
+ return eventAgendaPersistence.findBycalId(calId);
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ return null;
+ }
+
+ public List<EventAgenda> getEventAgendaByCallIdRangeDate(long calId, Date start, Date end) {
+ try {
+ return eventAgendaFinder.findBycalId_rangeDate(start, end, calId);
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ return null;
+ }
+
+
+ public List<EventAgenda> getEventAgendaByCallIdExcludeDate(long calId, Date start, Date end) {
+ try {
+ return eventAgendaPersistence.findBycalId_excludeDate(start, end, calId);
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ return null;
+ }
+
+
+ public List<EventAgenda> getEventAgendaByCallIdRangeENDDate(long calId, Date start, Date end) {
+ try {
+ return eventAgendaFinder.findBycalId_rangeENDDate(start, end, calId);
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ return null;
+ }
+
+ public boolean hasConcurrenceEvent(long evtId, long calId, Date start, Date end) {
+ // on regarde les startDate inclu dans la plage
+ List<EventAgenda> listEvt = new ArrayList<EventAgenda>();
+
+ try {
+ // il faut enlever 1 seconde à endDate
+ long endMillis = end.getTime();
+ endMillis = endMillis - 1000;
+ Date newEnd = new Date();
+ newEnd.setTime(endMillis);
+
+ listEvt.addAll(eventAgendaFinder.findBycalId_rangeDate(start, newEnd, calId));
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ // on regarde les EndDate inclu dans la plage
+ try {
+ // il faut ajouter une seconde a startDate
+ long startMillis = start.getTime();
+ startMillis = startMillis + 1000;
+ Date newStart = new Date();
+ newStart.setTime(startMillis);
+ listEvt.addAll(eventAgendaFinder.findBycalId_rangeENDDate(newStart, end, calId));
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ // on regarde les exclude complet dans la plage
+ try {
+ listEvt.addAll(eventAgendaPersistence.findBycalId_excludeDate(start, end, calId));
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+
+ List<EventAgenda> listEvtFinal = new ArrayList<EventAgenda>();
+ // si on a un evtId on le note!!!
+ if (evtId!=0) {
+ for (EventAgenda evt: listEvt) {
+ if (evt.getEvtId()!=evtId) {
+ listEvtFinal.add(evt);
+ }
+ }
+ }
+ else {
+ listEvtFinal = listEvt;
+ }
+ return !listEvtFinal.isEmpty();
+
+
+
+ }
+
+
+ public void deleteEventAgendaByCallId(long calId) {
+ try {
+ eventAgendaPersistence.removeBycalId(calId);
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ }
+
+ // Cas de EVENT repeat avec liaison entre eux
+ // on teste ici a chaque fois si le repeatEvtId est bien different de 0 pour eviter de supprimer toute la base! en cas de fausse manip...
+ public List<EventAgenda> getEventAgendaLinked(EventAgenda evt) {
+ if (evt.getRepeatEvtId() == 0) {
+ return null;
+ }
+ try {
+ return eventAgendaPersistence.findByrepeatEvtId(evt.getRepeatEvtId());
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ return null;
+ }
+
+ public void deleteEventAgendaLinked(EventAgenda evt) {
+ if (evt.getRepeatEvtId() == 0) {
+ return;
+ }
+ try {
+ eventAgendaPersistence.removeByrepeatEvtId(evt.getRepeatEvtId());
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ }
+
+ public List<EventAgenda> getEventAgendaLinkedAfter(EventAgenda evt) {
+ if (evt.getRepeatEvtId() == 0) {
+ return null;
+ }
+ try {
+ return eventAgendaPersistence.findByrepeatEvtId_startEvt(evt.getRepeatEvtId(), evt.getStartEvt());
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ return null;
+ }
+
+ public void deleteEventAgendaLinkedAfter(EventAgenda evt) {
+ if (evt.getRepeatEvtId() == 0) {
+ return;
+ }
+ try {
+ eventAgendaPersistence.removeByrepeatEvtId_startEvt(evt.getRepeatEvtId(), evt.getStartEvt());
+ } catch (SystemException e) {
+ _log.error(e);
+ }
+ }
+
+ public Hits search(
+ long companyId, long groupId, long calId, long userId, long ownerUserId, String keywords, int start, int end)
+ throws SystemException {
+
+ try {
+ _log.info("Searching '"+keywords+"' in agendas ...");
+
+ Indexer indexer = IndexerRegistryUtil.getIndexer(EventAgenda.class);
+ String searchEngineId = indexer.getSearchEngineId();
+
+ SearchContext searchContext = new SearchContext();
+ searchContext.setSearchEngineId(searchEngineId);
+
+ User user = UserLocalServiceUtil.getUser(userId);
+
+ BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(searchContext);
+
+ contextQuery.addRequiredTerm(Field.PORTLET_ID, EventAgendaIndexer.PORTLET_ID);
+
+ List<String> solrFilters = new ArrayList<String>();
+
+ if(calId>0){
+ solrFilters.add(Field.CALENDAR_ID + ":" + calId);
+ } else {
+ List<Ressource> listRessourcesFinal = getAllRessourceAgendaAttachToUser(user);
+ solrFilters.add(Field.CALENDAR_ID + ":" + buildCalendarCriteriaOR(listRessourcesFinal));
+ }
+
+ String query = SolrQueryUtil.getQueryFromKeywords(keywords, true);
+ String queryWithoutFuzzySearch = SolrQueryUtil.getQueryFromKeywords(keywords, false);
+
+ solrFilters.add("(" + Field.USER_NAME + ":" + query + ") "
+ + "OR (" + Field.TITLE + ":" + query + ") "
+ + "OR (" + Field.DESCRIPTION + ":" + queryWithoutFuzzySearch + ")");
+
+
+ BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
+
+ fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
+
+ //userId a 0 car on gere nous meme les permissions
+ return SearchEngineUtil.search(searchEngineId, companyId, fullQuery, solrFilters, start, end);
+ }
+ catch (Exception e) {
+ throw new SystemException(e);
+ }
+ }
+
+ public Hits searchByDate(
+ long companyId, long groupId, long calId, long userId, long ownerUserId,
+ String keywords, int start, int end)
+ throws SystemException {
+
+ try {
+ Indexer indexer = IndexerRegistryUtil.getIndexer(EventAgenda.class);
+ String searchEngineId = indexer.getSearchEngineId();
+
+ SearchContext searchContext = new SearchContext();
+ searchContext.setSearchEngineId(searchEngineId);
+ User user = UserLocalServiceUtil.getUser(userId);
+
+ BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(searchContext);
+
+ contextQuery.addRequiredTerm(Field.PORTLET_ID, EventAgendaIndexer.PORTLET_ID);
+
+ if(calId>0){
+ contextQuery.addRequiredTerm("calendarId", calId);
+ } else {
+ List<Ressource> listRessourcesFinal = getAllRessourceAgendaAttachToUser(user);
+ contextQuery.addRequiredTerm("calendarId", buildCalendarCriteriaOR(listRessourcesFinal));
+ }
+
+
+ BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(searchContext);
+
+ if(!keywords.isEmpty()){
+ searchQuery.addTerm("modifiedDate", keywords, false);
+ }
+
+ BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
+
+ fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
+
+ if (searchQuery.clauses().size() > 0) {
+ fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
+ }
+
+ //userId à 0 car on gere nous meme les permissions
+ return SearchEngineUtil.search(searchEngineId, companyId, fullQuery, start, end);
+ }
+ catch (Exception e) {
+ throw new SystemException(e);
+ }
+ }
+
+ /**
+ * GEt all event ressource agenda attach to a user. Check the personnal calendar, the forced calendar, role calendar
+ * @param pUser User - Represent the user you want the ressources
+ * @return the list of agenda ressources
+ * @throws SystemException
+ * @throws PortalException
+ */
+ public List<Ressource> getAllRessourceAgendaAttachToUser(User pUser) throws SystemException, PortalException{
+ List<Ressource> listRessourcesAvailable = new ArrayList<Ressource>();
+ List<Ressource> listRessourcesFinal = new ArrayList<Ressource>();
+
+ Ressource calPerso = RessourceLocalServiceUtil.getOrCreatePersonalRessource(pUser.getUserId());
+ listRessourcesFinal.add(calPerso);
+
+ List<RessourceUser> rUser = RessourceUserLocalServiceUtil.getRessourceUserByUserId(pUser.getUserId());
+ for (RessourceUser ru: rUser) {
+ Ressource r = RessourceLocalServiceUtil.getRessource(ru.getIdRessource());
+ listRessourcesFinal.add(r);
+ }
+
+ // on ajoute maitenant les ressources avec inscription forcée
+ // On prends toutes les ressources auxquelles on peut avoir acces
+ List<Ressource> listRessourceGeneral = RessourceLocalServiceUtil.getRessourcesByScopeTypeForcePubli(2, 1, true);
+ for(Ressource r : listRessourceGeneral){
+ if (!listRessourcesFinal.contains(r)) {
+ listRessourcesAvailable.add(r);
+ }
+ }
+
+ // Get ressources of all user etab
+ List<Organization> userEtabs = OrganizationFilter.getAllUserSchoolsIncludingSchoolComplex(pUser);
+ List<Ressource> listRessourceEtab = new ArrayList<Ressource>();
+ for(Organization anEtab : userEtabs){
+ listRessourceEtab .addAll(RessourceLocalServiceUtil.getRessourcesByScopeTypeEtabIdForcePubli(1, 1, anEtab.getOrganizationId(), true));
+ }
+
+ for(Ressource r : listRessourceEtab){
+ if (!listRessourcesFinal.contains(r)) {
+ listRessourcesAvailable.add(r);
+ }
+ }
+
+ // on check le filtre sur les roles
+ for(Ressource res : listRessourcesAvailable){
+ List<RessourceRole> ressourceRoles = RessourceRoleLocalServiceUtil.getRessourceRoleByRessourceId(res.getIdRessource());
+ if (ressourceRoles.isEmpty()) {
+ // pas de filtre role
+ listRessourcesFinal.add(res);
+ continue;
+ }
+ else {
+ for (RessourceRole rr: ressourceRoles) {
+ if(RoleLocalServiceUtil.hasUserRole(pUser.getUserId(), rr.getIdRole())) {
+ // on add et on break
+ listRessourcesFinal.add(res);
+ break;
+ }
+ }
+ }
+ }
+ return listRessourcesFinal;
+ }
+
+ /**
+ * Build string for calendar creria set OR operator between calendars
+ * @param pRessourcesList List<Ressource> - Create a string based on these ressources to build calendarId criteria
+ * @return criterie for calendarId with OR operator
+ */
+ private String buildCalendarCriteriaOR(List<Ressource> pRessourcesList){
+ StringBuilder listCalendarIdBuilder = new StringBuilder("(");
+ String listCalendarId = "";
+ for (Ressource res: pRessourcesList) {
+ listCalendarIdBuilder = listCalendarIdBuilder.append(res.getIdRessource()).append(" OR ");
+ }
+
+ listCalendarId = listCalendarIdBuilder.toString();
+ if(listCalendarId.contains(" OR ")){
+ listCalendarId = listCalendarId.substring(0, listCalendarId.lastIndexOf(" OR "));
+ }
+ listCalendarId = listCalendarId + ")";
+ return listCalendarId;
+ }
+
+ /**
+ * Build string for calendar creria set OR operator between calendars.Check the personnal calendar, the forced calendar, role calendar
+ * @param pUser User - Represent the user you want the ressources
+ * @return criterie for calendarId with OR operator
+ * @throws SystemException
+ * @throws PortalException
+ */
+ public String getCalendarCriteriaFromUser(User pUser) throws SystemException, PortalException{
+ List<Ressource> listRessourcesFinal = getAllRessourceAgendaAttachToUser(pUser);
+ return buildCalendarCriteriaOR(listRessourcesFinal);
+ }
+
+ public List<EventAgenda> getEventAgendaByCompanyId(long companyId) throws SystemException{
+ return eventAgendaPersistence.findByCompanyId(companyId);
+ }
+
+ public List<EventAgenda> getEventAgendaByCompanyId(long companyId, int start, int end) throws SystemException{
+ return eventAgendaPersistence.findByCompanyId(companyId, start, end);
+ }
+
+ public int countByCompanyId(long companyId) throws SystemException{
+ return eventAgendaPersistence.countByCompanyId(companyId);
+ }
+
+ private static Log _log = LogFactoryUtil.getLog(EventAgendaLocalServiceImpl.class);
+
+}