localize dates that will appear on invoices, #24850
[freeside.git] / FS / FS / quotation_pkg.pm
1 package FS::quotation_pkg;
2 use base qw( FS::TemplateItem_Mixin FS::Record );
3
4 use strict;
5 use FS::quotation_pkg_discount; #so its loaded when TemplateItem_Mixin needs it
6
7 =head1 NAME
8
9 FS::quotation_pkg - Object methods for quotation_pkg records
10
11 =head1 SYNOPSIS
12
13   use FS::quotation_pkg;
14
15   $record = new FS::quotation_pkg \%hash;
16   $record = new FS::quotation_pkg { 'column' => 'value' };
17
18   $error = $record->insert;
19
20   $error = $new_record->replace($old_record);
21
22   $error = $record->delete;
23
24   $error = $record->check;
25
26 =head1 DESCRIPTION
27
28 An FS::quotation_pkg object represents a quotation package.
29 FS::quotation_pkg inherits from FS::Record.  The following fields are currently
30 supported:
31
32 =over 4
33
34 =item quotationpkgnum
35
36 primary key
37
38 =item pkgpart
39
40 pkgpart
41
42 =item locationnum
43
44 locationnum
45
46 =item start_date
47
48 start_date
49
50 =item contract_end
51
52 contract_end
53
54 =item quantity
55
56 quantity
57
58 =item waive_setup
59
60 waive_setup
61
62
63 =back
64
65 =head1 METHODS
66
67 =over 4
68
69 =item new HASHREF
70
71 Creates a new quotation package.  To add the quotation package to the database,
72 see L<"insert">.
73
74 Note that this stores the hash reference, not a distinct copy of the hash it
75 points to.  You can ask the object for a copy with the I<hash> method.
76
77 =cut
78
79 sub table { 'quotation_pkg'; }
80
81 sub display_table         { 'quotation_pkg'; }
82
83 #forget it, just overriding cust_bill_pkg_display entirely
84 #sub display_table_orderby { 'quotationpkgnum'; } # something else?
85 #                                                 #  (for invoice display order)
86
87 sub discount_table        { 'quotation_pkg_discount'; }
88
89 =item insert
90
91 Adds this record to the database.  If there is an error, returns the error,
92 otherwise returns false.
93
94 =item delete
95
96 Delete this record from the database.
97
98 =item replace OLD_RECORD
99
100 Replaces the OLD_RECORD with this one in the database.  If there is an error,
101 returns the error, otherwise returns false.
102
103 =item check
104
105 Checks all fields to make sure this is a valid quotation package.  If there is
106 an error, returns the error, otherwise returns false.  Called by the insert
107 and replace methods.
108
109 =cut
110
111 sub check {
112   my $self = shift;
113
114   my $error = 
115     $self->ut_numbern('quotationpkgnum')
116     || $self->ut_foreign_key(  'quotationnum', 'quotation',    'quotationnum' )
117     || $self->ut_foreign_key(  'pkgpart',      'part_pkg',     'pkgpart'      )
118     || $self->ut_foreign_keyn( 'locationnum', 'cust_location', 'locationnum'  )
119     || $self->ut_numbern('start_date')
120     || $self->ut_numbern('contract_end')
121     || $self->ut_numbern('quantity')
122     || $self->ut_enum('waive_setup', [ '', 'Y'] )
123   ;
124   return $error if $error;
125
126   $self->SUPER::check;
127 }
128
129 sub desc {
130   my $self = shift;
131   $self->part_pkg->pkg;
132 }
133
134 sub setup {
135   my $self = shift;
136   return '0.00' if $self->waive_setup eq 'Y' || $self->{'_NO_SETUP_KLUDGE'};
137   my $part_pkg = $self->part_pkg;
138   #my $setup = $part_pkg->can('base_setup') ? $part_pkg->base_setup
139   #                                         : $part_pkg->option('setup_fee');
140   my $setup = $part_pkg->option('setup_fee');
141   #XXX discounts
142   $setup *= $self->quantity if $self->quantity;
143   sprintf('%.2f', $setup);
144
145 }
146
147 sub recur {
148   my $self = shift;
149   return '0.00' if $self->{'_NO_RECUR_KLUDGE'};
150   my $part_pkg = $self->part_pkg;
151   my $recur = $part_pkg->can('base_recur') ? $part_pkg->base_recur
152                                            : $part_pkg->option('recur_fee');
153   #XXX discounts
154   $recur *= $self->quantity if $self->quantity;
155   sprintf('%.2f', $recur);
156 }
157
158 =item cust_bill_pkg_display [ type => TYPE ]
159
160 =cut
161
162 sub cust_bill_pkg_display {
163   my ( $self, %opt ) = @_;
164
165   my $type = $opt{type} if exists $opt{type};
166   return () if $type eq 'U'; #quotations don't have usage
167
168   if ( $self->get('display') ) {
169     return ( grep { defined($type) ? ($type eq $_->type) : 1 }
170                @{ $self->get('display') }
171            );
172   } else {
173
174     #??
175     my $setup = $self->new($self->hashref);
176     $setup->{'_NO_RECUR_KLUDGE'} = 1;
177     $setup->{'type'} = 'S';
178     my $recur = $self->new($self->hashref);
179     $recur->{'_NO_SETUP_KLUDGE'} = 1;
180     $recur->{'type'} = 'R';
181
182     if ( $type eq 'S' ) {
183       return ($setup);
184     } elsif ( $type eq 'R' ) {
185       return ($recur);
186     } else {
187       #return ($setup, $recur);
188       return ($self);
189     }
190
191   }
192
193 }
194
195 =item cust_main
196
197 Returns the customer (L<FS::cust_main> object).
198
199 =cut
200
201 sub cust_main {
202   my $self = shift;
203   my $quotation = FS::quotation->by_key($self->quotationnum) or return '';
204   $quotation->cust_main;
205 }
206
207 =back
208
209 =head1 BUGS
210
211 =head1 SEE ALSO
212
213 L<FS::Record>, schema.html from the base documentation.
214
215 =cut
216
217 1;
218