diff options
author | ivan <ivan> | 2009-01-08 01:45:22 +0000 |
---|---|---|
committer | ivan <ivan> | 2009-01-08 01:45:22 +0000 |
commit | 2b8ffc98529637ffddfe7cbf6b4f9b8deb90f0fa (patch) | |
tree | bfd6fad6189838b809f405b3e83f613f4e436537 /FS | |
parent | 619b9c20b1c2c76d439284bd6d023e5d5d9dbc7d (diff) |
start adding package locations, RT#4499
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS.pm | 2 | ||||
-rw-r--r-- | FS/FS/Conf.pm | 7 | ||||
-rw-r--r-- | FS/FS/Schema.pm | 57 | ||||
-rw-r--r-- | FS/FS/cust_location.pm | 175 | ||||
-rw-r--r-- | FS/FS/cust_main.pm | 168 | ||||
-rw-r--r-- | FS/FS/cust_pkg.pm | 32 | ||||
-rw-r--r-- | FS/MANIFEST | 2 | ||||
-rw-r--r-- | FS/t/cust_location.t | 5 |
8 files changed, 389 insertions, 59 deletions
@@ -222,6 +222,8 @@ L<FS::cust_pkg_reason> - Package reason class L<FS::cust_main> - Customer class +L<FS::cust_main_location> - Customer location class + L<FS::cust_main_Mixin> - Mixin class for records that contain fields from cust_main L<FS::cust_main_invoice> - Invoice destination class diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 5d5616938..9c9c6aaaf 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -2001,6 +2001,13 @@ worry that config_items is freeside-specific and icky. 'section' => 'billing', 'description' => 'By default, tax calculations are done based on the billing address. Enable this switch to calculate tax based on the shipping address instead. Note: Tax reports can take a long time when enabled.', 'type' => 'checkbox', + } +, + { + 'key' => 'tax-pkg_address', + 'section' => 'billing', + 'description' => 'By default, tax calculations are done based on the billing address. Enable this switch to calculate tax based on the package address instead (when present). Note: Tax reports can take a long time when enabled.', + 'type' => 'checkbox', }, { diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 17665b132..ecf017e3b 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -671,6 +671,28 @@ sub tables_hashref { ], }, + #eventually use for billing & ship from cust_main too + #for now, just cust_pkg locations + 'cust_location' => { + 'columns' => [ + 'locationnum', 'serial', '', '', '', '', + 'custnum', 'int', '', '', '', '', + 'address1', 'varchar', '', $char_d, '', '', + 'address2', 'varchar', 'NULL', $char_d, '', '', + 'city', 'varchar', '', $char_d, '', '', + 'county', 'varchar', 'NULL', $char_d, '', '', + 'state', 'varchar', 'NULL', $char_d, '', '', + 'zip', 'varchar', 'NULL', 10, '', '', + 'country', 'char', '', 2, '', '', + 'geocode', 'varchar', 'NULL', 20, '', '', + ], + 'primary_key' => 'locationnum', + 'unique' => [], + 'index' => [ [ 'custnum' ], + [ 'county' ], [ 'state' ], [ 'country' ], [ 'zip' ], + ], + }, + 'cust_main_invoice' => { 'columns' => [ 'destnum', 'serial', '', '', '', '', @@ -938,26 +960,27 @@ sub tables_hashref { 'cust_pkg' => { 'columns' => [ - 'pkgnum', 'serial', '', '', '', '', - 'custnum', 'int', '', '', '', '', - 'pkgpart', 'int', '', '', '', '', - 'otaker', 'varchar', '', 32, '', '', - 'setup', @date_type, '', '', - 'bill', @date_type, '', '', - 'last_bill', @date_type, '', '', - 'susp', @date_type, '', '', - 'adjourn', @date_type, '', '', - 'cancel', @date_type, '', '', - 'expire', @date_type, '', '', - 'change_date', @date_type, '', '', - 'change_pkgnum', 'int', 'NULL', '', '', '', - 'change_pkgpart', 'int', 'NULL', '', '', '', - 'manual_flag', 'char', 'NULL', 1, '', '', - 'quantity', 'int', 'NULL', '', '', '', + 'pkgnum', 'serial', '', '', '', '', + 'custnum', 'int', '', '', '', '', + 'pkgpart', 'int', '', '', '', '', + 'locationnum', 'int', 'NULL', '', '', '', + 'otaker', 'varchar', '', 32, '', '', + 'setup', @date_type, '', '', + 'bill', @date_type, '', '', + 'last_bill', @date_type, '', '', + 'susp', @date_type, '', '', + 'adjourn', @date_type, '', '', + 'cancel', @date_type, '', '', + 'expire', @date_type, '', '', + 'change_date', @date_type, '', '', + 'change_pkgnum', 'int', 'NULL', '', '', '', + 'change_pkgpart', 'int', 'NULL', '', '', '', + 'manual_flag', 'char', 'NULL', 1, '', '', + 'quantity', 'int', 'NULL', '', '', '', ], 'primary_key' => 'pkgnum', 'unique' => [], - 'index' => [ ['custnum'], ['pkgpart'], + 'index' => [ ['custnum'], ['pkgpart'], [ 'locationnum' ], ['setup'], ['last_bill'], ['bill'], ['susp'], ['adjourn'], ['expire'], ['cancel'], ['change_date'], diff --git a/FS/FS/cust_location.pm b/FS/FS/cust_location.pm new file mode 100644 index 000000000..0544dcfba --- /dev/null +++ b/FS/FS/cust_location.pm @@ -0,0 +1,175 @@ +package FS::cust_location; + +use strict; +use base qw( FS::Record ); +use Locale::Country; +use FS::Record qw( qsearch ); #qsearchs ); +use FS::cust_main; +use FS::cust_main_county; + +=head1 NAME + +FS::cust_location - Object methods for cust_location records + +=head1 SYNOPSIS + + use FS::cust_location; + + $record = new FS::cust_location \%hash; + $record = new FS::cust_location { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::cust_location object represents a customer location. FS::cust_location +inherits from FS::Record. The following fields are currently supported: + +=over 4 + +=item locationnum + +primary key + +=item custnum + +custnum + +=item address1 + +Address line one (required) + +=item address2 + +Address line two (optional) + +=item city + +City + +=item county + +County (optional, see L<FS::cust_main_county>) + +=item state + +State (see L<FS::cust_main_county>) + +=item zip + +Zip + +=item country + +Country (see L<FS::cust_main_county>) + +=item geocode + +Geocode + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new location. To add the location to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I<hash> method. + +=cut + +sub table { 'cust_location'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=item delete + +Delete this record from the database. + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=item check + +Checks all fields to make sure this is a valid location. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +#some false laziness w/cust_main, but since it should eventually lose these +#fields anyway... +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('locationnum') + || $self->ut_foreign_key('custnum', 'cust_main', 'custnum') + || $self->ut_text('address1') + || $self->ut_textn('address2') + || $self->ut_text('city') + || $self->ut_textn('county') + || $self->ut_textn('state') + || $self->ut_country('country') + || $self->ut_zip('zip', $self->country) + || $self->ut_alphan('geocode') + ; + return $error if $error; + + unless ( qsearch('cust_main_county', { + 'country' => $self->country, + 'state' => '', + } ) ) { + return "Unknown state/county/country: ". + $self->state. "/". $self->county. "/". $self->country + unless qsearch('cust_main_county',{ + 'state' => $self->state, + 'county' => $self->county, + 'country' => $self->country, + } ); + } + + $self->SUPER::check; +} + +=item country_full + +Returns this locations's full country name + +=cut + +sub country_full { + my $self = shift; + code2country($self->country); +} + +=back + +=head1 BUGS + +Not yet used for cust_main billing and shipping addresses. + +=head1 SEE ALSO + +L<FS::cust_main_county>, L<FS::cust_pkg>, L<FS::Record>, +schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index da1d3e195..2b94dca33 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -135,101 +135,181 @@ FS::Record. The following fields are currently supported: =over 4 -=item custnum - primary key (assigned automatically for new customers) +=item custnum -=item agentnum - agent (see L<FS::agent>) +Primary key (assigned automatically for new customers) -=item refnum - Advertising source (see L<FS::part_referral>) +=item agentnum + +Agent (see L<FS::agent>) + +=item refnum + +Advertising source (see L<FS::part_referral>) + +=item first + +First name -=item first - name +=item last -=item last - name +Last name -=item ss - social security number (optional) +=item ss -=item company - (optional) +Cocial security number (optional) + +=item company + +(optional) =item address1 -=item address2 - (optional) +=item address2 + +(optional) =item city -=item county - (optional, see L<FS::cust_main_county>) +=item county -=item state - (see L<FS::cust_main_county>) +(optional, see L<FS::cust_main_county>) + +=item state + +(see L<FS::cust_main_county>) =item zip -=item country - (see L<FS::cust_main_county>) +=item country + +(see L<FS::cust_main_county>) -=item daytime - phone (optional) +=item daytime -=item night - phone (optional) +phone (optional) -=item fax - phone (optional) +=item night -=item ship_first - name +phone (optional) -=item ship_last - name +=item fax -=item ship_company - (optional) +phone (optional) + +=item ship_first + +Shipping first name + +=item ship_last + +Shipping last name + +=item ship_company + +(optional) =item ship_address1 -=item ship_address2 - (optional) +=item ship_address2 + +(optional) =item ship_city -=item ship_county - (optional, see L<FS::cust_main_county>) +=item ship_county + +(optional, see L<FS::cust_main_county>) + +=item ship_state -=item ship_state - (see L<FS::cust_main_county>) +(see L<FS::cust_main_county>) =item ship_zip -=item ship_country - (see L<FS::cust_main_county>) +=item ship_country -=item ship_daytime - phone (optional) +(see L<FS::cust_main_county>) -=item ship_night - phone (optional) +=item ship_daytime -=item ship_fax - phone (optional) +phone (optional) -=item payby - Payment Type (See L<FS::payinfo_Mixin> for valid payby values) +=item ship_night -=item payinfo - Payment Information (See L<FS::payinfo_Mixin> for data format) +phone (optional) -=item paymask - Masked payinfo (See L<FS::payinfo_Mixin> for how this works) +=item ship_fax + +phone (optional) + +=item payby + +Payment Type (See L<FS::payinfo_Mixin> for valid payby values) + +=item payinfo + +Payment Information (See L<FS::payinfo_Mixin> for data format) + +=item paymask + +Masked payinfo (See L<FS::payinfo_Mixin> for how this works) =item paycvv Card Verification Value, "CVV2" (also known as CVC2 or CID), the 3 or 4 digit number on the back (or front, for American Express) of the credit card -=item paydate - expiration date, mm/yyyy, m/yyyy, mm/yy or m/yy +=item paydate + +Expiration date, mm/yyyy, m/yyyy, mm/yy or m/yy + +=item paystart_month + +Start date month (maestro/solo cards only) + +=item paystart_year + +Start date year (maestro/solo cards only) -=item paystart_month - start date month (maestro/solo cards only) +=item payissue -=item paystart_year - start date year (maestro/solo cards only) +Issue number (maestro/solo cards only) -=item payissue - issue number (maestro/solo cards only) +=item payname -=item payname - name on card or billing name +Name on card or billing name -=item payip - IP address from which payment information was received +=item payip -=item tax - tax exempt, empty or `Y' +IP address from which payment information was received -=item otaker - order taker (assigned automatically, see L<FS::UID>) +=item tax -=item comments - comments (optional) +Tax exempt, empty or `Y' -=item referral_custnum - referring customer number +=item otaker -=item spool_cdr - Enable individual CDR spooling, empty or `Y' +Order taker (assigned automatically, see L<FS::UID>) -=item dundate - a suggestion to events (see L<FS::part_bill_event">) to delay until this unix timestamp +=item comments -=item squelch_cdr - Discourage individual CDR printing, empty or `Y' +Comments (optional) + +=item referral_custnum + +Referring customer number + +=item spool_cdr + +Enable individual CDR spooling, empty or `Y' + +=item dundate + +A suggestion to events (see L<FS::part_bill_event">) to delay until this unix timestamp + +=item squelch_cdr + +Discourage individual CDR printing, empty or `Y' =back @@ -2905,6 +2985,11 @@ Only return events for the specified eventtable (by default, events of all event Explicitly pass the objects to be tested (typically used with eventtable). +=item testonly + +Set to true to return the objects, but not actually insert them into the +database. + =back =cut @@ -2935,7 +3020,8 @@ sub due_cust_event { local $FS::UID::AutoCommit = 0; my $dbh = dbh; - $self->select_for_update; #mutex + $self->select_for_update #mutex + unless $opt{testonly}; ### # 1: find possible events (initial search) diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 70f23df9b..03cec75b8 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -13,6 +13,7 @@ use FS::cust_main_Mixin; use FS::cust_svc; use FS::part_pkg; use FS::cust_main; +use FS::cust_location; use FS::type_pkgs; use FS::pkg_svc; use FS::cust_bill_pkg; @@ -106,7 +107,7 @@ inherits from FS::Record. The following fields are currently supported: =item pkgnum -primary key (assigned automatically for new billing items) +Primary key (assigned automatically for new billing items) =item custnum @@ -116,6 +117,10 @@ Customer (see L<FS::cust_main>) Billing item definition (see L<FS::part_pkg>) +=item locationnum + +Optional link to package location (see L<FS::location>) + =item setup date @@ -435,6 +440,7 @@ sub check { $self->ut_numbern('pkgnum') || $self->ut_foreign_key('custnum', 'cust_main', 'custnum') || $self->ut_numbern('pkgpart') + || $self->ut_foreign_keyn('locationnum', 'location', 'locationnum') || $self->ut_numbern('setup') || $self->ut_numbern('bill') || $self->ut_numbern('susp') @@ -1569,6 +1575,30 @@ sub cust_main { qsearchs( 'cust_main', { 'custnum' => $self->custnum } ); } +=item cust_location + +Returns the location object, if any (see L<FS::cust_location>). + +=cut + +sub cust_location { + my $self = shift; + return '' unless $self->locationnum; + qsearchs( 'cust_main', { 'locationnum' => $self->locationnum } ); +} + +=item cust_location_or_main + +If this package is associated with a location, returns the locaiton (see +L<FS::cust_location>), otherwise returns the customer (see L<FS::cust_main>). + +=cut + +sub cust_location_or_main { + my $self = shift; + $self->cust_location || $self->cust_main; +} + =item seconds_since TIMESTAMP Returns the number of seconds all accounts (see L<FS::svc_acct>) in this diff --git a/FS/MANIFEST b/FS/MANIFEST index c3252425b..21d721dcb 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -427,3 +427,5 @@ FS/cust_bill_pkg_display.pm t/cust_bill_pkg_display.t FS/cust_pkg_detail.pm t/cust_pkg_detail.t +FS/cust_location.pm +t/cust_location.t diff --git a/FS/t/cust_location.t b/FS/t/cust_location.t new file mode 100644 index 000000000..e98372d72 --- /dev/null +++ b/FS/t/cust_location.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::cust_location; +$loaded=1; +print "ok 1\n"; |