From 9dec7c98bd123c7b1ab9e0c09e2a410131622001 Mon Sep 17 00:00:00 2001
From: Martin Correll <martin.correll@civiservice.de>
Date: Thu, 6 Mar 2025 10:48:19 +0100
Subject: [PATCH 1/2] Option to hide the end date when it is the same day as
 the start date.

---
 .../DateRangeFieldOutputHandler.php           | 56 +++++++++++++++++--
 .../DateRangeFieldOutputHandler.tpl           |  5 ++
 2 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/Civi/DataProcessor/FieldOutputHandler/DateRangeFieldOutputHandler.php b/Civi/DataProcessor/FieldOutputHandler/DateRangeFieldOutputHandler.php
index ab17661e..90a1a56f 100644
--- a/Civi/DataProcessor/FieldOutputHandler/DateRangeFieldOutputHandler.php
+++ b/Civi/DataProcessor/FieldOutputHandler/DateRangeFieldOutputHandler.php
@@ -9,6 +9,7 @@ namespace Civi\DataProcessor\FieldOutputHandler;
 use CRM_Dataprocessor_ExtensionUtil as E;
 use Civi\DataProcessor\Source\SourceInterface;
 use Civi\DataProcessor\DataSpecification\FieldSpecification;
+use DateTime;
 
 class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
 
@@ -36,6 +37,8 @@ class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
    */
   protected $separator;
 
+  protected bool $omitEndDate = FALSE;
+
   /**
    * Initialize the processor
    *
@@ -49,6 +52,8 @@ class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
     [$this->dataSourceDateEnd, $this->dateEnd] = $this->initializeField($configuration['date_end'], $configuration['date_end_datasource'], $alias . '_date_end');
     $this->formatDateOnly = isset($configuration['format_date_only']) ? $configuration['format_date_only'] : false;
     $this->separator = isset($configuration['separator']) ? $configuration['separator'] : false;
+
+    $this->omitEndDate = isset($configuration['omit_end_date_when_same_day']) ? $configuration['omit_end_date_when_same_day'] : FALSE;
   }
 
   /**
@@ -70,6 +75,8 @@ class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
       'placeholder' => E::ts('- select -'),
     ));
 
+    $form->add('checkbox', 'omit_end_date_when_same_day', E::ts('Hide end date when same day'));
+
     $form->add('text', 'format_date_only', E::ts('Format date only'), array(
       'style' => 'min-width:250px',
       'class' => 'huge',
@@ -96,6 +103,10 @@ class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
         }
       }
 
+      if (isset($configuration['omit_end_date_when_same_day'])) {
+        $defaults['omit_end_date_when_same_day'] = $configuration['omit_end_date_when_same_day'];
+      }
+
       $form->setDefaults($defaults);
     }
 
@@ -123,6 +134,8 @@ class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
     $configuration['date_end'] = $field;
     $configuration['date_end_datasource'] = $datasource;
 
+    $configuration['omit_end_date_when_same_day'] = isset($submittedValues['omit_end_date_when_same_day']) ? $submittedValues['omit_end_date_when_same_day'] : FALSE;
+
     foreach (array('separator', 'format_date_only') as $key) {
       $configuration[$key] = isset($submittedValues[$key]) ? $submittedValues[$key] : false;
     }
@@ -139,22 +152,57 @@ class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
    * @return \Civi\DataProcessor\FieldOutputHandler\FieldOutput
    */
   public function formatField($rawRecord, $formattedRecord) {
+    // todo: use $this->omitEndDate
+
     $output = new FieldOutput($rawRecord[$this->inputFieldSpec->alias]);
+
     $rawValue = $rawRecord[$this->inputFieldSpec->alias];
     if (($this->format || $this->formatDateOnly) && $rawValue) {
       $output->formattedValue = $this->formatHelper($rawValue);
     }
 
     $output2 = new FieldOutput($rawRecord[$this->dateEnd->alias]);
+
     $rawValue2 = $rawRecord[$this->dateEnd->alias];
     if ($rawValue2) {
       if ($this->format || $this->formatDateOnly) {
         $output2->formattedValue = $this->formatHelper($rawValue2);
       }
-      if ($this->separator) {
-        $output->formattedValue .= $this->separator;
+
+      $isSameDay = FALSE;
+      if ($this->omitEndDate) {
+        if (isset($output->rawValue) && isset($rawValue2)) {
+          $startDate = new DateTime($output->rawValue);
+          $startDay = $startDate->format('Y-m-d');
+
+          $endDate = new DateTime($rawValue2);
+          $endDay = $endDate->format('Y-m-d');
+
+          if ($startDay === $endDay) {
+            $isSameDay = TRUE;
+          }
+        }
+      }
+      if ($isSameDay) {
+        if ($this->formatDateOnly && str_ends_with($rawValue2, ' 00:00:00')) {
+          return $output;
+        }
+
+        // time separator
+        if ($this->separator) {
+          $output->formattedValue .= $this->separator;
+        }
+
+        $onlyTime = preg_replace('#.+(\d{2}\:\d{2})([ A-Za-z]*)$#', '$1$2', $output2->formattedValue);
+        $output->formattedValue .= $onlyTime;
+      }
+      else {
+        if ($this->separator) {
+          $output->formattedValue .= $this->separator;
+        }
+
+        $output->formattedValue .= $output2->formattedValue;
       }
-      $output->formattedValue .= $output2->formattedValue;
     }
 
     return $output;
@@ -173,7 +221,7 @@ class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
    * @throws \Exception
    */
   protected function formatHelper($raw_value) {
-    $date = new \DateTime($raw_value);
+    $date = new DateTime($raw_value);
     if ($this->formatDateOnly && str_ends_with($raw_value, ' 00:00:00')) {
       $format = $this->formatDateOnly;
     }
diff --git a/templates/CRM/Dataprocessor/Form/Field/Configuration/DateRangeFieldOutputHandler.tpl b/templates/CRM/Dataprocessor/Form/Field/Configuration/DateRangeFieldOutputHandler.tpl
index b289600b..781ae05d 100644
--- a/templates/CRM/Dataprocessor/Form/Field/Configuration/DateRangeFieldOutputHandler.tpl
+++ b/templates/CRM/Dataprocessor/Form/Field/Configuration/DateRangeFieldOutputHandler.tpl
@@ -17,6 +17,11 @@
     </div>
     <div class="clear"></div>
   </div>
+  <div class="crm-section">
+    <div class="label">{$form.omit_end_date_when_same_day.label}</div>
+    <div class="content">{$form.omit_end_date_when_same_day.html}</div>
+    <div class="clear"></div>
+  </div>
   <hr >
   <div class="crm-section">
     <div class="label">{$form.format_date_only.label}</div>
-- 
GitLab


From 508519f9964bbad41d8190c467057daa7f979dc5 Mon Sep 17 00:00:00 2001
From: Martin Correll <martin.correll@civiservice.de>
Date: Mon, 10 Mar 2025 12:24:10 +0100
Subject: [PATCH 2/2] Code cleanup

---
 .../DateRangeFieldOutputHandler.php           | 20 ++++++++-----------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/Civi/DataProcessor/FieldOutputHandler/DateRangeFieldOutputHandler.php b/Civi/DataProcessor/FieldOutputHandler/DateRangeFieldOutputHandler.php
index 90a1a56f..e5a8501d 100644
--- a/Civi/DataProcessor/FieldOutputHandler/DateRangeFieldOutputHandler.php
+++ b/Civi/DataProcessor/FieldOutputHandler/DateRangeFieldOutputHandler.php
@@ -152,8 +152,6 @@ class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
    * @return \Civi\DataProcessor\FieldOutputHandler\FieldOutput
    */
   public function formatField($rawRecord, $formattedRecord) {
-    // todo: use $this->omitEndDate
-
     $output = new FieldOutput($rawRecord[$this->inputFieldSpec->alias]);
 
     $rawValue = $rawRecord[$this->inputFieldSpec->alias];
@@ -170,17 +168,15 @@ class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
       }
 
       $isSameDay = FALSE;
-      if ($this->omitEndDate) {
-        if (isset($output->rawValue) && isset($rawValue2)) {
-          $startDate = new DateTime($output->rawValue);
-          $startDay = $startDate->format('Y-m-d');
+      if ($this->omitEndDate && isset($output->rawValue)) {
+        $startDate = new DateTime($output->rawValue);
+        $startDay = $startDate->format('Y-m-d');
 
-          $endDate = new DateTime($rawValue2);
-          $endDay = $endDate->format('Y-m-d');
+        $endDate = new DateTime($rawValue2);
+        $endDay = $endDate->format('Y-m-d');
 
-          if ($startDay === $endDay) {
-            $isSameDay = TRUE;
-          }
+        if ($startDay === $endDay) {
+          $isSameDay = TRUE;
         }
       }
       if ($isSameDay) {
@@ -193,7 +189,7 @@ class DateRangeFieldOutputHandler extends DateFieldOutputHandler {
           $output->formattedValue .= $this->separator;
         }
 
-        $onlyTime = preg_replace('#.+(\d{2}\:\d{2})([ A-Za-z]*)$#', '$1$2', $output2->formattedValue);
+        $onlyTime = preg_replace('#.+(\d{2}:\d{2})([ A-Za-z]*)$#', '$1$2', $output2->formattedValue);
         $output->formattedValue .= $onlyTime;
       }
       else {
-- 
GitLab