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

(-)a/Koha/Patron.pm (+67 lines)
Lines 3703-3708 sub create_expiry_notice_parameters { Link Here
3703
    return $sending_params;
3703
    return $sending_params;
3704
}
3704
}
3705
3705
3706
=head3 identify_updated_extended_attributes
3707
3708
Compares an array of updated extended attributes with the stored values to identify changes
3709
3710
=cut
3711
3712
sub identify_updated_extended_attributes {
3713
    my ( $self, $entered_attributes ) = @_;
3714
3715
    my @patron_attributes = grep { $_->type->opac_editable ? $_ : () }
3716
        Koha::Patron::Attributes->search( { borrowernumber => $self->borrowernumber } )->as_list;
3717
3718
    my $patron_attribute_types;
3719
    foreach my $attr (@patron_attributes) {
3720
        $patron_attribute_types->{ $attr->code } += 1;
3721
    }
3722
3723
    my $passed_attribute_types;
3724
    foreach my $attr ( @{$entered_attributes} ) {
3725
        $passed_attribute_types->{ $attr->{code} } += 1;
3726
    }
3727
3728
    my @changed_attributes;
3729
3730
    # Loop through the current patron attributes
3731
    foreach my $attribute_type ( keys %{$patron_attribute_types} ) {
3732
        if ( ( $patron_attribute_types->{$attribute_type} // q{} ) ne
3733
            ( $passed_attribute_types->{$attribute_type} // q{} ) )
3734
        {
3735
            # count differs, overwrite all attributes for given type
3736
            foreach my $attr ( @{$entered_attributes} ) {
3737
                push @changed_attributes, $attr
3738
                    if $attr->{code} eq $attribute_type;
3739
            }
3740
        } else {
3741
3742
            # count matches, check values
3743
            my $changes = 0;
3744
            foreach my $attr ( grep { $_->code eq $attribute_type } @patron_attributes ) {
3745
                $changes = 1
3746
                    unless any { $_->{attribute} eq $attr->attribute } @{$entered_attributes};
3747
                last if $changes;
3748
            }
3749
3750
            if ($changes) {
3751
                foreach my $attr ( @{$entered_attributes} ) {
3752
                    push @changed_attributes, $attr
3753
                        if $attr->{code} eq $attribute_type;
3754
                }
3755
            }
3756
        }
3757
    }
3758
3759
    # Loop through passed attributes, looking for new ones
3760
    foreach my $attribute_type ( keys %{$passed_attribute_types} ) {
3761
        if ( !defined $patron_attribute_types->{$attribute_type} ) {
3762
3763
            # YAY, new stuff
3764
            foreach my $attr ( grep { $_->{code} eq $attribute_type } @{$entered_attributes} ) {
3765
                push @changed_attributes, $attr;
3766
            }
3767
        }
3768
    }
3769
3770
    return \@changed_attributes;
3771
}
3772
3706
=head2 Internal methods
3773
=head2 Internal methods
3707
3774
3708
=head3 _type
3775
=head3 _type
(-)a/Koha/REST/V1/Patrons/SelfRenewal.pm (-2 / +5 lines)
Lines 99-107 sub submit { Link Here
99
                            $changes_detected++;
99
                            $changes_detected++;
100
                        }
100
                        }
101
                    }
101
                    }
102
                    if ($changes_detected) {
102
                    my $updated_extended_attributes =
103
                        $patron->identify_updated_extended_attributes($extended_attributes);
104
                    if ( $changes_detected || scalar(@$updated_extended_attributes) ) {
103
                        $changed_fields->{changed_fields}      = join ',', keys %$changed_fields;
105
                        $changed_fields->{changed_fields}      = join ',', keys %$changed_fields;
104
                        $changed_fields->{extended_attributes} = to_json($extended_attributes) if $extended_attributes;
106
                        $changed_fields->{extended_attributes} = to_json($updated_extended_attributes)
107
                            if scalar(@$updated_extended_attributes);
105
                        $patron->request_modification($changed_fields);
108
                        $patron->request_modification($changed_fields);
106
                    }
109
                    }
107
                }
110
                }
(-)a/admin/categories.pl (-1 / +3 lines)
Lines 50-56 if ( $op eq 'add_form' ) { Link Here
50
    my $category = Koha::Patron::Categories->find($categorycode);
50
    my $category = Koha::Patron::Categories->find($categorycode);
51
    $template->param(
51
    $template->param(
52
        category                          => scalar $category,
52
        category                          => scalar $category,
53
        self_renewal_information_messages => parse_renewal_info_message( $category->self_renewal_information_message )
53
        self_renewal_information_messages => scalar $category
54
        ? parse_renewal_info_message( $category->self_renewal_information_message )
55
        : []
54
    );
56
    );
55
57
56
    if ( C4::Context->preference('EnhancedMessagingPreferences') ) {
58
    if ( C4::Context->preference('EnhancedMessagingPreferences') ) {
(-)a/opac/opac-memberentry.pl (-63 / +2 lines)
Lines 333-345 if ( $op eq 'cud-create' ) { Link Here
333
333
334
        $template->param( op => 'edit' );
334
        $template->param( op => 'edit' );
335
    } else {
335
    } else {
336
        my $patron = Koha::Patrons->find($borrowernumber);
336
337
337
        # If preferred name is not included but firstname is then set preferred_name to firstname
338
        # If preferred name is not included but firstname is then set preferred_name to firstname
338
        $borrower{preferred_name} = $borrower{firstname}
339
        $borrower{preferred_name} = $borrower{firstname}
339
            if defined $borrower{firstname} && !defined $borrower{preferred_name};
340
            if defined $borrower{firstname} && !defined $borrower{preferred_name};
340
        my %borrower_changes = DelUnchangedFields( $borrowernumber, %borrower );
341
        my %borrower_changes = DelUnchangedFields( $borrowernumber, %borrower );
341
        $borrower_changes{'changed_fields'} = join ',', keys %borrower_changes;
342
        $borrower_changes{'changed_fields'} = join ',', keys %borrower_changes;
342
        my $extended_attributes_changes = FilterUnchangedAttributes( $borrowernumber, $attributes );
343
        my $extended_attributes_changes = $patron->identify_updated_extended_attributes($attributes);
343
344
344
        if ( $borrower_changes{'changed_fields'} || scalar @{$extended_attributes_changes} > 0 ) {
345
        if ( $borrower_changes{'changed_fields'} || scalar @{$extended_attributes_changes} > 0 ) {
345
            ( $template, $borrowernumber, $cookie ) = get_template_and_user(
346
            ( $template, $borrowernumber, $cookie ) = get_template_and_user(
Lines 354-360 if ( $op eq 'cud-create' ) { Link Here
354
            $borrower_changes{borrowernumber}      = $borrowernumber;
355
            $borrower_changes{borrowernumber}      = $borrowernumber;
355
            $borrower_changes{extended_attributes} = to_json($extended_attributes_changes);
356
            $borrower_changes{extended_attributes} = to_json($extended_attributes_changes);
356
357
357
            my $patron = Koha::Patrons->find($borrowernumber);
358
            $patron->request_modification( \%borrower_changes );
358
            $patron->request_modification( \%borrower_changes );
359
            $template->param( borrower => $patron->unblessed );
359
            $template->param( borrower => $patron->unblessed );
360
        } else {
360
        } else {
Lines 628-694 sub DelEmptyFields { Link Here
628
    return %borrower;
628
    return %borrower;
629
}
629
}
630
630
631
sub FilterUnchangedAttributes {
632
    my ( $borrowernumber, $entered_attributes ) = @_;
633
634
    my @patron_attributes = grep { $_->type->opac_editable ? $_ : () }
635
        Koha::Patron::Attributes->search( { borrowernumber => $borrowernumber } )->as_list;
636
637
    my $patron_attribute_types;
638
    foreach my $attr (@patron_attributes) {
639
        $patron_attribute_types->{ $attr->code } += 1;
640
    }
641
642
    my $passed_attribute_types;
643
    foreach my $attr ( @{$entered_attributes} ) {
644
        $passed_attribute_types->{ $attr->{code} } += 1;
645
    }
646
647
    my @changed_attributes;
648
649
    # Loop through the current patron attributes
650
    foreach my $attribute_type ( keys %{$patron_attribute_types} ) {
651
        if ( ( $patron_attribute_types->{$attribute_type} // q{} ) ne
652
            ( $passed_attribute_types->{$attribute_type} // q{} ) )
653
        {
654
            # count differs, overwrite all attributes for given type
655
            foreach my $attr ( @{$entered_attributes} ) {
656
                push @changed_attributes, $attr
657
                    if $attr->{code} eq $attribute_type;
658
            }
659
        } else {
660
661
            # count matches, check values
662
            my $changes = 0;
663
            foreach my $attr ( grep { $_->code eq $attribute_type } @patron_attributes ) {
664
                $changes = 1
665
                    unless any { $_->{value} eq $attr->attribute } @{$entered_attributes};
666
                last if $changes;
667
            }
668
669
            if ($changes) {
670
                foreach my $attr ( @{$entered_attributes} ) {
671
                    push @changed_attributes, $attr
672
                        if $attr->{code} eq $attribute_type;
673
                }
674
            }
675
        }
676
    }
677
678
    # Loop through passed attributes, looking for new ones
679
    foreach my $attribute_type ( keys %{$passed_attribute_types} ) {
680
        if ( !defined $patron_attribute_types->{$attribute_type} ) {
681
682
            # YAY, new stuff
683
            foreach my $attr ( grep { $_->{code} eq $attribute_type } @{$entered_attributes} ) {
684
                push @changed_attributes, $attr;
685
            }
686
        }
687
    }
688
689
    return \@changed_attributes;
690
}
691
692
sub GeneratePatronAttributesForm {
631
sub GeneratePatronAttributesForm {
693
    my ( $borrowernumber, $entered_attributes ) = @_;
632
    my ( $borrowernumber, $entered_attributes ) = @_;
694
633
(-)a/t/db_dependent/Koha/Patron.t (-2 / +126 lines)
Lines 19-25 Link Here
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::More tests => 49;
22
use Test::More tests => 50;
23
use Test::NoWarnings;
23
use Test::NoWarnings;
24
use Test::Exception;
24
use Test::Exception;
25
use Test::Warn;
25
use Test::Warn;
Lines 3704-3706 subtest "create_expiry_notice_parameters" => sub { Link Here
3704
    is_deeply( $letter_params, $expected_return, 'Letter params generated correctly' );
3704
    is_deeply( $letter_params, $expected_return, 'Letter params generated correctly' );
3705
    $schema->storage->txn_rollback;
3705
    $schema->storage->txn_rollback;
3706
};
3706
};
3707
- 
3707
3708
subtest "identify_updated_extended_attributes" => sub {
3709
    plan tests => 2;
3710
3711
    $schema->storage->txn_begin;
3712
3713
    my $patron = $builder->build_object(
3714
        {
3715
            class => 'Koha::Patrons',
3716
        }
3717
    );
3718
3719
    my $unique_attribute_type = $builder->build_object(
3720
        {
3721
            class => 'Koha::Patron::Attribute::Types',
3722
            value => {
3723
                unique_id     => 1,
3724
                repeatable    => 0,
3725
                is_date       => 0,
3726
                opac_editable => 1
3727
            }
3728
        }
3729
    );
3730
    my $repeatable_attribute_type = $builder->build_object(
3731
        {
3732
            class => 'Koha::Patron::Attribute::Types',
3733
            value => {
3734
                unique_id     => 0,
3735
                repeatable    => 1,
3736
                is_date       => 0,
3737
                opac_editable => 1
3738
            }
3739
        }
3740
    );
3741
    my $normal_attribute_type = $builder->build_object(
3742
        {
3743
            class => 'Koha::Patron::Attribute::Types',
3744
            value => {
3745
                unique_id     => 0,
3746
                repeatable    => 0,
3747
                is_date       => 0,
3748
                opac_editable => 1
3749
            }
3750
        }
3751
    );
3752
3753
    my $attributes = [
3754
        {
3755
            attribute => 'my unique attribute 1',
3756
            code      => $unique_attribute_type->code(),
3757
        },
3758
        {
3759
            attribute => 'my repeatable attribute 1',
3760
            code      => $repeatable_attribute_type->code(),
3761
        },
3762
        {
3763
            attribute => 'my normal attribute 1',
3764
            code      => $normal_attribute_type->code(),
3765
        }
3766
    ];
3767
    $patron->extended_attributes($attributes);
3768
3769
    my $changed_attributes = [
3770
        {
3771
            attribute => 'this is new',
3772
            code      => $unique_attribute_type->code(),
3773
        },
3774
        {
3775
            attribute => 'my repeatable attribute 1',
3776
            code      => $repeatable_attribute_type->code(),
3777
        },
3778
        {
3779
            attribute => 'my normal attribute 1',
3780
            code      => $normal_attribute_type->code(),
3781
        }
3782
    ];
3783
3784
    my $updated_attributes = $patron->identify_updated_extended_attributes($changed_attributes);
3785
    is( scalar(@$updated_attributes), 1, "Only the first one was changed" );
3786
3787
    $attributes = [
3788
        {
3789
            attribute => 'my unique attribute 1',
3790
            code      => $unique_attribute_type->code(),
3791
        },
3792
        {
3793
            attribute => 'my repeatable attribute 1',
3794
            code      => $repeatable_attribute_type->code(),
3795
        },
3796
        {
3797
            attribute => 'my repeatable attribute 2',
3798
            code      => $repeatable_attribute_type->code(),
3799
        },
3800
        {
3801
            attribute => 'my normal attribute 1',
3802
            code      => $normal_attribute_type->code(),
3803
        }
3804
    ];
3805
3806
    $patron->extended_attributes($attributes);
3807
3808
    $changed_attributes = [
3809
        {
3810
            attribute => 'this is new',
3811
            code      => $unique_attribute_type->code(),
3812
        },
3813
        {
3814
            attribute => 'this repeatable one is also new',
3815
            code      => $repeatable_attribute_type->code(),
3816
        },
3817
        {
3818
            attribute => 'my repeatable attribute 2',
3819
            code      => $repeatable_attribute_type->code(),
3820
        },
3821
        {
3822
            attribute => 'my normal attribute 1',
3823
            code      => $normal_attribute_type->code(),
3824
        }
3825
    ];
3826
3827
    $updated_attributes = $patron->identify_updated_extended_attributes($changed_attributes);
3828
    is( scalar(@$updated_attributes), 3, "Two have now been updated, one of which is repeatable and has two values" );
3829
3830
    $schema->storage->txn_rollback;
3831
};

Return to bug 26355