From 23b5c810efb0975fb4a06142674aa27eabd5e689 Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Tue, 25 Feb 2014 05:31:27 +0000 Subject: Added perm relating to refund reasons --- FS/FS/AccessRight.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index 4b165eb3f..4d9cff99e 100644 --- a/FS/FS/AccessRight.pm +++ b/FS/FS/AccessRight.pm @@ -230,6 +230,7 @@ tie my %rights, 'Tie::IxHash', 'Refund Echeck payment', 'Delete refund', #NEW 'Add on-the-fly credit reason', #NEW + 'Add on-the-fly refund reason', #NEW ], ### -- cgit v1.2.1 From 128443531fae5fced8a8d2adbcaf6cb945218e3d Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Tue, 25 Feb 2014 05:35:42 +0000 Subject: Added reasonnum col, allowed reason to be null, implemented key constraint with reasonnum col --- FS/FS/Schema.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index bf516b28f..ec4a1b3e2 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2847,7 +2847,8 @@ sub tables_hashref { 'currency', 'char', 'NULL', 3, '', '', 'otaker', 'varchar', 'NULL', 32, '', '', 'usernum', 'int', 'NULL', '', '', '', - 'reason', 'varchar', '', $char_d, '', '', + 'reason', 'varchar', 'NULL', $char_d, '', '', + 'reasonnum', 'int', 'NULL', '', '', '', 'payby', 'char', '', 4, '', '', # CARD/BILL/COMP, should # be index into payby # table eventually @@ -2871,6 +2872,9 @@ sub tables_hashref { { columns => [ 'usernum' ], table => 'access_user', }, + { columns => [ 'reasonnum' ], + table => 'reason', + }, { columns => [ 'gatewaynum' ], table => 'payment_gateway', }, -- cgit v1.2.1 From 79981f908752492b00cb4bdce3dceb0636fb81dd Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Tue, 25 Feb 2014 05:37:31 +0000 Subject: added reason method, allowed reasonnum to be passed in, allowed reason to be null in check method, modified _upgrade_data to migrate reason col in cust_refund table to reasonnum col --- FS/FS/cust_refund.pm | 144 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 5 deletions(-) diff --git a/FS/FS/cust_refund.pm b/FS/FS/cust_refund.pm index d29db5cfa..097ed2df3 100644 --- a/FS/FS/cust_refund.pm +++ b/FS/FS/cust_refund.pm @@ -3,14 +3,21 @@ package FS::cust_refund; use strict; use base qw( FS::otaker_Mixin FS::payinfo_transaction_Mixin FS::cust_main_Mixin FS::Record ); -use vars qw( @encrypted_fields ); +use vars qw( @encrypted_fields $me $DEBUG $ignore_empty_reasonnum ); use Business::CreditCard; -use FS::Record qw( qsearch qsearchs dbh ); +use FS::Record qw( qsearch qsearchs dbh dbdef ); use FS::CurrentUser; use FS::cust_credit; use FS::cust_credit_refund; use FS::cust_pay_refund; use FS::cust_main; +use FS::reason_type; +use FS::reason; + +$me = '[ FS::cust_refund ]'; +$DEBUG = 0; + +$ignore_empty_reasonnum = 0; @encrypted_fields = ('payinfo'); sub nohistory_fields { ('payinfo'); } @@ -56,7 +63,11 @@ Amount of the refund =item reason -Reason for the refund +Text stating the reason for the refund ( deprecated ) + +=item reasonnum + +Reason (see L) =item _date @@ -119,7 +130,7 @@ amount of the refund will be created. In both cases, custnum is optional. =cut sub insert { - my $self = shift; + my ($self, %options) = @_; local $SIG{HUP} = 'IGNORE'; local $SIG{INT} = 'IGNORE'; @@ -132,6 +143,20 @@ sub insert { local $FS::UID::AutoCommit = 0; my $dbh = dbh; + unless ($self->reasonnum) { + my $result = $self->reason( $self->getfield('reason'), + exists($options{ 'reason_type' }) + ? ('reason_type' => $options{ 'reason_type' }) + : (), + ); + unless($result) { + $dbh->rollback if $oldAutoCommit; + return "failed to set reason for $me"; #: ". $dbh->errstr; + } + } + + $self->setfield('reason', ''); + if ( $self->crednum ) { my $cust_credit = qsearchs('cust_credit', { 'crednum' => $self->crednum } ) or do { @@ -274,13 +299,17 @@ sub check { || $self->ut_numbern('custnum') || $self->ut_money('refund') || $self->ut_alphan('otaker') - || $self->ut_text('reason') + || $self->ut_textn('reason') || $self->ut_numbern('_date') || $self->ut_textn('paybatch') || $self->ut_enum('closed', [ '', 'Y' ]) ; return $error if $error; + my $method = $ignore_empty_reasonnum ? 'ut_foreign_keyn' : 'ut_foreign_key'; + $error = $self->$method('reasonnum', 'reason', 'reasonnum'); + return $error if $error; + return "refund must be > 0 " if $self->refund <= 0; $self->_date(time) unless $self->_date; @@ -377,9 +406,114 @@ sub unapplied_sql { } +=item reason + +Returns the text of the associated reason (see L) for this credit. + +=cut + +sub reason { + my ($self, $value, %options) = @_; + my $dbh = dbh; + my $reason; + my $typenum = $options{'reason_type'}; + + my $oldAutoCommit = $FS::UID::AutoCommit; # this should already be in + local $FS::UID::AutoCommit = 0; # a transaction if it matters + + if ( defined( $value ) ) { + my $hashref = { 'reason' => $value }; + $hashref->{'reason_type'} = $typenum if $typenum; + my $addl_from = "LEFT JOIN reason_type ON ( reason_type = typenum ) "; + my $extra_sql = " AND reason_type.class='F'"; + + $reason = qsearchs( { 'table' => 'reason', + 'hashref' => $hashref, + 'addl_from' => $addl_from, + 'extra_sql' => $extra_sql, + } ); + + if (!$reason && $typenum) { + $reason = new FS::reason( { 'reason_type' => $typenum, + 'reason' => $value, + 'disabled' => 'Y', + } ); + my $error = $reason->insert; + if ( $error ) { + warn "error inserting reason: $error\n"; + $reason = undef; + } + } + + $self->reasonnum($reason ? $reason->reasonnum : '') ; + warn "$me reason used in set mode with non-existant reason -- clearing" + unless $reason; + } + $reason = qsearchs( 'reason', { 'reasonnum' => $self->reasonnum } ); + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ( $reason ? $reason->reason : '' ). + ( $self->addlinfo ? ' '.$self->addlinfo : '' ); +} + # Used by FS::Upgrade to migrate to a new database. sub _upgrade_data { # class method my ($class, %opts) = @_; + + warn "$me upgrading $class\n" if $DEBUG; + + if (defined dbdef->table($class->table)->column('reason')) { + + warn "$me Checking for unmigrated reasons\n" if $DEBUG; + + my @cust_refunds = qsearch({ 'table' => $class->table, + 'hashref' => {}, + 'extra_sql' => 'WHERE reason IS NOT NULL', + }); + + if (scalar(grep { $_->getfield('reason') =~ /\S/ } @cust_refunds)) { + warn "$me Found unmigrated reasons\n" if $DEBUG; + my $hashref = { 'class' => 'F', 'type' => 'Legacy' }; + my $reason_type = qsearchs( 'reason_type', $hashref ); + unless ($reason_type) { + $reason_type = new FS::reason_type( $hashref ); + my $error = $reason_type->insert(); + die "$class had error inserting FS::reason_type into database: $error\n" + if $error; + } + + $hashref = { 'reason_type' => $reason_type->typenum, + 'reason' => '(none)' + }; + my $noreason = qsearchs( 'reason', $hashref ); + unless ($noreason) { + $hashref->{'disabled'} = 'Y'; + $noreason = new FS::reason( $hashref ); + my $error = $noreason->insert(); + die "can't insert legacy reason '(none)' into database: $error\n" + if $error; + } + + foreach my $cust_refund ( @cust_refunds ) { + my $reason = $cust_refund->getfield('reason'); + warn "Contemplating reason $reason\n" if $DEBUG > 1; + if ($reason =~ /\S/) { + $cust_refund->reason($reason, 'reason_type' => $reason_type->typenum) + or die "can't insert legacy reason $reason into database\n"; + }else{ + $cust_refund->reasonnum($noreason->reasonnum); + } + + $cust_refund->setfield('reason', ''); + my $error = $cust_refund->replace; + + warn "*** WARNING: error replacing reason in $class ". + $cust_refund->refundnum. ": $error ***\n" + if $error; + } + } + } $class->_upgrade_otaker(%opts); } -- cgit v1.2.1 From 73e20a91b38b27ad5be79306ba25bdfb5a1252e1 Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Tue, 25 Feb 2014 05:39:29 +0000 Subject: added activate, renewal, term change, and refund reason_type classes --- FS/FS/reason_type.pm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/FS/FS/reason_type.pm b/FS/FS/reason_type.pm index a603809e2..d66f7b572 100644 --- a/FS/FS/reason_type.pm +++ b/FS/FS/reason_type.pm @@ -10,12 +10,20 @@ our %class_name = ( 'C' => 'cancel', 'R' => 'credit', 'S' => 'suspend', + 'U' => 'activate', #uncancel/unsuspend + 'W' => 'renewal', + 'T' => 'term change', + 'F' => 'refund', ); our %class_purpose = ( 'C' => 'explain why a customer package was cancelled', 'R' => 'explain why a customer was credited', 'S' => 'explain why a customer package was suspended', + 'U' => 'explain why a customer package was unsuspended/uncanceled/activated', + 'W' => 'explain why a customer package was renewed', + 'T' => 'explain why a customer package term was changed', + 'F' => 'explain why a customer was refunded', ); =head1 NAME -- cgit v1.2.1 From daa3524d4f512f2bf671c6b07c606ba3eec1fefc Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Tue, 25 Feb 2014 05:40:17 +0000 Subject: updated ui to use a dropdown of existing reason types instead of text box --- httemplate/edit/cust_refund.cgi | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/httemplate/edit/cust_refund.cgi b/httemplate/edit/cust_refund.cgi index df42e63ae..9f7ac8dee 100755 --- a/httemplate/edit/cust_refund.cgi +++ b/httemplate/edit/cust_refund.cgi @@ -106,14 +106,17 @@ % } - - Reason - - +<& /elements/tr-select-reason.html, + 'field' => 'reasonnum', + 'reason_class' => 'F', + 'control_button' => "document.getElementById('confirm_refund_button')", + 'cgi' => $cgi, +&> +
- + -- cgit v1.2.1 From afe30fc7315196cc4ae6da7606995cb8388d1a32 Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Tue, 25 Feb 2014 05:40:44 +0000 Subject: added refund reasons to main menu --- httemplate/elements/menu.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index cd4fb39ec..4ba7b2f00 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -656,6 +656,10 @@ if ( $curuser->access_right('Configuration') ) { $config_billing{'separator4'} = ''; #its a separator! $config_billing{'Credit reasons'} = [ $fsurl.'browse/reason.html?class=R', 'Credit reasons explain why a credit was issued.' ]; $config_billing{'Credit reason types'} = [ $fsurl.'browse/reason_type.html?class=R', 'Credit reason types define groups of reasons.' ]; + + $config_billing{'separator5'} = ''; #its a separator! + $config_billing{'Refund reasons'} = [ $fsurl.'browse/reason.html?class=F', 'Refund reasons explain why a refund was issued.' ]; + $config_billing{'Refund reason types'} = [ $fsurl.'browse/reason_type.html?class=F', 'Refund reason types define groups of reasons.' ]; } #XXX also to be unified -- cgit v1.2.1 From 43839f03bf937eb086c7f2a55c059a606571ab77 Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Tue, 25 Feb 2014 05:45:23 +0000 Subject: added refund reason_type class --- httemplate/elements/tr-select-reason.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/httemplate/elements/tr-select-reason.html b/httemplate/elements/tr-select-reason.html index 9a670a26b..b7a715b42 100755 --- a/httemplate/elements/tr-select-reason.html +++ b/httemplate/elements/tr-select-reason.html @@ -6,8 +6,8 @@ Example: #required 'field' => 'reasonnum', - 'reason_class' => 'C', # currently 'C', 'R', or 'S' - # for cancel, credit, or suspend + 'reason_class' => 'C', # currently 'C', 'R', 'F', or 'S' + # for cancel, credit, refund, or suspend #recommended 'cgi' => $cgi, #easiest way for things to be properly "sticky" on errors @@ -161,6 +161,8 @@ if ($class eq 'C') { $add_access_right = 'Add on-the-fly suspend reason'; } elsif ($class eq 'R') { $add_access_right = 'Add on-the-fly credit reason'; +} elsif ($class eq 'F') { + $add_access_right = 'Add on-the-fly refund reason'; } else { die "illegal class: $class"; } -- cgit v1.2.1 From aa302b14cbe21ca99b70d9d13d75dbd3fb72d038 Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Thu, 6 Mar 2014 22:42:55 +0000 Subject: Created reason_Mixin.pm module to refactor the reason method and code inside the _upgrade method in cust_credit.pm and cust_refund.pm --- FS/FS/reason_Mixin.pm | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 FS/FS/reason_Mixin.pm diff --git a/FS/FS/reason_Mixin.pm b/FS/FS/reason_Mixin.pm new file mode 100644 index 000000000..fdf796219 --- /dev/null +++ b/FS/FS/reason_Mixin.pm @@ -0,0 +1,121 @@ +package FS::reason_Mixin; + +use strict; +use Carp qw( croak ); #confess ); +use FS::Record qw( qsearch qsearchs dbdef ); +use FS::access_user; +use FS::UID qw( dbh ); + +our $DEBUG = 0; +our $me = '[FS::reason_Mixin]'; + +=item reason + +Returns the text of the associated reason (see L) for this credit. + +=cut + +sub reason { + my ($self, $value, %options) = @_; + my $dbh = dbh; + my $reason; + my $typenum = $options{'reason_type'}; + + my $oldAutoCommit = $FS::UID::AutoCommit; # this should already be in + local $FS::UID::AutoCommit = 0; # a transaction if it matters + + if ( defined( $value ) ) { + my $hashref = { 'reason' => $value }; + $hashref->{'reason_type'} = $typenum if $typenum; + my $addl_from = "LEFT JOIN reason_type ON ( reason_type = typenum ) "; + my $extra_sql = " AND reason_type.class='F'"; + + $reason = qsearchs( { 'table' => 'reason', + 'hashref' => $hashref, + 'addl_from' => $addl_from, + 'extra_sql' => $extra_sql, + } ); + + if (!$reason && $typenum) { + $reason = new FS::reason( { 'reason_type' => $typenum, + 'reason' => $value, + 'disabled' => 'Y', + } ); + my $error = $reason->insert; + if ( $error ) { + warn "error inserting reason: $error\n"; + $reason = undef; + } + } + + $self->reasonnum($reason ? $reason->reasonnum : '') ; + warn "$me reason used in set mode with non-existant reason -- clearing" + unless $reason; + } + $reason = qsearchs( 'reason', { 'reasonnum' => $self->reasonnum } ); + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ( $reason ? $reason->reason : '' ). + ( $self->addlinfo ? ' '.$self->addlinfo : '' ); +} + +# Used by FS::Upgrade to migrate reason text fields to reasonnum. +sub _upgrade_reasonnum { # class method + my $class = shift; + my $table = $class->table; + + if (defined dbdef->table($table)->column('reason')) { + + warn "$me Checking for unmigrated reasons\n" if $DEBUG; + + my @cust_refunds = qsearch({ 'table' => $table, + 'hashref' => {}, + 'extra_sql' => 'WHERE reason IS NOT NULL', + }); + + if (scalar(grep { $_->getfield('reason') =~ /\S/ } @cust_refunds)) { + warn "$me Found unmigrated reasons\n" if $DEBUG; + my $hashref = { 'class' => 'F', 'type' => 'Legacy' }; + my $reason_type = qsearchs( 'reason_type', $hashref ); + unless ($reason_type) { + $reason_type = new FS::reason_type( $hashref ); + my $error = $reason_type->insert(); + die "$class had error inserting FS::reason_type into database: $error\n" + if $error; + } + + $hashref = { 'reason_type' => $reason_type->typenum, + 'reason' => '(none)' + }; + my $noreason = qsearchs( 'reason', $hashref ); + unless ($noreason) { + $hashref->{'disabled'} = 'Y'; + $noreason = new FS::reason( $hashref ); + my $error = $noreason->insert(); + die "can't insert legacy reason '(none)' into database: $error\n" + if $error; + } + + foreach my $cust_refund ( @cust_refunds ) { + my $reason = $cust_refund->getfield('reason'); + warn "Contemplating reason $reason\n" if $DEBUG > 1; + if ($reason =~ /\S/) { + $cust_refund->reason($reason, 'reason_type' => $reason_type->typenum) + or die "can't insert legacy reason $reason into database\n"; + }else{ + $cust_refund->reasonnum($noreason->reasonnum); + } + + $cust_refund->setfield('reason', ''); + my $error = $cust_refund->replace; + + warn "*** WARNING: error replacing reason in $class ". + $cust_refund->refundnum. ": $error ***\n" + if $error; + } + } + } +} + +1; -- cgit v1.2.1 From 9ac90646828dd34b49fc2474c9666ba33c3508a4 Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Thu, 6 Mar 2014 22:44:01 +0000 Subject: refactored reason and _upgrade method to inherit methods from reason_Mixin.pm --- FS/FS/cust_credit.pm | 103 ++---------------------------------------------- FS/FS/cust_refund.pm | 108 +-------------------------------------------------- 2 files changed, 6 insertions(+), 205 deletions(-) diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index 7ae6c97a5..567be21d6 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -1,5 +1,6 @@ package FS::cust_credit; -use base qw( FS::otaker_Mixin FS::cust_main_Mixin FS::Record ); +use base qw( FS::otaker_Mixin FS::cust_main_Mixin FS::reason_Mixin + FS::Record ); use strict; use vars qw( $conf $unsuspendauto $me $DEBUG @@ -447,57 +448,8 @@ sub credited { Returns the customer (see L) for this credit. -=item reason - -Returns the text of the associated reason (see L) for this credit. - =cut -sub reason { - my ($self, $value, %options) = @_; - my $dbh = dbh; - my $reason; - my $typenum = $options{'reason_type'}; - - my $oldAutoCommit = $FS::UID::AutoCommit; # this should already be in - local $FS::UID::AutoCommit = 0; # a transaction if it matters - - if ( defined( $value ) ) { - my $hashref = { 'reason' => $value }; - $hashref->{'reason_type'} = $typenum if $typenum; - my $addl_from = "LEFT JOIN reason_type ON ( reason_type = typenum ) "; - my $extra_sql = " AND reason_type.class='R'"; - - $reason = qsearchs( { 'table' => 'reason', - 'hashref' => $hashref, - 'addl_from' => $addl_from, - 'extra_sql' => $extra_sql, - } ); - - if (!$reason && $typenum) { - $reason = new FS::reason( { 'reason_type' => $typenum, - 'reason' => $value, - 'disabled' => 'Y', - } ); - my $error = $reason->insert; - if ( $error ) { - warn "error inserting reason: $error\n"; - $reason = undef; - } - } - - $self->reasonnum($reason ? $reason->reasonnum : '') ; - warn "$me reason used in set mode with non-existant reason -- clearing" - unless $reason; - } - $reason = qsearchs( 'reason', { 'reasonnum' => $self->reasonnum } ); - - $dbh->commit or die $dbh->errstr if $oldAutoCommit; - - ( $reason ? $reason->reason : '' ). - ( $self->addlinfo ? ' '.$self->addlinfo : '' ); -} - # _upgrade_data # # Used by FS::Upgrade to migrate to a new database. @@ -507,56 +459,9 @@ sub _upgrade_data { # class method warn "$me upgrading $class\n" if $DEBUG; - if (defined dbdef->table($class->table)->column('reason')) { - - warn "$me Checking for unmigrated reasons\n" if $DEBUG; - - my @cust_credits = qsearch({ 'table' => $class->table, - 'hashref' => {}, - 'extra_sql' => 'WHERE reason IS NOT NULL', - }); - - if (scalar(grep { $_->getfield('reason') =~ /\S/ } @cust_credits)) { - warn "$me Found unmigrated reasons\n" if $DEBUG; - my $hashref = { 'class' => 'R', 'type' => 'Legacy' }; - my $reason_type = qsearchs( 'reason_type', $hashref ); - unless ($reason_type) { - $reason_type = new FS::reason_type( $hashref ); - my $error = $reason_type->insert(); - die "$class had error inserting FS::reason_type into database: $error\n" - if $error; - } + $class->_upgrade_reasonnum(%opts); - $hashref = { 'reason_type' => $reason_type->typenum, - 'reason' => '(none)' - }; - my $noreason = qsearchs( 'reason', $hashref ); - unless ($noreason) { - $hashref->{'disabled'} = 'Y'; - $noreason = new FS::reason( $hashref ); - my $error = $noreason->insert(); - die "can't insert legacy reason '(none)' into database: $error\n" - if $error; - } - - foreach my $cust_credit ( @cust_credits ) { - my $reason = $cust_credit->getfield('reason'); - warn "Contemplating reason $reason\n" if $DEBUG > 1; - if ($reason =~ /\S/) { - $cust_credit->reason($reason, 'reason_type' => $reason_type->typenum) - or die "can't insert legacy reason $reason into database\n"; - }else{ - $cust_credit->reasonnum($noreason->reasonnum); - } - - $cust_credit->setfield('reason', ''); - my $error = $cust_credit->replace; - - warn "*** WARNING: error replacing reason in $class ". - $cust_credit->crednum. ": $error ***\n" - if $error; - } - } + if (defined dbdef->table($class->table)->column('reason')) { warn "$me Ensuring existance of auto reasons\n" if $DEBUG; diff --git a/FS/FS/cust_refund.pm b/FS/FS/cust_refund.pm index 097ed2df3..e3fc910ec 100644 --- a/FS/FS/cust_refund.pm +++ b/FS/FS/cust_refund.pm @@ -2,7 +2,7 @@ package FS::cust_refund; use strict; use base qw( FS::otaker_Mixin FS::payinfo_transaction_Mixin FS::cust_main_Mixin - FS::Record ); + FS::reason_Mixin FS::Record ); use vars qw( @encrypted_fields $me $DEBUG $ignore_empty_reasonnum ); use Business::CreditCard; use FS::Record qw( qsearch qsearchs dbh dbdef ); @@ -406,114 +406,10 @@ sub unapplied_sql { } -=item reason - -Returns the text of the associated reason (see L) for this credit. - -=cut - -sub reason { - my ($self, $value, %options) = @_; - my $dbh = dbh; - my $reason; - my $typenum = $options{'reason_type'}; - - my $oldAutoCommit = $FS::UID::AutoCommit; # this should already be in - local $FS::UID::AutoCommit = 0; # a transaction if it matters - - if ( defined( $value ) ) { - my $hashref = { 'reason' => $value }; - $hashref->{'reason_type'} = $typenum if $typenum; - my $addl_from = "LEFT JOIN reason_type ON ( reason_type = typenum ) "; - my $extra_sql = " AND reason_type.class='F'"; - - $reason = qsearchs( { 'table' => 'reason', - 'hashref' => $hashref, - 'addl_from' => $addl_from, - 'extra_sql' => $extra_sql, - } ); - - if (!$reason && $typenum) { - $reason = new FS::reason( { 'reason_type' => $typenum, - 'reason' => $value, - 'disabled' => 'Y', - } ); - my $error = $reason->insert; - if ( $error ) { - warn "error inserting reason: $error\n"; - $reason = undef; - } - } - - $self->reasonnum($reason ? $reason->reasonnum : '') ; - warn "$me reason used in set mode with non-existant reason -- clearing" - unless $reason; - } - $reason = qsearchs( 'reason', { 'reasonnum' => $self->reasonnum } ); - - $dbh->commit or die $dbh->errstr if $oldAutoCommit; - - ( $reason ? $reason->reason : '' ). - ( $self->addlinfo ? ' '.$self->addlinfo : '' ); -} - # Used by FS::Upgrade to migrate to a new database. sub _upgrade_data { # class method my ($class, %opts) = @_; - - warn "$me upgrading $class\n" if $DEBUG; - - if (defined dbdef->table($class->table)->column('reason')) { - - warn "$me Checking for unmigrated reasons\n" if $DEBUG; - - my @cust_refunds = qsearch({ 'table' => $class->table, - 'hashref' => {}, - 'extra_sql' => 'WHERE reason IS NOT NULL', - }); - - if (scalar(grep { $_->getfield('reason') =~ /\S/ } @cust_refunds)) { - warn "$me Found unmigrated reasons\n" if $DEBUG; - my $hashref = { 'class' => 'F', 'type' => 'Legacy' }; - my $reason_type = qsearchs( 'reason_type', $hashref ); - unless ($reason_type) { - $reason_type = new FS::reason_type( $hashref ); - my $error = $reason_type->insert(); - die "$class had error inserting FS::reason_type into database: $error\n" - if $error; - } - - $hashref = { 'reason_type' => $reason_type->typenum, - 'reason' => '(none)' - }; - my $noreason = qsearchs( 'reason', $hashref ); - unless ($noreason) { - $hashref->{'disabled'} = 'Y'; - $noreason = new FS::reason( $hashref ); - my $error = $noreason->insert(); - die "can't insert legacy reason '(none)' into database: $error\n" - if $error; - } - - foreach my $cust_refund ( @cust_refunds ) { - my $reason = $cust_refund->getfield('reason'); - warn "Contemplating reason $reason\n" if $DEBUG > 1; - if ($reason =~ /\S/) { - $cust_refund->reason($reason, 'reason_type' => $reason_type->typenum) - or die "can't insert legacy reason $reason into database\n"; - }else{ - $cust_refund->reasonnum($noreason->reasonnum); - } - - $cust_refund->setfield('reason', ''); - my $error = $cust_refund->replace; - - warn "*** WARNING: error replacing reason in $class ". - $cust_refund->refundnum. ": $error ***\n" - if $error; - } - } - } + $class->_upgrade_reasonnum(%opts); $class->_upgrade_otaker(%opts); } -- cgit v1.2.1 From 0d991a8c986099180aaf2843a928e9396ff232db Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Thu, 6 Mar 2014 22:45:53 +0000 Subject: modified _upgrade to grant "Add on-the-fly refund reason" to groups with "Add on-the-fly credit reason" --- FS/FS/access_right.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/access_right.pm b/FS/FS/access_right.pm index 0906c0c9a..9ec7ab95c 100644 --- a/FS/FS/access_right.pm +++ b/FS/FS/access_right.pm @@ -243,7 +243,7 @@ sub _upgrade_data { # class method 'Configuration' => 'Alarm global configuration', 'Services: Accounts' => 'Services: Conferencing', 'Services: Accounts' => 'Services: Video', - 'Edit global package definitions' => 'Edit package definition costs', + 'Add on-the-fly credit reason' => 'Add on-the-fly refund reason', ); # foreach my $old_acl ( keys %onetime ) { -- cgit v1.2.1 From 77b23be67a840dae149a9e82613248b5f048cedd Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Thu, 6 Mar 2014 22:48:43 +0000 Subject: removed activate, renewal, term change --- FS/FS/reason_type.pm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/FS/FS/reason_type.pm b/FS/FS/reason_type.pm index d66f7b572..00ac9a87e 100644 --- a/FS/FS/reason_type.pm +++ b/FS/FS/reason_type.pm @@ -10,9 +10,6 @@ our %class_name = ( 'C' => 'cancel', 'R' => 'credit', 'S' => 'suspend', - 'U' => 'activate', #uncancel/unsuspend - 'W' => 'renewal', - 'T' => 'term change', 'F' => 'refund', ); @@ -20,9 +17,6 @@ our %class_purpose = ( 'C' => 'explain why a customer package was cancelled', 'R' => 'explain why a customer was credited', 'S' => 'explain why a customer package was suspended', - 'U' => 'explain why a customer package was unsuspended/uncanceled/activated', - 'W' => 'explain why a customer package was renewed', - 'T' => 'explain why a customer package term was changed', 'F' => 'explain why a customer was refunded', ); -- cgit v1.2.1 From c7bc6770f2f0b4413b788f8fc9abde6ad5548da3 Mon Sep 17 00:00:00 2001 From: Joshua Goodman Date: Thu, 6 Mar 2014 23:02:59 +0000 Subject: Adding line 246 "edit global pockage definitions costs" back in --- FS/FS/access_right.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/FS/FS/access_right.pm b/FS/FS/access_right.pm index 9ec7ab95c..d26db4895 100644 --- a/FS/FS/access_right.pm +++ b/FS/FS/access_right.pm @@ -243,6 +243,7 @@ sub _upgrade_data { # class method 'Configuration' => 'Alarm global configuration', 'Services: Accounts' => 'Services: Conferencing', 'Services: Accounts' => 'Services: Video', + 'Edit global package definitions' => 'Edit package definition costs', 'Add on-the-fly credit reason' => 'Add on-the-fly refund reason', ); -- cgit v1.2.1