From 5c9d7a78bdd06fd1819333422212f9a17bc8dac4 Mon Sep 17 00:00:00 2001
From: Kyle Hall <kyle@bywatersolutions.com>
Date: Wed, 22 Feb 2023 07:03:39 -0500
Subject: [PATCH] Bug 33039: Add ability to specify a template for serial
 subscription "Published on (text)" field

Some libraries would like to have the text version of the serials
"published on" field auto-generated from a template. This template
should be definable at the subscription level.

Test Plan:
1) Apply this patch
2) Run updatedatabase.pl
3) Restart all the things!
4) Create or edit a new subscription
5) Edit the "Publication date template", create a template toolkit
   template.
   Keys available are the Koha::Subscription object as 'subscription'
   and the following serial table columns as keys:
    serialseq
    serialseq_x
    serialseq_y
    serialseq_z
    subscriptionid
    biblionumber
    status
    planneddate
    publisheddate
    publisheddateext
    notes
    routingnotes
   So your example template could be "[% subscription.subscriptionid %] [% biblionumber %]"
6) Generate the next serial
7) Note the next issue has a "Date published (text)" field based on the
   template you set!
---
 C4/Serials.pm                                 | 82 ++++++++++++++++---
 .../data/mysql/atomicupdate/bug_33039.pl      | 18 ++++
 installer/data/mysql/kohastructure.sql        |  1 +
 .../en/modules/serials/subscription-add.tt    |  4 +
 serials/subscription-add.pl                   |  6 +-
 t/db_dependent/Koha/Items.t                   |  9 +-
 6 files changed, 106 insertions(+), 14 deletions(-)
 create mode 100755 installer/data/mysql/atomicupdate/bug_33039.pl

diff --git a/C4/Serials.pm b/C4/Serials.pm
index 75c9d7f19f..ce143d0ad3 100644
--- a/C4/Serials.pm
+++ b/C4/Serials.pm
@@ -20,9 +20,7 @@ package C4::Serials;
 
 use Modern::Perl;
 
-use C4::Auth qw( haspermission );
-use C4::Context;
-use DateTime;
+use Carp qw( croak );
 use Date::Calc qw(
     Add_Delta_Days
     Add_Delta_YM
@@ -31,18 +29,23 @@ use Date::Calc qw(
     N_Delta_YMD
     Today
 );
+use DateTime;
 use POSIX qw( strftime );
+use Scalar::Util qw( looks_like_number );
+use Try::Tiny;
+
+use C4::Auth qw( haspermission );
 use C4::Biblio qw( GetMarcFromKohaField ModBiblio );
+use C4::Context;
 use C4::Log qw( logaction );    # logaction
 use C4::Serials::Frequency qw( GetSubscriptionFrequency );
 use C4::Serials::Numberpattern;
 use Koha::AdditionalFieldValues;
 use Koha::Biblios;
 use Koha::Serial;
-use Koha::Subscriptions;
-use Koha::Subscription::Histories;
 use Koha::SharedContent;
-use Scalar::Util qw( looks_like_number );
+use Koha::Subscription::Histories;
+use Koha::Subscriptions;
 
 # Define statuses
 use constant {
@@ -893,6 +896,7 @@ sub GetNextSeq {
             my $newlastvalue3string = _numeration( $newlastvalue3, $pattern->{numbering3}, $locale );
             $calculated =~ s/\{Z\}/$newlastvalue3string/g;
         }
+
     }
 
     return ($calculated,
@@ -1286,7 +1290,7 @@ sub ModSubscription {
     $biblionumber, $callnumber, $notes, $letter, $manualhistory,
     $internalnotes, $serialsadditems, $staffdisplaycount, $opacdisplaycount,
     $graceperiod, $location, $enddate, $subscriptionid, $skip_serialseq,
-    $itemtype, $previousitemtype, $mana_id, $ccode
+    $itemtype, $previousitemtype, $mana_id, $ccode, $published_on_template
     ) = @_;
 
     my $subscription = Koha::Subscriptions->find($subscriptionid);
@@ -1330,6 +1334,7 @@ sub ModSubscription {
             previousitemtype  => $previousitemtype,
             mana_id           => $mana_id,
             ccode             => $ccode,
+            published_on_template => $published_on_template,
         }
     )->store;
     # FIXME Must be $subscription->serials
@@ -1367,7 +1372,8 @@ sub NewSubscription {
     $innerloop3, $status, $notes, $letter, $firstacquidate, $irregularity,
     $numberpattern, $locale, $callnumber, $manualhistory, $internalnotes,
     $serialsadditems, $staffdisplaycount, $opacdisplaycount, $graceperiod,
-    $location, $enddate, $skip_serialseq, $itemtype, $previousitemtype, $mana_id, $ccode
+    $location, $enddate, $skip_serialseq, $itemtype, $previousitemtype, $mana_id, $ccode,
+    $published_on_template,
     ) = @_;
     my $dbh = C4::Context->dbh;
 
@@ -1410,7 +1416,8 @@ sub NewSubscription {
             itemtype          => $itemtype,
             previousitemtype  => $previousitemtype,
             mana_id           => $mana_id,
-            ccode             => $ccode
+            ccode             => $ccode,
+            published_on_template => $published_on_template,
         }
     )->store;
     $subscription->discard_changes;
@@ -1586,6 +1593,61 @@ sub NewIssue {
 
     my $subscription = Koha::Subscriptions->find( $subscriptionid );
 
+    if ( my $template = $subscription->published_on_template ) {
+        # If we detect a TT opening tag, run string through Template Toolkit Processor
+        if ( index( $template, '[%' ) != -1 ) { # Much faster than regex
+            my $use_template_cache = C4::Context->config('template_cache_dir')
+              && defined $ENV{GATEWAY_INTERFACE};
+
+            my $tt = Template->new(
+                {
+                    EVAL_PERL   => 1,
+                    ABSOLUTE    => 1,
+                    PLUGIN_BASE => 'Koha::Template::Plugin',
+                    COMPILE_EXT => $use_template_cache ? '.ttc' : '',
+                    COMPILE_DIR => $use_template_cache ? C4::Context->config('template_cache_dir') : '',
+                    FILTERS      => {},
+                    ENCODING     => 'UTF-8',
+                }
+            ) or die Template->error();
+
+            my $schema = Koha::Database->new->schema;
+
+            $schema->txn_begin;
+            try {
+                my $text;
+                $tt->process(
+                    \$template,
+                    {
+                        subscription      => $subscription,
+                        serialseq         => $serialseq,
+                        serialseq_x       => $subscription->lastvalue1(),
+                        serialseq_y       => $subscription->lastvalue2(),
+                        serialseq_z       => $subscription->lastvalue3(),
+                        subscriptionid    => $subscriptionid,
+                        biblionumber      => $biblionumber,
+                        status            => $status,
+                        planneddate       => $planneddate,
+                        publisheddate     => $publisheddate,
+                        publisheddatetext => $publisheddatetext,
+                        notes             => $notes,
+                        routingnotes      => $routingnotes,
+                    },
+                    \$text
+                );
+                $publisheddatetext = $text;
+            }
+            catch {
+                croak "ERROR PROCESSING TEMPLATE: $_ :: " . $template->error();
+            }
+            finally {
+                $schema->txn_rollback;
+            };
+        } else {
+            $publisheddatetext = $template;
+        }
+    }
+
     my $serial = Koha::Serial->new(
         {
             serialseq         => $serialseq,
@@ -1599,7 +1661,7 @@ sub NewIssue {
             publisheddate     => $publisheddate,
             publisheddatetext => $publisheddatetext,
             notes             => $notes,
-            routingnotes      => $routingnotes
+            routingnotes      => $routingnotes,
         }
     )->store();
 
diff --git a/installer/data/mysql/atomicupdate/bug_33039.pl b/installer/data/mysql/atomicupdate/bug_33039.pl
new file mode 100755
index 0000000000..980520d528
--- /dev/null
+++ b/installer/data/mysql/atomicupdate/bug_33039.pl
@@ -0,0 +1,18 @@
+use Modern::Perl;
+
+return {
+    bug_number => "33039",
+    description => "Add published on template to serial subscriptions table",
+    up => sub {
+        my ($args) = @_;
+        my ($dbh, $out) = @$args{qw(dbh out)};
+
+        if( !column_exists( 'subscription', 'published_on_template' ) ) {
+          $dbh->do(q{
+              ALTER TABLE subscription
+              ADD COLUMN `published_on_template` TEXT DEFAULT NULL COMMENT 'Template Toolkit syntax to generate the default "Published on (text)" field when receiving an issue this serial'
+              AFTER `ccode`
+          });
+        }
+    },
+};
diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql
index 03d6cbebc9..e459cbe539 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -5458,6 +5458,7 @@ CREATE TABLE `subscription` (
   `previousitemtype` varchar(10) DEFAULT NULL,
   `mana_id` int(11) DEFAULT NULL,
   `ccode` varchar(80) DEFAULT NULL COMMENT 'collection code to assign to serial items',
+  `published_on_template` TEXT DEFAULT NULL COMMENT 'Template Toolkit syntax to generate the default "Published on (text)" field when receiving an issue this serial',
   PRIMARY KEY (`subscriptionid`),
   KEY `subscription_ibfk_1` (`periodicity`),
   KEY `subscription_ibfk_2` (`numberpattern`),
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt
index e6918de53f..71a11a4cb0 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt
@@ -389,6 +389,10 @@ fieldset.rows table { clear: none; margin: 0; }
                                         </select>
                                         <span class="required">Required</span>
                                     </li>
+                                    <li>
+                                        <label for="published_on_template">Publication date template:</label>
+                                        <textarea id="published_on_template" name="published_on_template">[% published_on_template | html %]</textarea>
+                                    </li>
                                     <li>
                                         <label for="locale">Locale:</label>
                                         <select id="locale" name="locale">
diff --git a/serials/subscription-add.pl b/serials/subscription-add.pl
index c08142b897..70c7aaf1e5 100755
--- a/serials/subscription-add.pl
+++ b/serials/subscription-add.pl
@@ -330,6 +330,7 @@ sub redirect_add_subscription {
     my $previousitemtype  = $query->param('previousitemtype');
     my $skip_serialseq    = $query->param('skip_serialseq');
     my $ccode             = $query->param('ccode');
+    my $published_on_template = $query->param('published_on_template');
 
     my $mana_id;
     if ( $query->param('mana_id') ne "" ) {
@@ -356,7 +357,7 @@ sub redirect_add_subscription {
         join(";",@irregularity), $numberpattern, $locale, $callnumber,
         $manualhistory, $internalnotes, $serialsadditems,
         $staffdisplaycount, $opacdisplaycount, $graceperiod, $location, $enddate,
-        $skip_serialseq, $itemtype, $previousitemtype, $mana_id, $ccode
+        $skip_serialseq, $itemtype, $previousitemtype, $mana_id, $ccode, $published_on_template
     );
     if ( (C4::Context->preference('Mana') == 1) and ( grep { $_ eq "subscription" } split(/,/, C4::Context->preference('AutoShareWithMana'))) ){
         my $result = Koha::SharedContent::send_entity( $query->param('mana_language') || '', $loggedinuser, $subscriptionid, 'subscription');
@@ -445,6 +446,7 @@ sub redirect_mod_subscription {
     my $previousitemtype  = $query->param('previousitemtype');
     my $skip_serialseq    = $query->param('skip_serialseq');
     my $ccode             = $query->param('ccode');
+    my $published_on_template = $query->param('published_on_template');
 
     my $mana_id;
     if ( $query->param('mana_id') ne "" ) {
@@ -480,7 +482,7 @@ sub redirect_mod_subscription {
         $status, $biblionumber, $callnumber, $notes, $letter,
         $manualhistory, $internalnotes, $serialsadditems, $staffdisplaycount,
         $opacdisplaycount, $graceperiod, $location, $enddate, $subscriptionid,
-        $skip_serialseq, $itemtype, $previousitemtype, $mana_id, $ccode
+        $skip_serialseq, $itemtype, $previousitemtype, $mana_id, $ccode, $published_on_template
     );
 
     my @additional_fields;
diff --git a/t/db_dependent/Koha/Items.t b/t/db_dependent/Koha/Items.t
index 0c424f98db..31ad614d6e 100755
--- a/t/db_dependent/Koha/Items.t
+++ b/t/db_dependent/Koha/Items.t
@@ -1775,7 +1775,7 @@ subtest 'move_to_biblio() tests' => sub {
 
 subtest 'search_ordered' => sub {
 
-    plan tests => 6;
+    plan tests => 9;
 
     $schema->storage->txn_begin;
 
@@ -1837,7 +1837,8 @@ subtest 'search_ordered' => sub {
                 value => {
                     biblionumber  => $biblio->biblionumber,
                     periodicity   => $sub_freq->{id},
-                    numberpattern => $sub_np->{id}
+                    numberpattern => $sub_np->{id},
+                    published_on_template => "[% publisheddatetext %] [% biblionumber %]",
                 }
             }
         );
@@ -1892,6 +1893,10 @@ subtest 'search_ordered' => sub {
             [ $item3->itemnumber, $item2->itemnumber, $item1->itemnumber ],
             "serial - order by enumchron" );
 
+        is( $serial1->publisheddatetext, "publisheddatetext " . $biblio->biblionumber, "Column publisheddatetext rendered correctly from template for serial1" );
+        is( $serial2->publisheddatetext, "publisheddatetext " . $biblio->biblionumber, "Column publisheddatetext rendered correctly from template for serial2" );
+        is( $serial3->publisheddatetext, "publisheddatetext " . $biblio->biblionumber, "Column publisheddatetext rendered correctly from template for serial3" );
+
     }
 
     $schema->storage->txn_rollback;
-- 
2.30.2