refactor freeBusyComputation to cope with multiple events to check for
authorCornelius Weiß <c.weiss@metaways.de>
Wed, 19 Jul 2017 12:32:20 +0000 (14:32 +0200)
committerCornelius Weiss <c.weiss@metaways.de>
Wed, 19 Jul 2017 15:56:19 +0000 (17:56 +0200)
Change-Id: Iff1de025b7567bfffb889e701507057bc65af1d0
Reviewed-on: http://gerrit.tine20.com/customers/5253
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Cornelius Weiss <c.weiss@metaways.de>
tests/tine20/Calendar/JsonTests.php
tine20/Calendar/Frontend/Json.php
tine20/Calendar/js/AttendeeGridPanel.js
tine20/Calendar/js/AttendeePickerCombo.js
tine20/Calendar/js/FreeBusyInfo.js
tine20/Calendar/js/Model.js

index 466435b..2dcd237 100644 (file)
@@ -1998,11 +1998,12 @@ class Calendar_JsonTests extends Calendar_TestCase
         $persistentEvent = $this->_eventController->create($event);
         $persistentEvent->setTimezone(Tinebase_Core::getUserTimezone());
 
-        $fbinfo = $this->_uit->getFreeBusyInfo($persistentEvent->attendee->toArray(), $persistentEvent->toArray());
-        $this->assertEquals(2, count($fbinfo));
+        $fbinfo = $this->_uit->getFreeBusyInfo($persistentEvent->attendee->toArray(), [$persistentEvent->toArray()]);
+        $this->assertEquals(1, count($fbinfo));
+        $this->assertEquals(2, count(array_pop($fbinfo)));
 
-        $fbinfo = $this->_uit->getFreeBusyInfo($persistentEvent->attendee->toArray(), $persistentEvent->toArray(), array($persistentEvent->uid));
-        $this->assertEquals(0, count($fbinfo));
+        $fbinfo = $this->_uit->getFreeBusyInfo($persistentEvent->attendee->toArray(), [$persistentEvent->toArray()], array($persistentEvent->uid));
+        $this->assertEquals(0, count(array_pop($fbinfo)));
     }
 
     public function testSearchAttenders()
@@ -2018,7 +2019,7 @@ class Calendar_JsonTests extends Calendar_TestCase
         $filter = array(array('field' => 'query', 'operator' => 'contains', 'value' => 'l'));
         $paging = array('sort' => 'name', 'dir' => 'ASC', 'start' => 0, 'limit' => 50);
 
-        $result = $this->_uit->searchAttenders($filter, $paging, $persistentEvent->toArray(), array());
+        $result = $this->_uit->searchAttenders($filter, $paging, [$persistentEvent->toArray()], array());
         $this->assertTrue(
             isset($result[Calendar_Model_Attender::USERTYPE_USER]) &&
             count($result[Calendar_Model_Attender::USERTYPE_USER]) === 3 &&
@@ -2026,10 +2027,10 @@ class Calendar_JsonTests extends Calendar_TestCase
             isset($result[Calendar_Model_Attender::USERTYPE_GROUP]) &&
             isset($result[Calendar_Model_Attender::USERTYPE_RESOURCE]) &&
             isset($result['freeBusyInfo']) &&
-            count($result['freeBusyInfo']) === 2, print_r($result, true));
+            count(array_pop($result['freeBusyInfo'])) === 2, print_r($result, true));
 
         $filter[] = array('field' => 'type', 'value' => array(Calendar_Model_Attender::USERTYPE_RESOURCE));
-        $result = $this->_uit->searchAttenders($filter, $paging, $persistentEvent->toArray(), array());
+        $result = $this->_uit->searchAttenders($filter, $paging, [$persistentEvent->toArray()], array());
         $this->assertTrue(
             !isset($result[Calendar_Model_Attender::USERTYPE_USER]) &&
             !isset($result[Calendar_Model_Attender::USERTYPE_GROUP]) &&
@@ -2037,7 +2038,7 @@ class Calendar_JsonTests extends Calendar_TestCase
             count($result[Calendar_Model_Attender::USERTYPE_RESOURCE]) === 3 &&
             count($result[Calendar_Model_Attender::USERTYPE_RESOURCE]['results']) === 0 &&
             isset($result['freeBusyInfo']) &&
-            count($result['freeBusyInfo']) === 0, print_r($result, true));
+            count(array_pop($result['freeBusyInfo'])) === 0, print_r($result, true));
     }
 
     public function testSearchFreeTime()
index 71c696f..e607f34 100644 (file)
@@ -535,25 +535,29 @@ class Calendar_Frontend_Json extends Tinebase_Frontend_Json_Abstract
 
     /**
      * @param array $attendee
-     * @param array $event
+     * @param array $events single event or set of events
      * @param array $ignoreUIDs
-     * @return array
+     * @return array single fbInfo or array of eventid => fbinfo
      */
-    public function getFreeBusyInfo($attendee, $event, $ignoreUIDs = array())
+    public function getFreeBusyInfo($attendee, $events, $ignoreUIDs = array())
     {
         $attendee = new Tinebase_Record_RecordSet('Calendar_Model_Attender', $attendee);
         $calendarController = Calendar_Controller_Event::getInstance();
-        $eventRecord = new Calendar_Model_Event(array(), TRUE);
-        $eventRecord->setFromJsonInUsersTimezone($event);
+        $fbInfo = [];
 
-        $periods = $calendarController->getBlockingPeriods($eventRecord, array(
-            'from'  => $eventRecord->dtstart,
-            'until' => $eventRecord->dtstart->getClone()->addMonth(2)
-        ));
+        foreach($events as $event) {
+            $eventRecord = new Calendar_Model_Event(array(), TRUE);
+            $eventRecord->setFromJsonInUsersTimezone($event);
+
+            $periods = $calendarController->getBlockingPeriods($eventRecord, array(
+                'from'  => $eventRecord->dtstart,
+                'until' => $eventRecord->dtstart->getClone()->addMonth(2)
+            ));
 
-        $fbInfo = $calendarController->getFreeBusyInfo($periods, $attendee, $ignoreUIDs);
+            $fbInfo[$eventRecord->getId()] = $calendarController->getFreeBusyInfo($periods, $attendee, $ignoreUIDs)->toArray();
+        }
 
-        return $fbInfo->toArray();
+        return $fbInfo;
     }
 
     /**
@@ -563,7 +567,7 @@ class Calendar_Frontend_Json extends Tinebase_Frontend_Json_Abstract
      * @param array $ignoreUIDs
      * @return array
      */
-    public function searchAttenders($filter, $paging, $event, $ignoreUIDs)
+    public function searchAttenders($filter, $paging, $events, $ignoreUIDs)
     {
         $filters = array();
         foreach($filter as $f) {
@@ -613,7 +617,7 @@ class Calendar_Frontend_Json extends Tinebase_Frontend_Json_Abstract
             $result[Calendar_Model_Attender::USERTYPE_RESOURCE] = $this->searchResources($resourceFilter, $paging);
         }
 
-        if (empty($event)) {
+        if (empty($events)) {
             $result['freeBusyInfo'] = array();
         } else {
             $attendee = array();
@@ -626,7 +630,7 @@ class Calendar_Frontend_Json extends Tinebase_Frontend_Json_Abstract
                 }
             }
 
-            $result['freeBusyInfo'] = $this->getFreeBusyInfo($attendee, $event, $ignoreUIDs);
+            $result['freeBusyInfo'] = $this->getFreeBusyInfo($attendee, $events, $ignoreUIDs);
         }
 
         return $result;
index c9530ce..20700b4 100644 (file)
@@ -667,7 +667,8 @@ Tine.Calendar.AttendeeGridPanel = Ext.extend(Ext.grid.EditorGridPanel, {
     updateFreeBusyInfo: function(force) {
         if (this.showMemberOfType) return;
 
-        var schedulingInfo = Ext.copyTo({}, this.record.data, 'id,dtstart,dtend,originator_tz,rrule,rrule_constraints,rrule_until,is_all_day_event,uid'),
+        var _ = window.lodash,
+            schedulingInfo = Ext.copyTo({}, this.record.data, 'id,dtstart,dtend,originator_tz,rrule,rrule_constraints,rrule_until,is_all_day_event,uid'),
             encodedSchedulingInfo = Ext.encode(schedulingInfo);
 
         if (encodedSchedulingInfo == this.encodedSchedulingInfo && !force) return;
@@ -685,13 +686,13 @@ Tine.Calendar.AttendeeGridPanel = Ext.extend(Ext.grid.EditorGridPanel, {
 
         Tine.Calendar.getFreeBusyInfo(
             Tine.Calendar.Model.Attender.getAttendeeStore.getData(this.store),
-            schedulingInfo,
+            [schedulingInfo],
             [this.record.get('uid')],
             function(freeBusyData) {
                 // outdated data
                 if (encodedSchedulingInfo != this.encodedSchedulingInfo) return;
 
-                var fbInfo = new Tine.Calendar.FreeBusyInfo(freeBusyData);
+                var fbInfo = new Tine.Calendar.FreeBusyInfo(_.values(freeBusyData)[0]);
 
                 this.store.each(function(attendee) {
                     attendee.set('fbInfo', fbInfo.getStateOfAttendee(attendee, this.record));
index 127e707..5c92428 100644 (file)
@@ -36,28 +36,19 @@ Tine.Calendar.AttendeePickerCombo = Ext.extend(Tine.Tinebase.widgets.form.Record
     itemSelector: '.cal-attendee-picker-combo-list-item',
 
     initComponent: function() {
+        _ = window.lodash;
+
         this.typeTemplates = {};
 
-        this.recordProxy = new Tine.Calendar.Model.AttenderProxy({});
+        this.recordProxy = new Tine.Calendar.Model.AttenderProxy({
+            freeBusyEventsProvider: _.bind(function() {
+                return [this.eventRecord];
+            }, this)
+        });
 
         Tine.Calendar.AttendeePickerCombo.superclass.initComponent.call(this);
     },
 
-    onBeforeLoad: function(store, options) {
-        Tine.Calendar.AttendeePickerCombo.superclass.onBeforeLoad.call(this, store, options);
-
-        var _ = window.lodash;
-        options.params.ignoreUIDs = [];
-        if (_.get(this, 'eventRecord.data.dtstart')) {
-            options.params.event = this.eventRecord.data;
-            if (this.eventRecord.get('uid')) {
-                options.params.ignoreUIDs.push(this.eventRecord.get('uid'));
-            }
-        }
-
-        this.recordProxy.eventRecord = this.eventRecord
-    },
-
     /**
      * respect record.getTitle method
      */
index df4dd23..455b7f2 100644 (file)
@@ -120,7 +120,7 @@ Tine.Calendar.FreeBusyInfo.prototype = {
             qtip = stateId ? ('ext:qtip="' + info + '" ') : '';
 
         // @TODO impelment hover
-        return ['<div class="cal-fbinfo-state cal-fbinfo-state-', cls, '"', qtip, ' />'].join('');
+        return ['<div class="cal-fbinfo-state cal-fbinfo-state-', cls, '"', ' tine:calendar-event-id="', event.get('id'), '" ', qtip, ' />'].join('');
     },
 
     /**
@@ -135,4 +135,4 @@ Tine.Calendar.FreeBusyInfo.prototype = {
             return Math.max(result, value);
         }, 0);
     }
-};
\ No newline at end of file
+};
index 57b86d0..260bc6d 100644 (file)
@@ -858,18 +858,32 @@ Tine.Calendar.Model.AttenderProxy = function(config) {
 };
 Ext.extend(Tine.Calendar.Model.AttenderProxy, Tine.Tinebase.data.RecordProxy, {
     /**
-     * @cfg {Tine.Calendar.Model.Event} eventRecord
+     * provide events to do an freeBusy info checkup for when searching attendee
+     *
+     * @cfg {Function} freeBusyEventsProvider
      */
-    eventRecord: null,
+    freeBusyEventsProvider: Ext.emptyFn,
 
     recordClass: Tine.Calendar.Model.Attender,
 
+    searchRecords: function(filter, paging, options) {
+        var _ = window.lodash,
+            fbEvents = _.union([].concat(this.freeBusyEventsProvider()));
+
+        _.set(options, 'params.ignoreUIDs', _.union(_.map(fbEvents, 'data.uid')));
+        _.set(options, 'params.events', _.map(fbEvents, 'data'));
+
+        return Tine.Calendar.Model.AttenderProxy.superclass.searchRecords.apply(this, arguments);
+    },
+
     readRecords : function(resultData){
         var _ = window.lodash,
             totalcount = 0,
-            eventRecord = this.eventRecord,
+            fbEvents = _.union([].concat(this.freeBusyEventsProvider())),
             records = [],
-            fbInfo = new Tine.Calendar.FreeBusyInfo(resultData.freeBusyInfo)
+            fbInfos = _.map(fbEvents, function(fbEvent) {
+                return new Tine.Calendar.FreeBusyInfo(resultData.freeBusyInfo[fbEvent.get('id')]);
+            });
 
         _.each(['user', 'group', 'resource'], function(type) {
             var typeResult = _.get(resultData, type, {}),
@@ -886,8 +900,10 @@ Ext.extend(Tine.Calendar.Model.AttenderProxy, Tine.Tinebase.data.RecordProxy, {
                     }),
                     attendee = new Tine.Calendar.Model.Attender(attendeeData, id);
 
-                if (_.get(eventRecord, 'data.dtstart')) {
-                    attendee.set('fbInfo', fbInfo.getStateOfAttendee(attendee, eventRecord));
+                if (fbEvents.length) {
+                    attendee.set('fbInfo', _.map(fbInfos, function(fbInfo, idx) {
+                        return fbInfo.getStateOfAttendee(attendee, fbEvents[idx]);
+                    }).join('<br >'));
                 }
                 records.push(attendee);
             });