From 1344894ab02f6bda656a40ee12274a845b1ae4a4 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Wed, 9 Oct 2013 10:36:44 -0400 Subject: [PATCH] Bug 6427 - Rewrite of the accounts system - WIP --- C4/Context.pm | 2 +- Koha/Accounts/CreditTypes.pm | 98 ++++++++++++++++ Koha/Accounts/DebitTypes.pm | 138 ++++++++++++++++++++++ Koha/DateUtils.pm | 7 +- Koha/Schema/Result/AccountCredit.pm | 134 +++++++++++++++++++++ Koha/Schema/Result/AccountDebit.pm | 200 ++++++++++++++++++++++++++++++++ Koha/Schema/Result/AccountOffset.pm | 110 +++++++++++++++++ Koha/Schema/Result/Borrower.pm | 78 ++++++++++++- Koha/Schema/Result/Issue.pm | 13 ++- Koha/Schema/Result/OldIssue.pm | 4 +- installer/data/mysql/updatedatabase.pl | 7 + t/db_dependent/Accounts.t | 188 +++++++++++++++++++++++++++++- 12 files changed, 968 insertions(+), 11 deletions(-) create mode 100644 Koha/Accounts/CreditTypes.pm create mode 100644 Koha/Accounts/DebitTypes.pm create mode 100644 Koha/Schema/Result/AccountCredit.pm create mode 100644 Koha/Schema/Result/AccountDebit.pm create mode 100644 Koha/Schema/Result/AccountOffset.pm diff --git a/C4/Context.pm b/C4/Context.pm index db09a86..adbf3b7 100644 --- a/C4/Context.pm +++ b/C4/Context.pm @@ -1037,7 +1037,7 @@ sub schema { my $self = shift; my $sth; - if ( defined( $context->{"schema"} ) && $context->{"schema"}->ping() ) { + if ( defined( $context->{"schema"} ) ) { return $context->{"schema"}; } diff --git a/Koha/Accounts/CreditTypes.pm b/Koha/Accounts/CreditTypes.pm new file mode 100644 index 0000000..c4d3bae --- /dev/null +++ b/Koha/Accounts/CreditTypes.pm @@ -0,0 +1,98 @@ +package Koha::Accounts::CreditTypes; + +# Copyright 2013 ByWater Solutions +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +=head1 NAME + +Koha::AccountsCreditTypes - Module representing the enumerated data types for account fees + +=head1 SYNOPSIS + +use Koha::Accounts::CreditTypes; + +my $type = Koha::Accounts::CreditTypes::Payment; + +=head1 DESCRIPTION + +The subroutines in this modules act as enumerated data types for the +different credit types in Koha ( i.e. payments, writeoffs, etc. ) + +=head1 FUNCTIONS + +=head2 IsValid + +This subroutine takes a given string and returns 1 if +the string matches one of the data types, and 0 if not. + +FIXME: Perhaps we should use Class::Inspector instead of hard +coding the subs? It seems like it would be a major trade off +of speed just so we don't update something in two separate places +in the same file. + +=cut + +sub IsValid { + my ($string) = @_; + + return ( $string eq Koha::Accounts::CreditTypes::Payment() + || $string eq Koha::Accounts::CreditTypes::WriteOff() + || $string eq Koha::Accounts::CreditTypes::Found() + || $string eq Koha::Accounts::CreditTypes::Forgiven() ); +} + +=head2 Payment + +=cut + +sub Payment { + return 'PAYMENT'; +} + +=head2 Writeoff + +=cut + +sub WriteOff { + return 'WRITEOFF'; +} + +=head2 Writeoff + +=cut + +sub Found { + return 'FOUND'; +} + +=head2 Forgiven + +=cut + +sub Forgiven { + return 'FORGIVEN'; +} + +1; + +=head1 AUTHOR + +Kyle M Hall + +=cut diff --git a/Koha/Accounts/DebitTypes.pm b/Koha/Accounts/DebitTypes.pm new file mode 100644 index 0000000..8ee5395 --- /dev/null +++ b/Koha/Accounts/DebitTypes.pm @@ -0,0 +1,138 @@ +package Koha::Accounts::DebitTypes; + +# Copyright 2013 ByWater Solutions +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +=head1 NAME + +Koha::Accounts::DebitTypes - Module representing an enumerated data type for account fees + +=head1 SYNOPSIS + +use Koha::Accounts::DebitTypes; + +my $type = Koha::Accounts::DebitTypes::Fine; + +=head1 DESCRIPTION + +The subroutines in this modules act as an enumerated data type +for debit types ( stored in account_debits.type ) in Koha. + +=head1 FUNCTIONS + +=head2 IsValid + +This subroutine takes a given string and returns 1 if +the string matches one of the data types, and 0 if not. + +=cut + +sub IsValid { + my ($string) = @_; + + my $is_valid = + ( $string eq Koha::Accounts::DebitTypes::Fine() + || $string eq Koha::Accounts::DebitTypes::AccountManagementFee() + || $string eq Koha::Accounts::DebitTypes::Sundry() + || $string eq Koha::Accounts::DebitTypes::Lost() + || $string eq Koha::Accounts::DebitTypes::NewCard() ); + + unless ($is_valid) { + $is_valid = + C4::Context->schema->resultset('AuthorisedValue') + ->count( { category => 'MANUAL_INV', authorised_value => $string } ); + } + + return $is_valid; +} + +=head2 Fine + +This data type represents a standard fine within Koha. + +A fine still accruing no longer needs to be differiated by type +from a fine done accuring. Instead, that differentication is made +by which table the fine exists in, account_fees_accruing vs account_fees_accrued. + +In addition, fines can be checked for correctness based on the issue_id +they have. A fine in account_fees_accruing should always have a matching +issue_id in the issues table. A fine done accruing will almost always have +a matching issue_id in the old_issues table. However, in the case of an overdue +item with fines that has been renewed, and becomes overdue again, you may have +a case where a given issue may have a matching fine in account_fees_accruing and +one or more matching fines in account_fees_accrued ( one for each for the first +checkout and one each for any subsequent renewals ) + +=cut + +sub Fine { + return 'FINE'; +} + +=head2 AccountManagementFee + +This fee type is usually reserved for payments for library cards, +in cases where a library must charge a patron for the ability to +check out items. + +=cut + +sub AccountManagementFee { + return 'ACCOUNT_MANAGEMENT_FEE'; +} + +=head2 Sundry + +This fee type is basically a 'misc' type, and should be used +when no other fee type is more appropriate. + +=cut + +sub Sundry { + return 'SUNDRY'; +} + +=head2 Lost + +This fee type is used when a library charges for lost items. + +=cut + +sub Lost { + return 'LOST'; +} + +=head2 NewCard + +This fee type is used when a library charges for replacement +library cards. + +=cut + +sub NewCard { + return 'NEW_CARD'; +} + +1; + +=head1 AUTHOR + +Kyle M Hall + +=cut diff --git a/Koha/DateUtils.pm b/Koha/DateUtils.pm index 714b171..c120417 100644 --- a/Koha/DateUtils.pm +++ b/Koha/DateUtils.pm @@ -21,13 +21,14 @@ use warnings; use 5.010; use DateTime; use DateTime::Format::DateParse; +use DateTime::Format::MySQL; use C4::Context; use base 'Exporter'; use version; our $VERSION = qv('1.0.0'); our @EXPORT = ( - qw( dt_from_string output_pref format_sqldatetime output_pref_due format_sqlduedatetime) + qw( dt_from_string output_pref format_sqldatetime output_pref_due format_sqlduedatetime get_timestamp ) ); =head1 DateUtils @@ -218,4 +219,8 @@ sub format_sqlduedatetime { return q{}; } +sub get_timestamp { + return DateTime::Format::MySQL->format_datetime( dt_from_string() ); +} + 1; diff --git a/Koha/Schema/Result/AccountCredit.pm b/Koha/Schema/Result/AccountCredit.pm new file mode 100644 index 0000000..bf8e076 --- /dev/null +++ b/Koha/Schema/Result/AccountCredit.pm @@ -0,0 +1,134 @@ +package Koha::Schema::Result::AccountCredit; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + + +=head1 NAME + +Koha::Schema::Result::AccountCredit + +=cut + +__PACKAGE__->table("account_credits"); + +=head1 ACCESSORS + +=head2 credit_id + + data_type: 'integer' + is_auto_increment: 1 + is_nullable: 0 + +=head2 borrowernumber + + data_type: 'integer' + is_foreign_key: 1 + is_nullable: 0 + +=head2 type + + data_type: 'varchar' + is_nullable: 0 + size: 255 + +=head2 amount_paid + + data_type: 'decimal' + is_nullable: 0 + size: [28,6] + +=head2 amount_remaining + + data_type: 'decimal' + is_nullable: 0 + size: [28,6] + +=head2 notes + + data_type: 'text' + is_nullable: 1 + +=head2 manager_id + + data_type: 'integer' + is_nullable: 1 + +=head2 created_on + + data_type: 'timestamp' + is_nullable: 1 + +=head2 updated_on + + data_type: 'timestamp' + is_nullable: 1 + +=cut + +__PACKAGE__->add_columns( + "credit_id", + { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, + "borrowernumber", + { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, + "type", + { data_type => "varchar", is_nullable => 0, size => 255 }, + "amount_paid", + { data_type => "decimal", is_nullable => 0, size => [28, 6] }, + "amount_remaining", + { data_type => "decimal", is_nullable => 0, size => [28, 6] }, + "notes", + { data_type => "text", is_nullable => 1 }, + "manager_id", + { data_type => "integer", is_nullable => 1 }, + "created_on", + { data_type => "timestamp", is_nullable => 1 }, + "updated_on", + { data_type => "timestamp", is_nullable => 1 }, +); +__PACKAGE__->set_primary_key("credit_id"); + +=head1 RELATIONS + +=head2 borrowernumber + +Type: belongs_to + +Related object: L + +=cut + +__PACKAGE__->belongs_to( + "borrowernumber", + "Koha::Schema::Result::Borrower", + { borrowernumber => "borrowernumber" }, + { on_delete => "CASCADE", on_update => "CASCADE" }, +); + +=head2 account_offsets + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "account_offsets", + "Koha::Schema::Result::AccountOffset", + { "foreign.credit_id" => "self.credit_id" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + + +# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-10-09 10:37:23 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:uvt4OuaJxv4jk08zJsKouw + + +# You can replace this text with custom content, and it will be preserved on regeneration +1; diff --git a/Koha/Schema/Result/AccountDebit.pm b/Koha/Schema/Result/AccountDebit.pm new file mode 100644 index 0000000..008c626 --- /dev/null +++ b/Koha/Schema/Result/AccountDebit.pm @@ -0,0 +1,200 @@ +package Koha::Schema::Result::AccountDebit; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + + +=head1 NAME + +Koha::Schema::Result::AccountDebit + +=cut + +__PACKAGE__->table("account_debits"); + +=head1 ACCESSORS + +=head2 debit_id + + data_type: 'integer' + is_auto_increment: 1 + is_nullable: 0 + +=head2 borrowernumber + + data_type: 'integer' + default_value: 0 + is_foreign_key: 1 + is_nullable: 0 + +=head2 itemnumber + + data_type: 'integer' + is_nullable: 1 + +=head2 issue_id + + data_type: 'integer' + is_nullable: 1 + +=head2 type + + data_type: 'varchar' + is_nullable: 0 + size: 255 + +=head2 accruing + + data_type: 'tinyint' + default_value: 0 + is_nullable: 0 + +=head2 amount_original + + data_type: 'decimal' + is_nullable: 1 + size: [28,6] + +=head2 amount_outstanding + + data_type: 'decimal' + is_nullable: 1 + size: [28,6] + +=head2 amount_last_increment + + data_type: 'decimal' + is_nullable: 1 + size: [28,6] + +=head2 description + + data_type: 'mediumtext' + is_nullable: 1 + +=head2 notes + + data_type: 'text' + is_nullable: 1 + +=head2 dispute + + data_type: 'mediumtext' + is_nullable: 1 + +=head2 notify_id + + data_type: 'integer' + default_value: 0 + is_nullable: 0 + +=head2 notify_level + + data_type: 'integer' + default_value: 0 + is_nullable: 0 + +=head2 manager_id + + data_type: 'integer' + is_nullable: 1 + +=head2 created_on + + data_type: 'timestamp' + is_nullable: 1 + +=head2 updated_on + + data_type: 'timestamp' + is_nullable: 1 + +=cut + +__PACKAGE__->add_columns( + "debit_id", + { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, + "borrowernumber", + { + data_type => "integer", + default_value => 0, + is_foreign_key => 1, + is_nullable => 0, + }, + "itemnumber", + { data_type => "integer", is_nullable => 1 }, + "issue_id", + { data_type => "integer", is_nullable => 1 }, + "type", + { data_type => "varchar", is_nullable => 0, size => 255 }, + "accruing", + { data_type => "tinyint", default_value => 0, is_nullable => 0 }, + "amount_original", + { data_type => "decimal", is_nullable => 1, size => [28, 6] }, + "amount_outstanding", + { data_type => "decimal", is_nullable => 1, size => [28, 6] }, + "amount_last_increment", + { data_type => "decimal", is_nullable => 1, size => [28, 6] }, + "description", + { data_type => "mediumtext", is_nullable => 1 }, + "notes", + { data_type => "text", is_nullable => 1 }, + "dispute", + { data_type => "mediumtext", is_nullable => 1 }, + "notify_id", + { data_type => "integer", default_value => 0, is_nullable => 0 }, + "notify_level", + { data_type => "integer", default_value => 0, is_nullable => 0 }, + "manager_id", + { data_type => "integer", is_nullable => 1 }, + "created_on", + { data_type => "timestamp", is_nullable => 1 }, + "updated_on", + { data_type => "timestamp", is_nullable => 1 }, +); +__PACKAGE__->set_primary_key("debit_id"); + +=head1 RELATIONS + +=head2 borrowernumber + +Type: belongs_to + +Related object: L + +=cut + +__PACKAGE__->belongs_to( + "borrowernumber", + "Koha::Schema::Result::Borrower", + { borrowernumber => "borrowernumber" }, + { on_delete => "CASCADE", on_update => "CASCADE" }, +); + +=head2 account_offsets + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "account_offsets", + "Koha::Schema::Result::AccountOffset", + { "foreign.debit_id" => "self.debit_id" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + + +# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-10-09 10:37:23 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LuHGHKmf3tPEWsTqE4VoMQ + + +# You can replace this text with custom content, and it will be preserved on regeneration +1; diff --git a/Koha/Schema/Result/AccountOffset.pm b/Koha/Schema/Result/AccountOffset.pm new file mode 100644 index 0000000..f592eaf --- /dev/null +++ b/Koha/Schema/Result/AccountOffset.pm @@ -0,0 +1,110 @@ +package Koha::Schema::Result::AccountOffset; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + + +=head1 NAME + +Koha::Schema::Result::AccountOffset + +=cut + +__PACKAGE__->table("account_offsets"); + +=head1 ACCESSORS + +=head2 offset_id + + data_type: 'integer' + is_auto_increment: 1 + is_nullable: 0 + +=head2 debit_id + + data_type: 'integer' + is_foreign_key: 1 + is_nullable: 1 + +=head2 credit_id + + data_type: 'integer' + is_foreign_key: 1 + is_nullable: 1 + +=head2 amount + + data_type: 'decimal' + is_nullable: 0 + size: [28,6] + +=head2 created_on + + data_type: 'timestamp' + default_value: current_timestamp + is_nullable: 0 + +=cut + +__PACKAGE__->add_columns( + "offset_id", + { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, + "debit_id", + { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, + "credit_id", + { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, + "amount", + { data_type => "decimal", is_nullable => 0, size => [28, 6] }, + "created_on", + { + data_type => "timestamp", + default_value => \"current_timestamp", + is_nullable => 0, + }, +); +__PACKAGE__->set_primary_key("offset_id"); + +=head1 RELATIONS + +=head2 credit + +Type: belongs_to + +Related object: L + +=cut + +__PACKAGE__->belongs_to( + "credit", + "Koha::Schema::Result::AccountCredit", + { credit_id => "credit_id" }, + { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" }, +); + +=head2 debit + +Type: belongs_to + +Related object: L + +=cut + +__PACKAGE__->belongs_to( + "debit", + "Koha::Schema::Result::AccountDebit", + { debit_id => "debit_id" }, + { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" }, +); + + +# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-09-10 14:57:34 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:O3cL8IVdqGD6stE30ohBxA + + +# You can replace this text with custom content, and it will be preserved on regeneration +1; diff --git a/Koha/Schema/Result/Borrower.pm b/Koha/Schema/Result/Borrower.pm index be6e849..d31cd50 100644 --- a/Koha/Schema/Result/Borrower.pm +++ b/Koha/Schema/Result/Borrower.pm @@ -389,6 +389,13 @@ __PACKAGE__->table("borrowers"); default_value: 1 is_nullable: 0 +=head2 account_balance + + data_type: 'decimal' + default_value: 0.000000 + is_nullable: 0 + size: [28,6] + =cut __PACKAGE__->add_columns( @@ -538,12 +545,49 @@ __PACKAGE__->add_columns( { data_type => "varchar", is_nullable => 1, size => 50 }, "privacy", { data_type => "integer", default_value => 1, is_nullable => 0 }, + "account_balance", + { + data_type => "decimal", + default_value => "0.000000", + is_nullable => 0, + size => [28, 6], + }, ); __PACKAGE__->set_primary_key("borrowernumber"); __PACKAGE__->add_unique_constraint("cardnumber", ["cardnumber"]); =head1 RELATIONS +=head2 account_credits + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "account_credits", + "Koha::Schema::Result::AccountCredit", + { "foreign.borrowernumber" => "self.borrowernumber" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + +=head2 account_debits + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "account_debits", + "Koha::Schema::Result::AccountDebit", + { "foreign.borrowernumber" => "self.borrowernumber" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + =head2 accountlines Type: has_many @@ -604,6 +648,21 @@ __PACKAGE__->has_many( { cascade_copy => 0, cascade_delete => 0 }, ); +=head2 borrower_files + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "borrower_files", + "Koha::Schema::Result::BorrowerFile", + { "foreign.borrowernumber" => "self.borrowernumber" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + =head2 borrower_message_preferences Type: has_many @@ -649,6 +708,21 @@ __PACKAGE__->belongs_to( { on_delete => "CASCADE", on_update => "CASCADE" }, ); +=head2 course_instructors + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "course_instructors", + "Koha::Schema::Result::CourseInstructor", + { "foreign.borrowernumber" => "self.borrowernumber" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + =head2 creator_batches Type: has_many @@ -920,8 +994,8 @@ __PACKAGE__->has_many( ); -# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-04-22 08:57:05 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:x1GvKQJu/IfGrdz4QG1AfQ +# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-09-10 14:57:34 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:0RVIm6TnhPVC3zIvXAxZKg # You can replace this text with custom content, and it will be preserved on regeneration diff --git a/Koha/Schema/Result/Issue.pm b/Koha/Schema/Result/Issue.pm index 981d2f1..8d4ac5f 100644 --- a/Koha/Schema/Result/Issue.pm +++ b/Koha/Schema/Result/Issue.pm @@ -19,6 +19,12 @@ __PACKAGE__->table("issues"); =head1 ACCESSORS +=head2 issue_id + + data_type: 'integer' + is_auto_increment: 1 + is_nullable: 0 + =head2 borrowernumber data_type: 'integer' @@ -83,6 +89,8 @@ __PACKAGE__->table("issues"); =cut __PACKAGE__->add_columns( + "issue_id", + { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, "borrowernumber", { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, "itemnumber", @@ -110,6 +118,7 @@ __PACKAGE__->add_columns( "issuedate", { data_type => "datetime", is_nullable => 1 }, ); +__PACKAGE__->set_primary_key("issue_id"); =head1 RELATIONS @@ -144,8 +153,8 @@ __PACKAGE__->belongs_to( ); -# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-04-22 08:57:05 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:yGeX5Tx60Cj3S9MUj1s++g +# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-09-10 14:57:34 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:qcAHoiJvPlCgR8xNEskeMg # You can replace this text with custom content, and it will be preserved on regeneration diff --git a/Koha/Schema/Result/OldIssue.pm b/Koha/Schema/Result/OldIssue.pm index 40c1bbc..2cb6eb2 100644 --- a/Koha/Schema/Result/OldIssue.pm +++ b/Koha/Schema/Result/OldIssue.pm @@ -144,8 +144,8 @@ __PACKAGE__->belongs_to( ); -# Created by DBIx::Class::Schema::Loader v0.07000 @ 2012-09-02 08:44:15 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:OmCAF2QYzR59eHr1w51seA +# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-09-10 14:57:34 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:4bnXphmCgmRkFQRHxhWNGw # You can replace this text with custom content, and it will be preserved on regeneration diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index ddcc455..2b0c396 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -7104,6 +7104,13 @@ if ( CheckVersion($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.11.00.XXX"; +if ( CheckVersion($DBversion) ) { + $dbh->do("ALTER TABLE `issues` ADD `issue_id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST"); + print "Upgrade to $DBversion done (WIP: Accounts rewrite)\n"; + SetVersion ($DBversion); +} + =head1 FUNCTIONS =head2 TableExists($table) diff --git a/t/db_dependent/Accounts.t b/t/db_dependent/Accounts.t index 1c2dd5a..3120780 100644 --- a/t/db_dependent/Accounts.t +++ b/t/db_dependent/Accounts.t @@ -1,16 +1,198 @@ #!/usr/bin/perl # -# This Koha test module is a stub! +# This Koha test module is a stub! # Add more tests here!!! use strict; use warnings; -use Test::More tests => 1; +use Test::More tests => 18; + +use C4::Context; BEGIN { - use_ok('C4::Accounts'); + use_ok('Koha::Accounts'); + use_ok('Koha::Accounts::DebitTypes'); + use_ok('Koha::Accounts::CreditTypes'); } +## Intial Setup ## +my $borrower = C4::Context->schema->resultset('Borrower')->create( + { + surname => 'Test', + categorycode => 'S', + branchcode => 'MPL', + account_balance => 0, + } +); + +my $biblio = + C4::Context->schema->resultset('Biblio') + ->create( { title => "Test Record" } ); +my $biblioitem = + C4::Context->schema->resultset('Biblioitem') + ->create( { biblionumber => $biblio->biblionumber() } ); +my $item = C4::Context->schema->resultset('Item')->create( + { + biblionumber => $biblio->biblionumber(), + biblioitemnumber => $biblioitem->biblioitemnumber(), + replacementprice => 25.00, + barcode => q{TEST_ITEM_BARCODE} + } +); + +my $issue = C4::Context->schema->resultset('Issue')->create( + { + borrowernumber => $borrower->borrowernumber(), + itemnumber => $item->itemnumber(), + } +); +## END initial setup + +ok( Koha::Accounts::DebitTypes::Fine eq 'FINE', 'Test DebitTypes::Fine' ); +ok( Koha::Accounts::DebitTypes::Lost eq 'LOST', 'Test DebitTypes::Lost' ); +ok( + Koha::Accounts::DebitTypes::IsValid('FINE'), + 'Test DebitTypes::IsValid with valid debit type' +); +ok( + !Koha::Accounts::DebitTypes::IsValid('Not A Valid Fee Type'), + 'Test DebitTypes::IsValid with an invalid debit type' +); +my $authorised_value = + C4::Context->schema->resultset('AuthorisedValue')->create( + { + category => 'MANUAL_INV', + authorised_value => 'TEST', + lib => 'Test', + } + ); +ok( Koha::Accounts::DebitTypes::IsValid('TEST'), + 'Test DebitTypes::IsValid with valid authorised value debit type' ); +$authorised_value->delete(); + +my $debit = AddDebit( + { + borrower => $borrower, + amount => 5.00, + type => Koha::Accounts::DebitTypes::Fine, + branchcode => 'MPL', + } +); +ok( $debit, "AddDebit returned a valid debit id " . $debit->id() ); + +ok( + $borrower->account_balance() == 5.00, + "Borrower's account balance updated correctly" +); + +my $debit2 = AddDebit( + { + borrower => $borrower, + amount => 7.00, + type => Koha::Accounts::DebitTypes::Fine, + branchcode => 'MPL', + } +); + +my $credit = AddCredit( + { + borrower => $borrower, + type => Koha::Accounts::CreditTypes::Payment, + amount => 9.00, + branchcode => 'MPL', + } +); + +RecalculateAccountBalance( { borrower => $borrower } ); +ok( + sprintf( "%.2f", $borrower->account_balance() ) eq "3.00", + "RecalculateAccountBalance updated balance correctly." +); + +C4::Context->schema->resultset('AccountCredit')->create( + { + borrowernumber => $borrower->borrowernumber(), + type => Koha::Accounts::CreditTypes::Payment, + amount_paid => 3.00, + amount_remaining => 3.00, + } +); +NormalizeBalances( { borrower => $borrower } ); +ok( + $borrower->account_balance() == 0.00, + "NormalizeBalances updated balance correctly." +); + +# Adding advance credit with no balance due +$credit = AddCredit( + { + borrower => $borrower, + type => Koha::Accounts::CreditTypes::Payment, + amount => 9.00, + branchcode => 'MPL', + } +); +ok( + $borrower->account_balance() == -9, +'Adding a $9 credit for borrower with 0 balance results in a -9 dollar account balance' +); + +my $debit3 = AddDebit( + { + borrower => $borrower, + amount => 5.00, + type => Koha::Accounts::DebitTypes::Fine, + branchcode => 'MPL', + } +); +ok( + $borrower->account_balance() == -4, +'Adding a $5 debit when the balance is negative results in the debit being automatically paid, resulting in a balance of -4' +); + +my $debit4 = AddDebit( + { + borrower => $borrower, + amount => 6.00, + type => Koha::Accounts::DebitTypes::Fine, + branchcode => 'MPL', + } +); +ok( + $borrower->account_balance() == 2, +'Adding another debit ( 6.00 ) more than the negative account balance results in a partial credit and a balance due of 2.00' +); +$credit = AddCredit( + { + borrower => $borrower, + type => Koha::Accounts::CreditTypes::WriteOff, + amount => 2.00, + branchcode => 'MPL', + debit_id => $debit4->debit_id(), + } +); +ok( $borrower->account_balance() == 0, + 'WriteOff of remaining 2.00 balance succeeds' ); + +my $debit5 = DebitLostItem( + { + borrower => $borrower, + issue => $issue, + } +); +ok( $borrower->account_balance() == 25, + 'DebitLostItem adds debit for replacement price of item' ); +my $lost_credit = + CreditLostItem( { borrower => $borrower, account_debit => $debit5 } ); +ok( + $borrower->account_balance() == 0, + 'CreditLostItem adds credit for same about as the debit for the lost tiem' +); +## Post test cleanup ## +$issue->delete(); +$item->delete(); +$biblio->delete(); +$borrower->delete(); -- 1.7.2.5