Merge branch 'master' of git.freeside.biz:/home/git/freeside
[freeside.git] / FS / FS / cust_credit_void.pm
1 package FS::cust_credit_void; 
2 use base qw( FS::otaker_Mixin FS::cust_main_Mixin FS::reason_Mixin FS::Record );
3
4 use strict;
5 use FS::Record qw(qsearchs); # qsearch qsearchs);
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 =item void_access_user
149
150 Returns the voiding employee object (see L<FS::access_user>).
151
152 =cut
153
154 sub void_access_user {
155   my $self = shift;
156   qsearchs('access_user', { 'usernum' => $self->void_usernum } );
157 }
158
159 =item void_access_user_name
160
161 Returns the voiding employee name.
162
163 =cut
164
165 sub void_access_user_name {
166   my $self = shift;
167   my $user = $self->void_access_user;
168   return unless $user;
169   return $user->name;
170 }
171
172 =item void_reason
173
174 Returns the text of the associated void credit reason (see L<FS::reason>) for this voided credit.
175
176 The reason for the original credit remains accessible through the reason method.
177
178 =cut
179
180 sub void_reason {
181   my ($self, $value, %options) = @_;
182   my $reason_text;
183   if ( $self->void_reasonnum ) {
184     my $reason = FS::reason->by_key($self->void_reasonnum);
185     $reason_text = $reason->reason;
186   } else { # in case one of these somehow still exists
187     $reason_text = $self->get('void_reason');
188   }
189
190   return $reason_text;
191 }
192
193 =back
194
195 =head1 BUGS
196
197 Doesn't yet support unvoid.
198
199 =head1 SEE ALSO
200
201 L<FS::cust_credit>, L<FS::Record>, schema.html from the base documentation.
202
203 =cut
204
205 1;
206