001/*
002 *  Copyright 2022 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.calendar.search;
017
018import java.time.ZonedDateTime;
019
020import org.ametys.cms.search.query.AndQuery;
021import org.ametys.cms.search.query.DateTimeQuery;
022import org.ametys.cms.search.query.NotQuery;
023import org.ametys.cms.search.query.OrQuery;
024import org.ametys.cms.search.query.Query;
025import org.ametys.cms.search.query.Query.Operator;
026import org.ametys.plugins.calendar.events.EventsFilterHelper.DateTimeRange;
027import org.ametys.web.frontoffice.search.requesttime.AbstractSearchComponent;
028import org.ametys.web.frontoffice.search.requesttime.SearchComponent;
029import org.ametys.web.frontoffice.search.requesttime.SearchComponentArguments;
030import org.ametys.web.frontoffice.search.requesttime.impl.SearchComponentHelper;
031
032
033/**
034 * {@link SearchComponent} to add date range to query
035 */
036public class DateRangeCriterionSearchComponent extends AbstractSearchComponent
037{
038    /** The helper for search component */
039    protected SearchComponentHelper _searchComponentHelper;
040    
041    @Override
042    public int getPriority()
043    {
044        return SEARCH_PRIORITY - 7999; // after CriterionTreeSearchComponent
045    }
046
047    @Override
048    public boolean supports(SearchComponentArguments args)
049    {
050        return CalendarSearchService.isFormSubmit(args) && CalendarSearchService.isActive(args);
051    }
052
053    @Override
054    public void execute(SearchComponentArguments args) throws Exception
055    {
056        DateTimeRange dateRange = CalendarSearchService.getDateRange(args);
057        if (dateRange != null)
058        {
059            ZonedDateTime fromDateTime = dateRange.fromDate();
060            ZonedDateTime untilDateTime = dateRange.untilDate();
061            
062            Query startBeforeQuery = new DateTimeQuery(CalendarSearchService.START_DATE_ATTRIBUTE_NAME, Operator.LT, untilDateTime);
063            Query endAfterExpr = new DateTimeQuery(CalendarSearchService.END_DATE_ATTRIBUTE_NAME, Operator.GE, fromDateTime);
064            Query startAfterExpr = new DateTimeQuery(CalendarSearchService.START_DATE_ATTRIBUTE_NAME, Operator.GE, fromDateTime);
065            Query noEndExpr = new NotQuery(new DateTimeQuery(CalendarSearchService.END_DATE_ATTRIBUTE_NAME));
066            
067            // start-date < untilDate AND (end-date >= fromDate OR not(end-date) AND start-date >= fromDate)
068            args.searcher()
069                .addFilterQuery(new AndQuery(startBeforeQuery, new OrQuery(endAfterExpr,  new AndQuery(noEndExpr, startAfterExpr))));
070        }
071        else
072        {
073            // filter on start-date exists
074            args.searcher()
075                .addFilterQuery(new DateTimeQuery(CalendarSearchService.START_DATE_ATTRIBUTE_NAME));
076        }
077    }
078}