@@ -, +, @@ - Apply this patch, - Launch installer/data/mysql/updatedatabase.pl - Launch misc/devel/update_dbix_class_files.pl - Create a daily subscription. i.e: - From: 2017-10-09, To: 2017-10-15, - Frequency: 1/day, - 7 issues, - test prediction pattern - check Wednesday and Thursday as irregularity, - save - Edit subscription, - Check that Wednesday and Thursday are still checked - Renew subscription from 2017-10-16 - Edit subscription, - Make sure that Wednesday and Thursday are still checked with corresponding serials - Do the same for a monthly and weekly subscription --- C4/Serials.pm | 142 +++++++------- Koha/Subscription.pm | 131 ++++++++++++- ...ug_17656-add-permanent-irregularities.perl | 9 + installer/data/mysql/kohastructure.sql | 1 + .../prog/css/src/staff-global.scss | 10 + .../serials/subscription_daily_choice.inc | 33 ++++ .../serials/subscription_monthly_choice.inc | 38 ++++ .../serials/subscription_weekly_choice.inc | 28 +++ .../modules/serials/showpredictionpattern.tt | 34 ++-- .../en/modules/serials/subscription-add.tt | 1 + .../en/modules/serials/subscription-renew.tt | 41 ++++ .../prog/js/showpredictionpattern.js | 21 ++- .../intranet-tmpl/prog/js/subscription-add.js | 77 +------- .../intranet-tmpl/prog/js/subscription.js | 78 ++++++++ serials/showpredictionpattern.pl | 15 +- serials/subscription-add.pl | 69 ++++--- serials/subscription-renew.pl | 53 +++++- t/Serials/IssueNumber.t | 47 +++++ t/db_dependent/Koha/Subscription.t | 39 +++- .../Koha/Subscription/GuessEnddate.t | 148 +++++++++++++++ .../Koha/Subscription/Irregularities.t | 175 ++++++++++++++++++ .../Serials/SubscriptionIrregularity.t | 35 ++++ 22 files changed, 1014 insertions(+), 211 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/Bug_17656-add-permanent-irregularities.perl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/serials/subscription_daily_choice.inc create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/serials/subscription_monthly_choice.inc create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/serials/subscription_weekly_choice.inc create mode 100644 koha-tmpl/intranet-tmpl/prog/js/subscription.js create mode 100644 t/Serials/IssueNumber.t create mode 100644 t/db_dependent/Koha/Subscription/GuessEnddate.t create mode 100644 t/db_dependent/Koha/Subscription/Irregularities.t create mode 100644 t/db_dependent/Serials/SubscriptionIrregularity.t --- a/C4/Serials.pm +++ a/C4/Serials.pm @@ -87,6 +87,7 @@ BEGIN { &CountIssues HasItems &subscriptionCurrentlyOnOrder + &issue_number ); } @@ -1263,37 +1264,6 @@ sub ModNextExpected { } -=head2 GetSubscriptionIrregularities - -=over 4 - -=item @irreg = &GetSubscriptionIrregularities($subscriptionid); -get the list of irregularities for a subscription - -=back - -=cut - -sub GetSubscriptionIrregularities { - my $subscriptionid = shift; - - return unless $subscriptionid; - - my $dbh = C4::Context->dbh; - my $query = qq{ - SELECT irregularity - FROM subscription - WHERE subscriptionid = ? - }; - my $sth = $dbh->prepare($query); - $sth->execute($subscriptionid); - - my ($result) = $sth->fetchrow_array; - my @irreg = split /;/, $result; - - return @irreg; -} - =head2 ModSubscription this function modifies a subscription. Put all new values on input args. @@ -1304,7 +1274,7 @@ returns the number of rows affected sub ModSubscription { my ( $auser, $branchcode, $aqbooksellerid, $cost, $aqbudgetid, $startdate, - $periodicity, $firstacquidate, $irregularity, $numberpattern, $locale, + $periodicity, $firstacquidate, $irregularity, $permanent_irregularity, $numberpattern, $locale, $numberlength, $weeklength, $monthlength, $lastvalue1, $innerloop1, $lastvalue2, $innerloop2, $lastvalue3, $innerloop3, $status, $biblionumber, $callnumber, $notes, $letter, $manualhistory, @@ -1338,6 +1308,7 @@ sub ModSubscription { letter => $letter, firstacquidate => $firstacquidate, irregularity => $irregularity, + permanent_irregularity => $permanent_irregularity, numberpattern => $numberpattern, locale => $locale, callnumber => $callnumber, @@ -1388,51 +1359,52 @@ sub NewSubscription { $startdate, $periodicity, $numberlength, $weeklength, $monthlength, $lastvalue1, $innerloop1, $lastvalue2, $innerloop2, $lastvalue3, $innerloop3, $status, $notes, $letter, $firstacquidate, $irregularity, - $numberpattern, $locale, $callnumber, $manualhistory, $internalnotes, - $serialsadditems, $staffdisplaycount, $opacdisplaycount, $graceperiod, + $permanent_irregularity, $numberpattern, $locale, $callnumber, $manualhistory, + $internalnotes, $serialsadditems, $staffdisplaycount, $opacdisplaycount, $graceperiod, $location, $enddate, $skip_serialseq, $itemtype, $previousitemtype, $mana_id ) = @_; my $dbh = C4::Context->dbh; my $subscription = Koha::Subscription->new( { - librarian => $auser, - branchcode => $branchcode, - aqbooksellerid => $aqbooksellerid, - cost => $cost, - aqbudgetid => $aqbudgetid, - biblionumber => $biblionumber, - startdate => $startdate, - periodicity => $periodicity, - numberlength => $numberlength, - weeklength => $weeklength, - monthlength => $monthlength, - lastvalue1 => $lastvalue1, - innerloop1 => $innerloop1, - lastvalue2 => $lastvalue2, - innerloop2 => $innerloop2, - lastvalue3 => $lastvalue3, - innerloop3 => $innerloop3, - status => $status, - notes => $notes, - letter => $letter, - firstacquidate => $firstacquidate, - irregularity => $irregularity, - numberpattern => $numberpattern, - locale => $locale, - callnumber => $callnumber, - manualhistory => $manualhistory, - internalnotes => $internalnotes, - serialsadditems => $serialsadditems, - staffdisplaycount => $staffdisplaycount, - opacdisplaycount => $opacdisplaycount, - graceperiod => $graceperiod, - location => $location, - enddate => $enddate, - skip_serialseq => $skip_serialseq, - itemtype => $itemtype, - previousitemtype => $previousitemtype, - mana_id => $mana_id, + librarian => $auser, + branchcode => $branchcode, + aqbooksellerid => $aqbooksellerid, + cost => $cost, + aqbudgetid => $aqbudgetid, + biblionumber => $biblionumber, + startdate => $startdate, + periodicity => $periodicity, + numberlength => $numberlength, + weeklength => $weeklength, + monthlength => $monthlength, + lastvalue1 => $lastvalue1, + innerloop1 => $innerloop1, + lastvalue2 => $lastvalue2, + innerloop2 => $innerloop2, + lastvalue3 => $lastvalue3, + innerloop3 => $innerloop3, + status => $status, + notes => $notes, + letter => $letter, + firstacquidate => $firstacquidate, + irregularity => $irregularity, + permanent_irregularity => $permanent_irregularity, + numberpattern => $numberpattern, + locale => $locale, + callnumber => $callnumber, + manualhistory => $manualhistory, + internalnotes => $internalnotes, + serialsadditems => $serialsadditems, + staffdisplaycount => $staffdisplaycount, + opacdisplaycount => $opacdisplaycount, + graceperiod => $graceperiod, + location => $location, + enddate => $enddate, + skip_serialseq => $skip_serialseq, + itemtype => $itemtype, + previousitemtype => $previousitemtype, + mana_id => $mana_id, } )->store; $subscription->discard_changes; @@ -2687,6 +2659,34 @@ sub findSerialsByStatus { return @$serials; } +=head2 issue_number + + my $week_number = issue_number($dt, 'week'); + +=cut + +sub issue_number { + my ($date, $issue_type) = @_; + + unless ( ref($date) eq 'DateTime' ) { + Koha::Exceptions::WrongParameter->throw("Date passed to issue_number is not a valid DateTime object" ); + } + + if ($issue_type eq 'day') { + return $date->dow; + } + + if ($issue_type eq 'week') { + return $date->week_number; + } + + if ($issue_type eq 'month') { + return $date->month; + } + + return 0; +} + 1; __END__ --- a/Koha/Subscription.pm +++ a/Koha/Subscription.pm @@ -21,6 +21,9 @@ use Modern::Perl; use Carp; +use C4::Serials::Frequency; +use C4::Serials qw(issue_number); + use Koha::Database; use Koha::Biblios; use Koha::Acquisition::Booksellers; @@ -28,7 +31,9 @@ use Koha::Biblioitems; use Koha::Subscriptions; use Koha::Subscription::Frequencies; use Koha::Subscription::Numberpatterns; +use Koha::DateUtils; use JSON; +use Date::Calc qw( Delta_Days Add_Delta_Days Add_Delta_YM ); use base qw(Koha::Object Koha::Object::Mixin::AdditionalFields); @@ -197,7 +202,131 @@ sub get_sharable_info { } -=head3 _type +=head2 irregularities + +Returns an array containing irregularities + +=cut + +sub irregularities { + my ($self) = @_; + + return split(';', $self->irregularity); +} + +=head2 permanent_irregularities + +Returns an array containing permanent irregularities + +=cut + +sub permanent_irregularities { + my ($self) = @_; + + return split(';', $self->permanent_irregularity); +} + +=head3 lengthtype + +Return the length type (issues, weeks, months) + +=cut + +sub lengthtype { + my ($self) = @_; + + if ($self->numberlength) { + return 'issues'; + } + + if ($self->weeklength) { + return 'weeks'; + } + + if ($self->monthlength) { + return 'months'; + } +} + +=head3 guess_irregularities + +my @irregularities = $subscription->guess_irregularities + +=cut + +sub guess_irregularities { + my ($self) = @_; + + my @irregularities; + my %permanent_irregularities = map { $_ => 1 } $self->permanent_irregularities; + + my $schema = Koha::Database->new->schema; + my $frequency = $schema->resultset('SubscriptionFrequency')->find($self->periodicity); + + my $enddate = $self->enddate; + my $nextexpected = C4::Serials::GetNextExpected($self->id); + my $date = $nextexpected->{planneddate}; + + my ($issuenumber) = C4::Serials::GetFictiveIssueNumber($self->unblessed, $date); + my $dow = issue_number( dt_from_string($date), $frequency->unit ); + + if ( defined( $permanent_irregularities{$dow} ) ) { + push @irregularities, $issuenumber; + } + + while ( Delta_Days( split(/-/, $date), split(/-/, $enddate) ) >= 0 ) { + $issuenumber++; + $date = C4::Serials::GetNextDate($self->unblessed, $date); + $dow = issue_number( dt_from_string($date), $frequency->unit ); + + if ( defined( $permanent_irregularities{$dow} ) ) { + push @irregularities, $issuenumber; + } + } + + return @irregularities; +} + +=head2 guess_enddate + +my $enddate = $subscription->guess_enddate; + +=cut + +sub guess_enddate { + my ($self) = @_; + + my ($year, $month, $day, $enddate); + my $startdate = $self->startdate; + my $numberlength = $self->numberlength; + my $weeklength = $self->weeklength; + my $monthlength = $self->monthlength; + + if($numberlength != 0) { + my $frequency = GetSubscriptionFrequency($self->periodicity); + if($frequency->{'unit'} eq 'day') { + ($year, $month, $day) = Add_Delta_Days(split(/-/, $startdate), $numberlength * $frequency->{'unitsperissue'} / $frequency->{'issuesperunit'}); + } elsif($frequency->{'unit'} eq 'week') { + ($year, $month, $day) = Add_Delta_Days(split(/-/, $startdate), $numberlength * 7 * $frequency->{'unitsperissue'} / $frequency->{'issuesperunit'}); + } elsif($frequency->{'unit'} eq 'month') { + ($year, $month, $day) = Add_Delta_YM(split(/-/, $startdate), 0, $numberlength * $frequency->{'unitsperissue'} / $frequency->{'issuesperunit'}); + } elsif($frequency->{'unit'} eq 'year') { + ($year, $month, $day) = Add_Delta_YM(split(/-/, $startdate), $numberlength * $frequency->{'unitsperissue'} / $frequency->{'issuesperunit'}, 0); + } + } elsif($weeklength != 0) { + ($year, $month, $day) = Add_Delta_Days(split(/-/, $startdate), $weeklength * 7); + } elsif($monthlength != 0) { + ($year, $month, $day) = Add_Delta_YM(split(/-/, $startdate), 0, $monthlength); + } + if(defined $year) { + $enddate = sprintf("%04d-%02d-%02d", $year, $month, $day); + } else { + undef $enddate; + } + return $enddate; +} + +=head3 type =cut --- a/installer/data/mysql/atomicupdate/Bug_17656-add-permanent-irregularities.perl +++ a/installer/data/mysql/atomicupdate/Bug_17656-add-permanent-irregularities.perl @@ -0,0 +1,9 @@ +$DBversion = 'XXX'; +if( CheckVersion( $DBversion ) ) { + if( !column_exists( 'subscription', 'permanent_irregularity' ) ) { + $dbh->do( "ALTER TABLE `subscription` ADD permanent_irregularity MEDIUMTEXT AFTER irregularity" ); + } + + SetVersion( $DBversion ); + print "Upgrade to $DBversion done (Bug 17656 - Irregularities in serial prediction pattern are planned only for current subscription)\n"; +} --- a/installer/data/mysql/kohastructure.sql +++ a/installer/data/mysql/kohastructure.sql @@ -4779,6 +4779,7 @@ CREATE TABLE `subscription` ( `firstacquidate` date DEFAULT NULL COMMENT 'first issue received date', `manualhistory` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'yes or no to managing the history manually', `irregularity` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'any irregularities in the subscription', + `permanent_irregularity` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'permanent irregularities for renewal', `skip_serialseq` tinyint(1) NOT NULL DEFAULT 0, `letter` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `numberpattern` int(11) DEFAULT NULL COMMENT 'the numbering pattern used links to subscription_numberpatterns.id', --- a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss +++ a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss @@ -4426,6 +4426,16 @@ div .suggestion_note { } } +.week-columns{ + -moz-column-count: 2; /* Firefox */ + -webkit-column-count: 2; /* Safari and Chrome */ + column-count: 3; +} + +fieldset.rows label.inline { + float: none; +} + @media (min-width: 200px) { } --- a/koha-tmpl/intranet-tmpl/prog/en/includes/serials/subscription_daily_choice.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/serials/subscription_daily_choice.inc @@ -0,0 +1,33 @@ +
+ If there is a day (or more) in the week where issues are never + published, you can check corresponding boxes below. +
+[% daily_choice = [ {name => 'monday', value => 1}, {name => 'tuesday', value => 2}, {name => 'wednesday', value => 3}, {name => 'thursday', value => 4}, {name => 'friday', value => 5}, {name => 'saturday', value => 6}, {name => 'sunday', value => 7} ] %] + +[% BLOCK days %] + [% SWITCH d %] + [% CASE 'monday' %]Monday + [% CASE 'tuesday' %]Tuesday + [% CASE 'wednesday' %]Wednesday + [% CASE 'thursday' %]Thursday + [% CASE 'friday' %]Friday + [% CASE 'saturday' %]Saturday + [% CASE 'sunday' %]Sunday + [% END %] +[% END %] + +[% FOREACH day IN daily_choice %] + [% IF permanent_irreg.grep( day.value ).0 == day.value %] + + [% ELSE %] + + [% END %] + +[% END %] --- a/koha-tmpl/intranet-tmpl/prog/en/includes/serials/subscription_monthly_choice.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/serials/subscription_monthly_choice.inc @@ -0,0 +1,38 @@ ++ If there is a month (or more) in the year where issues are never + published, you can check corresponding boxes below. +
+[% monthly_choice = [ {name => 'january', value => 1}, {name => 'february', value => 2}, {name => 'march', value => 3}, {name => 'april', value => 4}, {name => 'may', value => 5}, {name => 'june', value => 6}, {name => 'july', value => 7}, {name => 'august', value => 8}, {name => 'september', value => 9}, {name => 'october', value => 10}, {name => 'november', value => 11}, {name => 'december', value =>12} ] %] + +[% BLOCK months %] + [% SWITCH m %] + [% CASE 'january' %]January + [% CASE 'february' %]February + [% CASE 'march' %]March + [% CASE 'april' %]April + [% CASE 'may' %]May + [% CASE 'june' %]June + [% CASE 'july' %]July + [% CASE 'august' %]August + [% CASE 'september' %]September + [% CASE 'october' %]October + [% CASE 'november' %]November + [% CASE 'december' %]December + [% END %] +[% END %] + +[% FOREACH month IN monthly_choice %] + [% IF permanent_irreg.grep( month.value ).0 == month.value %] + + [% ELSE %] + + [% END %] + +[% END %] --- a/koha-tmpl/intranet-tmpl/prog/en/includes/serials/subscription_weekly_choice.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/serials/subscription_weekly_choice.inc @@ -0,0 +1,28 @@ ++ Choice the week(s) in the year where issues are never + published. +
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/showpredictionpattern.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/showpredictionpattern.tt @@ -5,25 +5,21 @@ [% END %] [% IF (ask_for_irregularities) %]Please check issues that are NOT published (irregularities)
- [% IF (daily_options) %] -- If there is a day (or more) in the week where issues are never - published, you can check corresponding boxes below. -
- - - - - - - - - - - - - - + [% IF (show_irregularity_options) %] + + [% IF (show_irregularity_options == 'day') %] + [% INCLUDE 'serials/subscription_daily_choice.inc' %] + [% ELSIF (show_irregularity_options == 'month') %] + [% INCLUDE 'serials/subscription_monthly_choice.inc' %] + [% ELSIF (show_irregularity_options == 'week') %] + [% INCLUDE 'serials/subscription_weekly_choice.inc' %] + [% END %] [% END %] [% END %] [% IF (predictions_loop) %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt @@ -587,6 +587,7 @@ fieldset.rows table { clear: none; margin: 0; } var BOOKSELLER_IDS = [% To.json( bookseller_ids ) || '[]' | $raw %]; + [% Asset.js("js/subscription.js") | $raw %] [% Asset.js("js/subscription-add.js") | $raw %] [% Asset.js("js/showpredictionpattern.js") | $raw %] [% END %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-renew.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-renew.tt @@ -1,5 +1,6 @@ [% USE Koha %] [% USE Branches %] +[% USE Asset %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] [% IF subscription %] @@ -30,6 +31,36 @@