View | Details | Raw Unified | Return to bug 11023
Collapse All | Expand All

(-)a/installer/data/mysql/kohastructure.sql (-2 / +2 lines)
Lines 946-952 CREATE TABLE `deleteditems` ( Link Here
946
  `enumchron` text default NULL, -- serial enumeration/chronology for the item (MARC21 952$h)
946
  `enumchron` text default NULL, -- serial enumeration/chronology for the item (MARC21 952$h)
947
  `copynumber` varchar(32) default NULL, -- copy number (MARC21 952$t)
947
  `copynumber` varchar(32) default NULL, -- copy number (MARC21 952$t)
948
  `stocknumber` varchar(32) default NULL, -- inventory number (MARC21 952$i)
948
  `stocknumber` varchar(32) default NULL, -- inventory number (MARC21 952$i)
949
  `new` VARCHAR(32) DEFAULT NULL, -- 'new' value, you can put whatever free-text information. This field is intented to be managed by the toggle_new_status cronjob.
949
  `new` VARCHAR(32) DEFAULT NULL, -- 'new' value, you can put whatever free-text information. This field is intented to be managed by the automatic_item_modification_by_age cronjob.
950
  PRIMARY KEY  (`itemnumber`),
950
  PRIMARY KEY  (`itemnumber`),
951
  KEY `delitembarcodeidx` (`barcode`),
951
  KEY `delitembarcodeidx` (`barcode`),
952
  KEY `delitemstocknumberidx` (`stocknumber`),
952
  KEY `delitemstocknumberidx` (`stocknumber`),
Lines 1246-1252 CREATE TABLE `items` ( -- holdings/item information Link Here
1246
  `enumchron` text default NULL, -- serial enumeration/chronology for the item (MARC21 952$h)
1246
  `enumchron` text default NULL, -- serial enumeration/chronology for the item (MARC21 952$h)
1247
  `copynumber` varchar(32) default NULL, -- copy number (MARC21 952$t)
1247
  `copynumber` varchar(32) default NULL, -- copy number (MARC21 952$t)
1248
  `stocknumber` varchar(32) default NULL, -- inventory number (MARC21 952$i)
1248
  `stocknumber` varchar(32) default NULL, -- inventory number (MARC21 952$i)
1249
  `new` VARCHAR(32) DEFAULT NULL, -- 'new' value, you can put whatever free-text information. This field is intended to be managed by the toggle_new_status cronjob.
1249
  `new` VARCHAR(32) DEFAULT NULL, -- 'new' value, you can put whatever free-text information. This field is intended to be managed by the automatic_item_modification_by_age cronjob.
1250
  PRIMARY KEY  (`itemnumber`),
1250
  PRIMARY KEY  (`itemnumber`),
1251
  UNIQUE KEY `itembarcodeidx` (`barcode`),
1251
  UNIQUE KEY `itembarcodeidx` (`barcode`),
1252
  KEY `itemstocknumberidx` (`stocknumber`),
1252
  KEY `itemstocknumberidx` (`stocknumber`),
(-)a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css (-1 / +1 lines)
Lines 2759-2765 span.onsite_checkout { Link Here
2759
    border : 1px solid #FFF2CE;
2759
    border : 1px solid #FFF2CE;
2760
}
2760
}
2761
2761
2762
/* Tools > toggle_new_status */
2762
/* Tools > automatic_item_modification_by_age */
2763
div.rules {
2763
div.rules {
2764
    display: block;
2764
    display: block;
2765
}
2765
}
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/toggle_new_status.tt (-1 / +1 lines)
Lines 38-44 Link Here
38
</ul>
38
</ul>
39
39
40
<h3>How to execute the cronjob script?</h3>
40
<h3>How to execute the cronjob script?</h3>
41
<p>The cronjob script is misc/cronjobs/toggle_new_status.pl.</p>
41
<p>The cronjob script is misc/cronjobs/automatic_item_modification_by_age.pl.</p>
42
<p>Try the -h parameter in order to see the help.</p>
42
<p>Try the -h parameter in order to see the help.</p>
43
<p>Without any parameter, the script will be launched in a dry-run mode. If the -c (or --confirm) flag is given, the script will apply the changes.</p>
43
<p>Without any parameter, the script will be launched in a dry-run mode. If the -c (or --confirm) flag is given, the script will apply the changes.</p>
44
44
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/toggle_new_status.tt (-5 / +5 lines)
Lines 113-122 Link Here
113
//]]>
113
//]]>
114
</script>
114
</script>
115
</head>
115
</head>
116
<body id="tools_toggle_new_status" class="tools">
116
<body id="tools_automatic_item_modification_by_age" class="tools">
117
[% INCLUDE 'header.inc' %]
117
[% INCLUDE 'header.inc' %]
118
[% INCLUDE 'cat-search.inc' %]
118
[% INCLUDE 'cat-search.inc' %]
119
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; <a href="/cgi-bin/koha/tools/toggle_new_status.pl">Automatic item modifications by age</a></div>
119
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; <a href="/cgi-bin/koha/tools/automatic_item_modification_by_age.pl">Automatic item modifications by age</a></div>
120
120
121
<div id="doc3" class="yui-t2">
121
<div id="doc3" class="yui-t2">
122
  <div id="bd">
122
  <div id="bd">
Lines 124-130 Link Here
124
      <div class="yui-b">
124
      <div class="yui-b">
125
        <h3>Automatic item modifications by age</h3>
125
        <h3>Automatic item modifications by age</h3>
126
        <div id="toolbar" class="btn-toolbar">
126
        <div id="toolbar" class="btn-toolbar">
127
          <a class="btn btn-small" id="newentry" href="/cgi-bin/koha/tools/toggle_new_status.pl?op=edit_form"><i class="icon-plus"></i> Edit</a>
127
          <a class="btn btn-small" id="newentry" href="/cgi-bin/koha/tools/automatic_item_modification_by_age.pl?op=edit_form"><i class="icon-plus"></i> Edit</a>
128
        </div>
128
        </div>
129
        [% FOR message IN messages %]
129
        [% FOR message IN messages %]
130
          [% IF message.type == "error" %]
130
          [% IF message.type == "error" %]
Lines 137-143 Link Here
137
        [% END %]
137
        [% END %]
138
138
139
        [% IF op == 'edit_form' %]
139
        [% IF op == 'edit_form' %]
140
          <form method="post" action="/cgi-bin/koha/tools/toggle_new_status.pl">
140
          <form method="post" action="/cgi-bin/koha/tools/automatic_item_modification_by_age.pl">
141
            <div id="edit_rules">
141
            <div id="edit_rules">
142
              <h4>List of rules</h4>
142
              <h4>List of rules</h4>
143
                <div id="rules">
143
                <div id="rules">
Lines 200-206 Link Here
200
                </div>
200
                </div>
201
              <fieldset class="action">
201
              <fieldset class="action">
202
                <input type="hidden" name="op" value="update" />
202
                <input type="hidden" name="op" value="update" />
203
                <a class="cancel" href="/cgi-bin/koha/tools/toggle_new_status.pl">Cancel</a>
203
                <a class="cancel" href="/cgi-bin/koha/tools/automatic_item_modification_by_age.pl">Cancel</a>
204
                <input type="submit" value="Submit theses rules" />
204
                <input type="submit" value="Submit theses rules" />
205
              </fieldset>
205
              </fieldset>
206
            </div>
206
            </div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt (-1 / +1 lines)
Lines 128-134 Link Here
128
    [% END %]
128
    [% END %]
129
129
130
    [% IF ( CAN_user_tools_items_batchmod ) %]
130
    [% IF ( CAN_user_tools_items_batchmod ) %]
131
      <dt><a href="/cgi-bin/koha/tools/toggle_new_status.pl">Automatic item modifications by age</a></dt>
131
      <dt><a href="/cgi-bin/koha/tools/automatic_item_modification_by_age.pl">Automatic item modifications by age</a></dt>
132
      <dd>Define rules to modify items by age</dd>
132
      <dd>Define rules to modify items by age</dd>
133
    [% END %]
133
    [% END %]
134
134
(-)a/misc/cronjobs/automatic_item_modification_by_age.pl (-3 / +3 lines)
Lines 21-27 pod2usage(1) if $help; Link Here
21
$verbose = 1 unless $confirm;
21
$verbose = 1 unless $confirm;
22
22
23
# Load configuration from the syspref
23
# Load configuration from the syspref
24
my $syspref_content = C4::Context->preference('toggle_new_status_configuration');
24
my $syspref_content = C4::Context->preference('automatic_item_modification_by_age_configuration');
25
my $rules = eval { JSON::from_json( $syspref_content ) };
25
my $rules = eval { JSON::from_json( $syspref_content ) };
26
pod2usage({ -message => "Unable to load the configuration : $@", -exitval => 1 })
26
pod2usage({ -message => "Unable to load the configuration : $@", -exitval => 1 })
27
    if $@;
27
    if $@;
Lines 51-61 __END__ Link Here
51
51
52
=head1 NAME
52
=head1 NAME
53
53
54
toggle_new_status.pl
54
automatic_item_modification_by_age.pl
55
55
56
=head1 SYNOPSIS
56
=head1 SYNOPSIS
57
57
58
./toggle_new_status.pl -h
58
./automatic_item_modification_by_age.pl -h
59
59
60
Toggle recent acquisitions status.
60
Toggle recent acquisitions status.
61
Use this script to delete "new" status for items.
61
Use this script to delete "new" status for items.
(-)a/t/db_dependent/Items/ToggleNewStatus.t (-283 lines)
Lines 1-283 Link Here
1
#!/usr/bin/perl
2
3
use Modern::Perl;
4
use Test::More tests => 16;
5
use MARC::Record;
6
use MARC::Field;
7
use DateTime;
8
use DateTime::Duration;
9
10
use C4::Biblio;
11
use C4::Context;
12
use C4::Items;
13
use Koha::DateUtils;
14
15
my $dbh = C4::Context->dbh;
16
$dbh->{AutoCommit} = 0;
17
$dbh->{RaiseError} = 1;
18
19
$dbh->do(q|
20
    DELETE FROM marc_subfield_structure
21
    WHERE kohafield = 'items.new' OR kohafield = 'items.stocknumber'
22
|);
23
24
my $new_tagfield = 'i';
25
$dbh->do(qq|
26
    INSERT INTO marc_subfield_structure(tagfield, tagsubfield, kohafield, frameworkcode)
27
    VALUES ( 952, '$new_tagfield', 'items.new', '' )
28
|);
29
30
my $record = MARC::Record->new();
31
$record->append_fields(
32
    MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
33
    MARC::Field->new('245', ' ', ' ', a => 'Silence in the library'),
34
    MARC::Field->new('942', ' ', ' ', c => 'ITEMTYPE_T'),
35
);
36
my ($biblionumber, undef) = C4::Biblio::AddBiblio($record, '');
37
38
my ($item_bibnum, $item_bibitemnum, $itemnumber) = C4::Items::AddItem(
39
    {
40
        homebranch => 'CPL',
41
        holdingbranch => 'CPL',
42
        new => 'new_value',
43
        ccode => 'FIC',
44
    },
45
    $biblionumber
46
);
47
48
my $item = C4::Items::GetItem( $itemnumber );
49
is ( $item->{new}, 'new_value', q|AddItem insert the 'new' field| );
50
51
my ( $tagfield, undef ) = GetMarcFromKohaField('items.itemnumber', '');
52
my $marc_item = C4::Items::GetMarcItem( $biblionumber, $itemnumber );
53
is( $marc_item->subfield($tagfield, $new_tagfield), 'new_value', q|Koha mapping is correct|);
54
55
# Update the items.new field if items.ccode eq 'FIC' => should be updated
56
my @rules = (
57
    {
58
        conditions => [
59
            {
60
                field => 'items.ccode',
61
                value => 'FIC',
62
            },
63
        ],
64
        substitutions => [
65
            {
66
                field => 'items.new',
67
                value => 'updated_value',
68
             },
69
        ],
70
        age => '0',
71
    },
72
);
73
74
C4::Items::ToggleNewStatus( { rules => \@rules } );
75
76
my $modified_item = C4::Items::GetItem( $itemnumber );
77
is( $modified_item->{new}, 'updated_value', q|ToggleNewStatus: The new value is updated|);
78
$marc_item = C4::Items::GetMarcItem( $biblionumber, $itemnumber );
79
is( $marc_item->subfield($tagfield, $new_tagfield), 'updated_value', q|ToggleNewStatus: The new value is updated| );
80
81
# Update the items.new field if items.ccode eq 'DONT_EXIST' => should not be updated
82
@rules = (
83
    {
84
        conditions => [
85
            {
86
                field => 'items.ccode',
87
                value => 'DONT_EXIST',
88
            },
89
        ],
90
        substitutions => [
91
            {
92
                field => 'items.new',
93
                value => 'new_updated_value',
94
             },
95
        ],
96
        age => '0',
97
    },
98
);
99
100
C4::Items::ToggleNewStatus( { rules => \@rules } );
101
102
$modified_item = C4::Items::GetItem( $itemnumber );
103
is( $modified_item->{new}, 'updated_value', q|ToggleNewStatus: The new value is not updated|);
104
$marc_item = C4::Items::GetMarcItem( $biblionumber, $itemnumber );
105
is( $marc_item->subfield($tagfield, $new_tagfield), 'updated_value', q|ToggleNewStatus: The new value is not updated| );
106
107
# Play with age
108
$item = C4::Items::GetItem( $itemnumber );
109
my $dt_today = dt_from_string;
110
my $days5ago = $dt_today->add_duration( DateTime::Duration->new( days => -5 ) );
111
112
C4::Items::ModItem( { dateaccessioned => $days5ago }, $biblionumber, $itemnumber );
113
$item = C4::Items::GetItem( $itemnumber );
114
115
@rules = (
116
    {
117
        conditions => [
118
            {
119
                field => 'items.ccode',
120
                value => 'FIC',
121
            },
122
        ],
123
        substitutions => [
124
            {
125
                field => 'items.new',
126
                value => 'new_updated_value',
127
             },
128
        ],
129
        age => '10',
130
    },
131
);
132
C4::Items::ToggleNewStatus( { rules => \@rules } );
133
$modified_item = C4::Items::GetItem( $itemnumber );
134
is( $modified_item->{new}, 'updated_value', q|ToggleNewStatus: Age = 10 : The new value is not updated|);
135
136
$rules[0]->{age} = 5;
137
$rules[0]->{substitutions}[0]{value} = 'new_updated_value5';
138
C4::Items::ToggleNewStatus( { rules => \@rules } );
139
$modified_item = C4::Items::GetItem( $itemnumber );
140
is( $modified_item->{new}, 'new_updated_value5', q|ToggleNewStatus: Age = 5 : The new value is updated|);
141
142
$rules[0]->{age} = '';
143
$rules[0]->{substitutions}[0]{value} = 'new_updated_value_empty_string';
144
C4::Items::ToggleNewStatus( { rules => \@rules } );
145
$modified_item = C4::Items::GetItem( $itemnumber );
146
is( $modified_item->{new}, 'new_updated_value_empty_string', q|ToggleNewStatus: Age = '' : The new value is updated|);
147
148
$rules[0]->{age} = undef;
149
$rules[0]->{substitutions}[0]{value} = 'new_updated_value_undef';
150
C4::Items::ToggleNewStatus( { rules => \@rules } );
151
$modified_item = C4::Items::GetItem( $itemnumber );
152
is( $modified_item->{new}, 'new_updated_value_undef', q|ToggleNewStatus: Age = undef : The new value is updated|);
153
154
# Field deletion
155
@rules = (
156
    {
157
        conditions => [
158
            {
159
                field => 'items.ccode',
160
                value => 'FIC',
161
            },
162
        ],
163
        substitutions => [
164
            {
165
                field => 'items.new',
166
                value => '',
167
             },
168
        ],
169
        age => '0',
170
    },
171
);
172
173
C4::Items::ToggleNewStatus( { rules => \@rules } );
174
175
$modified_item = C4::Items::GetItem( $itemnumber );
176
is( $modified_item->{new}, '', q|ToggleNewStatus: The new value is empty|);
177
$marc_item = C4::Items::GetMarcItem( $biblionumber, $itemnumber );
178
is( $marc_item->subfield($tagfield, $new_tagfield), undef, q|ToggleNewStatus: The new field is removed from the item marc| );
179
180
# conditions multiple
181
@rules = (
182
    {
183
        conditions => [
184
            {
185
                field => 'items.ccode',
186
                value => 'FIC',
187
            },
188
            {
189
                field => 'items.homebranch',
190
                value => 'CPL',
191
            },
192
        ],
193
        substitutions => [
194
            {
195
                field => 'items.new',
196
                value => 'new_value',
197
             },
198
        ],
199
        age => '0',
200
    },
201
);
202
203
C4::Items::ToggleNewStatus( { rules => \@rules } );
204
205
$modified_item = C4::Items::GetItem( $itemnumber );
206
is( $modified_item->{new}, 'new_value', q|ToggleNewStatus: conditions multiple: all match, the new value is updated|);
207
208
@rules = (
209
    {
210
        conditions => [
211
            {
212
                field => 'items.ccode',
213
                value => 'FIC',
214
            },
215
            {
216
                field => 'items.homebranch',
217
                value => 'DONT_EXIST',
218
            },
219
        ],
220
        substitutions => [
221
            {
222
                field => 'items.new',
223
                value => 'new_updated_value',
224
             },
225
        ],
226
        age => '0',
227
    },
228
);
229
230
C4::Items::ToggleNewStatus( { rules => \@rules } );
231
232
$modified_item = C4::Items::GetItem( $itemnumber );
233
is( $modified_item->{new}, 'new_value', q|ToggleNewStatus: conditions multiple: at least 1 condition does not match, the new value is not updated|);
234
235
@rules = (
236
    {
237
        conditions => [
238
            {
239
                field => 'items.ccode',
240
                value => 'FIC|NFIC',
241
            },
242
            {
243
                field => 'items.homebranch',
244
                value => 'MPL|CPL',
245
            },
246
        ],
247
        substitutions => [
248
            {
249
                field => 'items.new',
250
                value => 'new_updated_value',
251
             },
252
        ],
253
        age => '0',
254
    },
255
);
256
257
C4::Items::ToggleNewStatus( { rules => \@rules } );
258
259
$modified_item = C4::Items::GetItem( $itemnumber );
260
is( $modified_item->{new}, 'new_updated_value', q|ToggleNewStatus: conditions multiple: the 2 conditions match, the new value is updated|);
261
262
@rules = (
263
    {
264
        conditions => [
265
            {
266
                field => 'biblioitems.itemtype',
267
                value => 'ITEMTYPE_T',
268
            },
269
        ],
270
        substitutions => [
271
            {
272
                field => 'items.new',
273
                value => 'another_new_updated_value',
274
             },
275
        ],
276
        age => '0',
277
    },
278
);
279
280
C4::Items::ToggleNewStatus( { rules => \@rules } );
281
282
$modified_item = C4::Items::GetItem( $itemnumber );
283
is( $modified_item->{new}, 'another_new_updated_value', q|ToggleNewStatus: conditions on biblioitems|);
(-)a/tools/toggle_new_status.pl (-4 / +3 lines)
Lines 19-25 Link Here
19
19
20
=head1 NAME
20
=head1 NAME
21
21
22
toggle_new_status.pl: Update new status for items.
22
automatic_item_modification_by_age.pl: Update new status for items.
23
23
24
=cut
24
=cut
25
25
Lines 45-51 my $cgi = new CGI; Link Here
45
# open template
45
# open template
46
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
46
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
47
    {
47
    {
48
        template_name   => "tools/toggle_new_status.tt",
48
        template_name   => "tools/automatic_item_modification_by_age.tt",
49
        query           => $cgi,
49
        query           => $cgi,
50
        type            => "intranet",
50
        type            => "intranet",
51
        authnotrequired => 0,
51
        authnotrequired => 0,
Lines 55-61 my ( $template, $loggedinuser, $cookie ) = get_template_and_user( Link Here
55
55
56
my $op = $cgi->param('op') // 'show';
56
my $op = $cgi->param('op') // 'show';
57
57
58
my $syspref_name = q|toggle_new_status_configuration|;
58
my $syspref_name = q|automatic_item_modification_by_age_configuration|;
59
if ( $op eq 'update' ) {
59
if ( $op eq 'update' ) {
60
    my @rules;
60
    my @rules;
61
    my @unique_ids = $cgi->param('unique_id');
61
    my @unique_ids = $cgi->param('unique_id');
62
- 

Return to bug 11023