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

(-)a/Koha/Patron.pm (-3 / +14 lines)
Lines 394-400 sub store { Link Here
394
                }
394
                }
395
395
396
                # Actionlogs
396
                # Actionlogs
397
                if ( C4::Context->preference("BorrowersLog") ) {
397
                if ( C4::Context->preference("BorrowersLog") || C4::Context->preference("CardnumberLog") ) {
398
                    my $info;
398
                    my $info;
399
                    my $from_storage = $self_from_storage->unblessed;
399
                    my $from_storage = $self_from_storage->unblessed;
400
                    my $from_object  = $self->unblessed;
400
                    my $from_object  = $self->unblessed;
Lines 406-412 sub store { Link Here
406
                        if $from_object->{dateexpiry};
406
                        if $from_object->{dateexpiry};
407
407
408
                    my @skip_fields = (qw/lastseen updated_on/);
408
                    my @skip_fields = (qw/lastseen updated_on/);
409
                    for my $key ( keys %{$from_storage} ) {
409
                    my @keys = C4::Context->preference("BorrowersLog") ? keys %{$from_storage} : ('cardnumber');
410
                    for my $key ( @keys ) {
410
                        next if any { /$key/ } @skip_fields;
411
                        next if any { /$key/ } @skip_fields;
411
                        my $storage_value = $from_storage->{$key} // q{};
412
                        my $storage_value = $from_storage->{$key} // q{};
412
                        my $object_value  = $from_object->{$key}  // q{};
413
                        my $object_value  = $from_object->{$key}  // q{};
Lines 429-435 sub store { Link Here
429
                                $info,
430
                                $info,
430
                                { utf8 => 1, pretty => 1, canonical => 1 }
431
                                { utf8 => 1, pretty => 1, canonical => 1 }
431
                            )
432
                            )
432
                        );
433
                        ) if C4::Context->preference("BorrowersLog");
434
                        logaction(
435
                            "MEMBERS",
436
                            "MODIFY_CARDNUMBER",
437
                            $self->borrowernumber,
438
                            to_json(
439
                                $info->{cardnumber},
440
                                { utf8 => 1, pretty => 1, canonical => 1 }
441
                            )
442
                        ) if defined $info->{cardnumber} && C4::Context->preference("CardnumberLog");
443
433
                    }
444
                    }
434
                }
445
                }
435
446
(-)a/installer/data/mysql/atomicupdate/bug_39452_add_cardnumberlog.pl (+19 lines)
Line 0 Link Here
1
use Modern::Perl;
2
use Koha::Installer::Output qw(say_warning say_success say_info);
3
4
return {
5
    bug_number  => "39452",
6
    description => "Add CardnumberLog Preference",
7
    up          => sub {
8
        my ($args) = @_;
9
        my ( $dbh, $out ) = @$args{qw(dbh out)};
10
11
        # Do you stuffs here
12
        $dbh->do(q{
13
            INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
14
            ('CardnumberLog','1',NULL,'If ON, log edit actions on patron cardnumbers','YesNo')
15
        });
16
17
        say $out "Added new system preference 'CardnumberLog'";
18
    },
19
};
(-)a/installer/data/mysql/mandatory/sysprefs.sql (+1 lines)
Lines 142-147 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
142
('CanMarkHoldsToPullAsLost','do_not_allow','do_not_allow|allow|allow_and_notify','Add a button to the "Holds to pull" screen to mark an item as lost and notify the patron.','Choice'),
142
('CanMarkHoldsToPullAsLost','do_not_allow','do_not_allow|allow|allow_and_notify','Add a button to the "Holds to pull" screen to mark an item as lost and notify the patron.','Choice'),
143
('canreservefromotherbranches','1','','With Independent branches on, can a user from one library place a hold on an item from another library','YesNo'),
143
('canreservefromotherbranches','1','','With Independent branches on, can a user from one library place a hold on an item from another library','YesNo'),
144
('CardnumberLength', '', '', 'Set a length for card numbers with a maximum of 32 characters.', 'Free'),
144
('CardnumberLength', '', '', 'Set a length for card numbers with a maximum of 32 characters.', 'Free'),
145
('CardnumberLog','1',NULL,'If ON, log edit actions on patron cardnumbers','YesNo'),
145
('casAuthentication','0','','Enable or disable CAS authentication','YesNo'),
146
('casAuthentication','0','','Enable or disable CAS authentication','YesNo'),
146
('casLogout','0','','Does a logout from Koha should also log the user out of CAS?','YesNo'),
147
('casLogout','0','','Does a logout from Koha should also log the user out of CAS?','YesNo'),
147
('casServerUrl','https://localhost:8443/cas','','URL of the cas server','Free'),
148
('casServerUrl','https://localhost:8443/cas','','URL of the cas server','Free'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/action-logs.inc (+2 lines)
Lines 145-150 Link Here
145
        <span>Overdue</span>
145
        <span>Overdue</span>
146
    [% CASE 'EXPIRE' %]
146
    [% CASE 'EXPIRE' %]
147
        <span>Expire</span>
147
        <span>Expire</span>
148
    [% CASE 'MODIFY_CARDNUMBER' %]
149
        <span>Modify cardnumber</span>
148
    [% CASE %]
150
    [% CASE %]
149
        [% action | html %]
151
        [% action | html %]
150
    [% END %]
152
    [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/logs.pref (+6 lines)
Lines 12-17 Logging: Link Here
12
                  1: Log
12
                  1: Log
13
                  0: "Don't log"
13
                  0: "Don't log"
14
            - changes to patron records and patron restrictions.
14
            - changes to patron records and patron restrictions.
15
        -
16
            - pref: CardnumberLog
17
              choices:
18
                  1: Log
19
                  0: "Don't log"
20
            - changes to patron cardnumbers.
15
        -
21
        -
16
            - pref: CataloguingLog
22
            - pref: CataloguingLog
17
              choices:
23
              choices:
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt (-1 / +1 lines)
Lines 147-153 Link Here
147
                            <label for="actionALL" class="viewlog"><input type="checkbox" id="actionALL" name="actions" value="" /> All</label>
147
                            <label for="actionALL" class="viewlog"><input type="checkbox" id="actionALL" name="actions" value="" /> All</label>
148
                        [% END %]
148
                        [% END %]
149
149
150
                        [% FOREACH actx IN [ 'ADD' 'DELETE' 'MODIFY' 'ISSUE' 'RETURN' 'RENEW' 'CREATE' 'CANCEL' 'FILL' 'SUSPEND' 'RESUME' 'ADDCIRCMESSAGE' 'MODCIRCMESSAGE' 'DELCIRCMESSAGE' 'STATUS_CHANGE' 'PATRON_NOTICE' 'CHANGE PASS' 'RESET PASS' 'Run' 'End' 'EDIT_MAPPINGS' 'RESET_MAPPINGS' 'ADD_BASKET' 'MODIFY_BASKET' 'MODIFY_BASKET_HEADER' 'MODIFY_BASKET_USERS' 'CLOSE_BASKET' 'APPROVE_BASKET' 'REOPEN_BASKET' 'CANCEL_ORDER' 'CREATE_ORDER' 'MODIFY_ORDER' 'CREATE_INVOICE_ADJUSTMENT' 'UPDATE_INVOICE_ADJUSTMENT' 'DELETE_INVOICE_ADJUSTMENT' 'RECEIVE_ORDER' 'MODIFY_BUDGET' 'MODIFY_FUND' 'CREATE_FUND' 'DELETE_FUND' 'ACQUISITION CLAIM' 'ACQUISITION ORDER' 'OVERDUE' 'EXPIRE' 'CREATE_RESTRICTION' 'MODIFY_RESTRICTION' 'DELETE_RESTRICTION' ] %]
150
                        [% FOREACH actx IN [ 'ADD' 'DELETE' 'MODIFY' 'ISSUE' 'RETURN' 'RENEW' 'CREATE' 'CANCEL' 'FILL' 'SUSPEND' 'RESUME' 'ADDCIRCMESSAGE' 'MODCIRCMESSAGE' 'DELCIRCMESSAGE' 'STATUS_CHANGE' 'PATRON_NOTICE' 'CHANGE PASS' 'RESET PASS' 'Run' 'End' 'EDIT_MAPPINGS' 'RESET_MAPPINGS' 'ADD_BASKET' 'MODIFY_BASKET' 'MODIFY_BASKET_HEADER' 'MODIFY_BASKET_USERS' 'CLOSE_BASKET' 'APPROVE_BASKET' 'REOPEN_BASKET' 'CANCEL_ORDER' 'CREATE_ORDER' 'MODIFY_ORDER' 'CREATE_INVOICE_ADJUSTMENT' 'UPDATE_INVOICE_ADJUSTMENT' 'DELETE_INVOICE_ADJUSTMENT' 'RECEIVE_ORDER' 'MODIFY_BUDGET' 'MODIFY_FUND' 'CREATE_FUND' 'DELETE_FUND' 'ACQUISITION CLAIM' 'ACQUISITION ORDER' 'OVERDUE' 'EXPIRE' 'CREATE_RESTRICTION' 'MODIFY_RESTRICTION' 'DELETE_RESTRICTION' 'MODIFY_CARDNUMBER' ] %]
151
                            [% IF actions.grep(actx).size %]
151
                            [% IF actions.grep(actx).size %]
152
                                <label for="action[% actx| replace('\s+', '_') | html %]" class="viewlog"
152
                                <label for="action[% actx| replace('\s+', '_') | html %]" class="viewlog"
153
                                    ><input type="checkbox" id="action[% actx | replace('\s+', '_') | html %]" name="actions" value="[% actx | html %]" checked="checked" /> [% PROCESS translate_log_action action=actx %]</label
153
                                    ><input type="checkbox" id="action[% actx | replace('\s+', '_') | html %]" name="actions" value="[% actx | html %]" checked="checked" /> [% PROCESS translate_log_action action=actx %]</label
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt (-1 / +1 lines)
Lines 1514-1520 Link Here
1514
                        <td class="barcode" property="serialNumber">[% ITEM_RESULT.barcode | html %]</td>
1514
                        <td class="barcode" property="serialNumber">[% ITEM_RESULT.barcode | html %]</td>
1515
                    [% END %]
1515
                    [% END %]
1516
1516
1517
                    [% IF item_level_holds > 0 %]
1517
                    [% IF item_level_holds > 0 || show_priority %]
1518
                        <td class="holds_count">
1518
                        <td class="holds_count">
1519
                            [% IF holds_count.defined %][% ITEM_RESULT.holds_count | html %][% END %]
1519
                            [% IF holds_count.defined %][% ITEM_RESULT.holds_count | html %][% END %]
1520
                            [% IF ITEM_RESULT.priority %]
1520
                            [% IF ITEM_RESULT.priority %]
(-)a/t/db_dependent/Koha/Patrons.t (-4 / +37 lines)
Lines 2019-2028 $nb_of_patrons = Koha::Patrons->search->count; Link Here
2019
$retrieved_patron_1->delete;
2019
$retrieved_patron_1->delete;
2020
is( Koha::Patrons->search->count, $nb_of_patrons - 1, 'Delete should have deleted the patron' );
2020
is( Koha::Patrons->search->count, $nb_of_patrons - 1, 'Delete should have deleted the patron' );
2021
2021
2022
subtest 'BorrowersLog tests' => sub {
2022
subtest 'BorrowersLog and CardnumberLog tests' => sub {
2023
    plan tests => 5;
2023
    plan tests => 13;
2024
2024
2025
    t::lib::Mocks::mock_preference( 'BorrowersLog', 1 );
2025
    t::lib::Mocks::mock_preference( 'BorrowersLog', 1 );
2026
    t::lib::Mocks::mock_preference( 'CardnumberLog', 0 );
2026
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
2027
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
2027
2028
2028
    my $cardnumber = $patron->cardnumber;
2029
    my $cardnumber = $patron->cardnumber;
Lines 2042-2048 subtest 'BorrowersLog tests' => sub { Link Here
2042
        ->search( { module => 'MEMBERS', action => 'MODIFY', object => $patron->borrowernumber } );
2043
        ->search( { module => 'MEMBERS', action => 'MODIFY', object => $patron->borrowernumber } );
2043
    is( scalar @logs, 1, 'With BorrowerLogs and TrackLastPatronActivityTriggers we should not spam the logs' );
2044
    is( scalar @logs, 1, 'With BorrowerLogs and TrackLastPatronActivityTriggers we should not spam the logs' );
2044
2045
2045
    Koha::ActionLogs->search()->delete();
2046
    # Clear the logs for this patron
2047
    Koha::ActionLogs->search({ object => $patron->borrowernumber })->delete();
2046
    $patron->get_from_storage();
2048
    $patron->get_from_storage();
2047
    $patron->set( { debarred => "" } );
2049
    $patron->set( { debarred => "" } );
2048
    $patron->store;
2050
    $patron->store;
Lines 2057-2062 subtest 'BorrowersLog tests' => sub { Link Here
2057
        defined $log,
2059
        defined $log,
2058
        "No action log generated where incoming changed column is empty string and value in storage is NULL"
2060
        "No action log generated where incoming changed column is empty string and value in storage is NULL"
2059
    );
2061
    );
2062
2063
    t::lib::Mocks::mock_preference( 'CardnumberLog', 1);
2064
    $patron->set( { cardnumber => 'TESTCARDNUMBER_1' } )->store;
2065
    @logs = $schema->resultset('ActionLog')
2066
        ->search( { module => 'MEMBERS', action => 'MODIFY', object => $patron->borrowernumber } );
2067
    is( scalar @logs, 1, 'With BorrowersLog, one detailed MODIFY action should be logged for the modification.' );
2068
    @logs = $schema->resultset('ActionLog')
2069
        ->search( { module => 'MEMBERS', action => 'MODIFY_CARDNUMBER', object => $patron->borrowernumber } );
2070
    is( scalar @logs, 1, 'With CardnumberLog, one detailed MODIFY_CARDNUMBER action should be logged for the modification.' );
2071
2072
    t::lib::Mocks::mock_preference( 'BorrowersLog', 0 );
2073
    $patron->set( { cardnumber => 'TESTCARDNUMBER' } )->store;
2074
    @logs = $schema->resultset('ActionLog')
2075
        ->search( { module => 'MEMBERS', action => 'MODIFY', object => $patron->borrowernumber } );
2076
    is( scalar @logs, 1, 'With Cardnumberlog and not BorrowersLog, no more detailed MODIFY action should be logged for the modification.' );
2077
    @logs = $schema->resultset('ActionLog')
2078
        ->search( { module => 'MEMBERS', action => 'MODIFY_CARDNUMBER', object => $patron->borrowernumber } );
2079
    is( scalar @logs, 2, 'With CardnumberLogs, one more detailed MODIFY_CARDNUMBER action should be logged for the modification.' );
2080
    $log_info = from_json( $logs[1]->info );
2081
    is( $log_info->{after},  'TESTCARDNUMBER', 'Got correct new cardnumber' );
2082
    is( $log_info->{before}, 'TESTCARDNUMBER_1',      'Got correct old cardnumber' );
2083
2084
    t::lib::Mocks::mock_preference( 'CardnumberLog', 0);
2085
    $patron->set( { cardnumber => 'TESTCARDNUMBER_1' } )->store;
2086
    @logs = $schema->resultset('ActionLog')
2087
        ->search( { module => 'MEMBERS', action => 'MODIFY', object => $patron->borrowernumber } );
2088
    is( scalar @logs, 1, 'With neither Cardnumberlog nor BorrowersLog, no more detailed MODIFY action should be logged for the modification.' );
2089
    @logs = $schema->resultset('ActionLog')
2090
        ->search( { module => 'MEMBERS', action => 'MODIFY_CARDNUMBER', object => $patron->borrowernumber } );
2091
    is( scalar @logs, 2, 'With niether CardnumberLog nor BorrowersLog, one detailed MODIFY_CARDNUMBER action should be logged for the modification.' );
2092
2093
2060
};
2094
};
2061
$schema->storage->txn_rollback;
2095
$schema->storage->txn_rollback;
2062
2096
2063
- 

Return to bug 39452