RT#41501: OBH: Separate credit additional info into separate field on reports [v3...
[freeside.git] / FS / FS / cust_credit_void.pm
1 package FS::cust_credit_void; 
2
3 use strict;
4 use base qw( FS::otaker_Mixin FS::cust_main_Mixin FS::reason_Mixin FS::Record );
5 use FS::Record qw(qsearch qsearchs dbh fields);
6 use FS::CurrentUser;
7 use FS::access_user;
8 use FS::cust_credit;
9 use FS::UID qw( dbh );
10
11 =head1 NAME
12
13 FS::cust_credit_void - Object methods for cust_credit_void objects
14
15 =head1 SYNOPSIS
16
17   use FS::cust_credit_void;
18
19   $record = new FS::cust_credit_void \%hash;
20   $record = new FS::cust_credit_void { 'column' => 'value' };
21
22   $error = $record->insert;
23
24   $error = $new_record->replace($old_record);
25
26   $error = $record->delete;
27
28   $error = $record->check;
29
30 =head1 DESCRIPTION
31
32 An FS::cust_credit_void object represents a voided credit.  All fields in
33 FS::cust_credit are present, as well as:
34
35 =over 4
36
37 =item void_date - the date (unix timestamp) that the credit was voided
38
39 =item void_reason - the reason (a freeform string)
40
41 =item void_usernum - the user (L<FS::access_user>) who voided it
42
43 =back
44
45 =head1 METHODS
46
47 =over 4 
48
49 =item new HASHREF
50
51 Creates a new voided credit record.
52
53 =cut
54
55 sub table { 'cust_credit_void'; }
56
57 =item insert
58
59 Adds this voided credit to the database.
60
61 =item check
62
63 Checks all fields to make sure this is a valid voided credit.  If there is an
64 error, returns the error, otherwise returns false.  Called by the insert
65 method.
66
67 =cut
68
69 sub check {
70   my $self = shift;
71
72   my $error =
73     $self->ut_numbern('crednum')
74     || $self->ut_number('custnum')
75     || $self->ut_numbern('_date')
76     || $self->ut_money('amount')
77     || $self->ut_alphan('otaker')
78     || $self->ut_textn('reason')
79     || $self->ut_textn('addlinfo')
80     || $self->ut_enum('closed', [ '', 'Y' ])
81     || $self->ut_foreign_keyn('pkgnum', 'cust_pkg', 'pkgnum')
82     || $self->ut_foreign_keyn('eventnum', 'cust_event', 'eventnum')
83     || $self->ut_foreign_keyn('commission_agentnum',  'agent', 'agentnum')
84     || $self->ut_foreign_keyn('commission_salesnum',  'sales', 'salesnum')
85     || $self->ut_foreign_keyn('commission_pkgnum', 'cust_pkg', 'pkgnum')
86     || $self->ut_numbern('void_date')
87     || $self->ut_textn('void_reason')
88     || $self->ut_foreign_keyn('void_usernum', 'access_user', 'usernum')
89     || $self->ut_foreign_keyn('void_reasonnum', 'reason', 'reasonnum')
90   ;
91   return $error if $error;
92
93   $self->void_date(time) unless $self->void_date;
94
95   $self->void_usernum($FS::CurrentUser::CurrentUser->usernum)
96     unless $self->void_usernum;
97
98   $self->SUPER::check;
99 }
100
101 =item unvoid 
102
103 "Un-void"s this credit: Deletes the voided credit from the database and adds
104 back (but does not re-apply) a normal credit.
105
106 =cut
107
108 sub unvoid {
109   my $self = shift;
110
111   local $SIG{HUP} = 'IGNORE';
112   local $SIG{INT} = 'IGNORE';
113   local $SIG{QUIT} = 'IGNORE';
114   local $SIG{TERM} = 'IGNORE';
115   local $SIG{TSTP} = 'IGNORE';
116   local $SIG{PIPE} = 'IGNORE';
117
118   my $oldAutoCommit = $FS::UID::AutoCommit;
119   local $FS::UID::AutoCommit = 0;
120   my $dbh = dbh;
121
122   my $cust_credit = new FS::cust_credit ( {
123     map { $_ => $self->get($_) } grep { $_ !~ /void/ } $self->fields
124   } );
125   my $error = $cust_credit->insert;
126
127   if ( $error ) {
128     $dbh->rollback if $oldAutoCommit;
129     return $error;
130   }
131
132   $error ||= $self->delete;
133   if ( $error ) {
134     $dbh->rollback if $oldAutoCommit;
135     return $error;
136   }
137
138   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
139
140   '';
141
142 }
143
144 =item cust_main
145
146 Returns the parent customer object (see L<FS::cust_main>).
147
148 =cut
149
150 sub cust_main {
151   my $self = shift;
152   qsearchs( 'cust_main', { 'custnum' => $self->custnum } );
153 }
154
155 =item void_access_user
156
157 Returns the voiding employee object (see L<FS::access_user>).
158
159 =cut
160
161 sub void_access_user {
162   my $self = shift;
163   qsearchs('access_user', { 'usernum' => $self->void_usernum } );
164 }
165
166 =item void_access_user_name
167
168 Returns the voiding employee name.
169
170 =cut
171
172 sub void_access_user_name {
173   my $self = shift;
174   my $user = $self->void_access_user;
175   return unless $user;
176   return $user->name;
177 }
178
179 =item void_reason
180
181 Returns the text of the associated void credit reason (see L<FS::reason>) for this voided credit.
182
183 The reason for the original credit remains accessible through the reason method.
184
185 =cut
186
187 sub void_reason {
188   my ($self, $value, %options) = @_;
189   my $reason_text;
190   if ( $self->void_reasonnum ) {
191     my $reason = FS::reason->by_key($self->void_reasonnum);
192     $reason_text = $reason->reason;
193   } else { # in case one of these somehow still exists
194     $reason_text = $self->get('void_reason');
195   }
196
197   return $reason_text;
198 }
199
200 =back
201
202 =head1 BUGS
203
204 Doesn't yet support unvoid.
205
206 =head1 SEE ALSO
207
208 L<FS::cust_credit>, L<FS::Record>, schema.html from the base documentation.
209
210 =cut
211
212 1;
213