Bug 24255: Add summation methods to Koha::Account::Lines
authorMartin Renvoize <martin.renvoize@ptfs-europe.com>
Tue, 17 Dec 2019 15:58:21 +0000 (15:58 +0000)
committerMartin Renvoize <martin.renvoize@ptfs-europe.com>
Thu, 9 Jan 2020 16:33:46 +0000 (16:33 +0000)
This patch adds a number of summation methods to Koha::Account::Lines
giving quick access to overall total, total credits and total debits.

Test plan
1) Run the included tests

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Koha/Account/Lines.pm
t/db_dependent/Koha/Account/Lines.t

index 75225fc..41c6216 100644 (file)
@@ -43,13 +43,14 @@ empty it returns 0.
 =cut
 
 sub total_outstanding {
-    my ( $self ) = @_;
+    my ($self) = @_;
 
+    my $me = $self->_resultset()->current_source_alias . ".";
     my $lines = $self->search(
         {},
         {
-            select => [ { sum => 'amountoutstanding' } ],
-            as => ['total_amountoutstanding'],
+            select => [ { sum => $me.'amountoutstanding' } ],
+            as     => ['total_amountoutstanding'],
         }
     );
 
@@ -58,6 +59,87 @@ sub total_outstanding {
       : 0;
 }
 
+=head3 total
+
+    my $lines = Koha::Account::Lines->search({ ...  });
+    my $total = $lines->total;
+
+Returns the sum of the amounts of the resultset. If the resultset is
+empty it returns 0.
+
+=cut
+
+sub total {
+    my ( $self, $conditions ) = @_;
+
+    $conditions //= {};
+    my $me = $self->_resultset()->current_source_alias . ".";
+    my $lines = $self->search(
+        $conditions,
+        {
+            select => [ { sum => $me.'amount' } ],
+            as     => ['total']
+        }
+    );
+    return $lines->count ? $lines->next->get_column('total') + 0 : 0;
+}
+
+=head3 credits_total
+
+    my $lines = Koha::Account::Lines->search({ ...  });
+    my $credits_total = $lines->credits_total;
+
+Returns the sum of the amounts of the resultset. If the resultset is
+empty it returns 0.
+
+=cut
+
+sub credits_total {
+    my ( $self, $conditions ) = @_;
+
+    my $me = $self->_resultset()->current_source_alias . ".";
+    my $local_conditions = { $me.'amount' => { '<' => 0 } };
+    $conditions //= {};
+    my $merged_conditions = { %{$conditions}, %{$local_conditions} };
+
+    my $lines = $self->search(
+        $merged_conditions,
+        {
+            select => [ { sum => $me.'amount' } ],
+            as     => ['total']
+        }
+    );
+    return $lines->count ? $lines->next->get_column('total') + 0 : 0;
+}
+
+=head3 debits_total
+
+    my $lines = Koha::Account::Lines->search({ ...  });
+    my $debits_total = $lines->debits_total;
+
+Returns the sum of the amounts of the resultset. If the resultset is
+empty it returns 0.
+
+=cut
+
+sub debits_total {
+    my ( $self, $conditions ) = @_;
+
+    my $me = $self->_resultset()->current_source_alias . ".";
+    my $local_conditions = { $me.'amount' => { '>' => 0 } };
+    $conditions //= {};
+    my $merged_conditions = { %{$conditions}, %{$local_conditions} };
+
+    my $lines = $self->search(
+        $merged_conditions,
+        {
+            select => [ { sum => $me.'amount' } ],
+            as     => ['total']
+        }
+    );
+    return $lines->count ? $lines->next->get_column('total') + 0 : 0;
+}
+
 =head2 Internal methods
 
 =head3 _type
index 6e99bb4..f060135 100755 (executable)
@@ -19,7 +19,7 @@
 
 use Modern::Perl;
 
-use Test::More tests => 11;
+use Test::More tests => 14;
 use Test::Exception;
 
 use C4::Circulation qw/AddIssue AddReturn/;
@@ -178,6 +178,234 @@ subtest 'total_outstanding() tests' => sub {
     $schema->storage->txn_rollback;
 };
 
+subtest 'total() tests' => sub {
+
+    plan tests => 5;
+
+    $schema->storage->txn_begin;
+
+    my $patron  = $builder->build_object({ class => 'Koha::Patrons' });
+
+    my $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->total, 0, 'total returns 0 if no lines (undef case)' );
+
+    my $debit_1 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => 10,
+            amountoutstanding => 10,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    my $debit_2 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code       => "OVERDUE",
+            status            => "RETURNED",
+            amount            => 10,
+            amountoutstanding => 10,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->total, 20, 'total sums correctly' );
+
+    my $credit_1 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => -10,
+            amountoutstanding => -10,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->total, 10, 'total sums correctly' );
+
+    my $credit_2 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => -10,
+            amountoutstanding => -10,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->total, 0, 'total sums correctly' );
+
+    my $credit_3 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => -100,
+            amountoutstanding => -100,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->total, -100, 'total sums correctly' );
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'credits_total() tests' => sub {
+
+    plan tests => 5;
+
+    $schema->storage->txn_begin;
+
+    my $patron  = $builder->build_object({ class => 'Koha::Patrons' });
+
+    my $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->credits_total, 0, 'credits_total returns 0 if no lines (undef case)' );
+
+    my $debit_1 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => 10,
+            amountoutstanding => 10,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    my $debit_2 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => 10,
+            amountoutstanding => 10,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->credits_total, 0, 'credits_total sums correctly' );
+
+    my $credit_1 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => -10,
+            amountoutstanding => -10,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->credits_total, -10, 'credits_total sums correctly' );
+
+    my $credit_2 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => -10,
+            amountoutstanding => -10,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->credits_total, -20, 'credits_total sums correctly' );
+
+    my $credit_3 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => -100,
+            amountoutstanding => -100,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->credits_total, -120, 'credits_total sums correctly' );
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'debits_total() tests' => sub {
+
+    plan tests => 5;
+
+    $schema->storage->txn_begin;
+
+    my $patron  = $builder->build_object({ class => 'Koha::Patrons' });
+
+    my $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->debits_total, 0, 'debits_total returns 0 if no lines (undef case)' );
+
+    my $debit_1 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => 10,
+            amountoutstanding => 0,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    my $debit_2 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => 10,
+            amountoutstanding => 0,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->debits_total, 20, 'debits_total sums correctly' );
+
+    my $credit_1 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => -10,
+            amountoutstanding => 0,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->debits_total, 20, 'debits_total sums correctly' );
+
+    my $credit_2 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => -10,
+            amountoutstanding => 0,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->debits_total, 20, 'debits_total sums correctly' );
+
+    my $credit_3 = Koha::Account::Line->new(
+        {   borrowernumber    => $patron->id,
+            debit_type_code   => "OVERDUE",
+            status            => "RETURNED",
+            amount            => -100,
+            amountoutstanding => 0,
+            interface         => 'commandline',
+        }
+    )->store;
+
+    $lines = Koha::Account::Lines->search({ borrowernumber => $patron->id });
+    is( $lines->debits_total, 20, 'debits_total sums correctly' );
+
+    $schema->storage->txn_rollback;
+};
+
 subtest 'is_credit() and is_debit() tests' => sub {
 
     plan tests => 4;