summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitch Jackson <mitch@freeside.biz>2017-12-13 18:13:01 -0600
committerMitch Jackson <mitch@freeside.biz>2017-12-19 17:10:53 -0600
commit1650732b0a3a3d52a2072d72aa75b2c6939bacfe (patch)
treecc12d772a169eff25710e664147d9c72ff4cb936
parent4c1510910211827eec5cb6a4bd3726857e6fb94c (diff)
rt# 74031 reworked realestate schema as locations and units
- Update schemas - Original approach discarded and rewritten as locations with units
-rw-r--r--FS/FS/Mason.pm2
-rw-r--r--FS/FS/Schema.pm56
-rw-r--r--FS/FS/realestate_location.pm178
-rw-r--r--FS/FS/realestate_property.pm176
-rw-r--r--FS/FS/realestate_subproperty.pm125
-rw-r--r--FS/FS/realestate_unit.pm134
-rw-r--r--FS/t/realestate_location.t (renamed from FS/t/realestate_property.t)2
-rw-r--r--FS/t/realestate_unit.t (renamed from FS/t/realestate_subproperty.t)2
8 files changed, 349 insertions, 326 deletions
diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm
index 7bdb605..068f5b6 100644
--- a/FS/FS/Mason.pm
+++ b/FS/FS/Mason.pm
@@ -223,6 +223,8 @@ if ( -e $addl_handler_use_file ) {
use FS::cdr_batch;
use FS::inventory_class;
use FS::inventory_item;
+ use FS::realestate_location;
+ use FS::realestate_unit;
use FS::pkg_category;
use FS::pkg_class;
use FS::access_user;
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index b94407b..e1301b6 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -7636,38 +7636,48 @@ sub tables_hashref {
'foreign_keys' => [],
},
- 'realestate_property' => {
+ 'realestate_unit' => {
'columns' => [
- 'propnum', 'serial', '', '', '', '',
- 'agentnum', 'int', 'NULL', '', '', '',
- 'title', 'varchar', '', $char_d, '', '',
- 'address1', 'varchar', 'NULL', $char_d, '', '',
- 'address2', 'varchar', 'NULL', $char_d, '', '',
- 'city', 'varchar', 'NULL', $char_d, '', '',
- 'state', 'varchar', 'NULL', $char_d, '', '',
- 'zip', 'char', 'NULL', 5, '', '',
- 'disabled', 'char', '', 1, '0', '',
+ 'realestatenum', 'serial', '', '', '', '',
+ 'realestatelocnum', 'int', '', '', '', '',
+ 'agentnum', 'int', 'NULL', '', '', '',
+ 'custnum', 'int', 'NULL', '', '', '',
+ 'unit_title', 'varchar', '', $char_d, '', '',
+ 'disabled', 'char', 'NULL', 1, '', '',
+ ],
+ 'primary_key' => 'realestatenum',
+ 'unique' => [ ['unit_title'] ],
+ 'index' => [
+ ['agentnum'],
+ ['custnum'],
+ ['realestatelocnum'],
+ ['disabled'],
+ ['title']
],
- 'primary_key' => 'propnum',
- 'unique' => [],
- 'index' => [ ['agentnum'] ],
'foreign_keys' => [
- {columns => ['agentnum'], table => 'agent'}
+ {columns => ['agentnum'], table => 'agent'},
+ {columns => ['custnum'], table => 'cust_main'},
+ {columns => ['realestatelocnum'] => table => 'realestate_location'},
],
},
- 'realestate_subproperty' => {
+ realestate_location => {
'columns' => [
- 'subpropnum', 'serial', '', '', '', '',
- 'propnum', 'int', '', '', '', '',
- 'subtitle', 'varchar', '', $char_d, '', '',
- 'disabled', 'char', '', 1, '0', '',
+ 'realestatelocnum', 'serial', '', '', '', '',
+ 'agentnum', 'int', 'NULL', '', '', '',
+ 'location_title', 'varchar', '', $char_d, '', '',
+ 'address1', 'varchar', 'NULL', $char_d, '', '',
+ 'address2', 'varchar', 'NULL', $char_d, '', '',
+ 'city', 'varchar', 'NULL', $char_d, '', '',
+ 'state', 'varchar', 'NULL', $char_d, '', '',
+ 'zip', 'char', 'NULL', 5, '', '',
+ 'disabled', 'char', 'NULL', 1, '', '',
],
- 'primary_key' => 'subpropnum',
- 'unique' => [],
- 'index' => [ ['propnum'],['subtitle'] ],
+ primary_key => 'realestatelocnum',
+ 'unique' => [ ['location_title'] ],
+ 'index' => [ ['agentnum'], ['disabled'] ],
'foreign_keys' => [
- {columns => ['propnum'], table => 'realestate_property'}
+ {columns => ['agentnum'], table => 'agent'},
],
},
diff --git a/FS/FS/realestate_location.pm b/FS/FS/realestate_location.pm
new file mode 100644
index 0000000..08d6dd3
--- /dev/null
+++ b/FS/FS/realestate_location.pm
@@ -0,0 +1,178 @@
+package FS::realestate_location;
+use strict;
+use warnings;
+use Carp qw(croak);
+
+use base 'FS::Record';
+
+use FS::Record qw(qsearchs qsearch);
+
+=head1 NAME
+
+FS::realestate_location - Object representing a realestate_location record
+
+=head1 SYNOPSIS
+
+ use FS::realestate_location;
+
+ $location = new FS::realestate_location \%values;
+ $location = new FS::realestate_location {
+ agentnum => 1,
+ title => 'Superdome',
+ address1 => '1500 Sugar Bowl Dr',
+ city => 'New Orleans',
+ state => 'LA',
+ zip => '70112',
+ };
+
+ $error = $location->insert;
+ $error = $new_loc->replace($location);
+ $error = $record->check;
+
+ $error = $location->add_unit('Box Seat No. 42');
+ @units = $location->units;
+ @units = $location->active_units;
+
+=head1 DESCRIPTION
+
+An FS::realestate_location object represents a location for one or more
+FS::realestate_unit objects. Expected to contain at least one unit, as only
+realestate_unit objects are assignable to packages via
+L<FS::svc_realestate>.
+
+FS::realestate_location inherits from FS::Record.
+
+The following fields are currently supported:
+
+=over 4
+
+=item realestatelocnum
+
+=item agentnum
+
+=item location_title
+
+=item address1 (optional)
+
+=item address2 (optional)
+
+=item city (optional)
+
+=item state (optional)
+
+=item zip (optional)
+
+=item disabled
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF (see L<FS::Record>)
+
+=cut
+
+sub table {'realestate_location';}
+
+=item insert (see L<FS::Record>)
+
+=item delete
+
+ FS::realestate_location records should never be deleted, only disabled
+
+=cut
+
+sub delete {
+ # Once this record has been associated with a customer in any way, it
+ # should not be deleted. todo perhaps, add a is_deletable function that
+ # checks if the record has ever actually been used, and allows deletion
+ # if it hasn't. (entered in error, etc).
+ croak "FS::realestate_location records should never be deleted";
+}
+
+=item replace OLD_RECORD (see L<FS::Record>)
+
+=item check (see L<FS::Record>)
+
+=item agent
+
+Returns the associated agent
+
+=cut
+
+sub agent {
+ my $self = shift;
+ return undef unless $self->agentnum;
+ return exists $self->{agent}
+ ? $self->{agent}
+ : $self->{agent} = qsearchs('agent', {agentnum => $self->agentnum} );
+}
+
+
+=item add_unit UNIT_TITLE
+
+Create an associated L<FS::realestate_unit> record
+
+=cut
+
+sub add_unit {
+ my ($self, $unit_title) = @_;
+ croak "add_unit() requires a \$unit_title parameter" unless $unit_title;
+
+ if (
+ qsearchs('realestate_unit',{
+ realestatelocnum => $self->realestatelocnum,
+ unit_title => $unit_title,
+ })
+ ) {
+ return "Unit Title ($unit_title) has already been used for location (".
+ $self->location_title.")";
+ }
+
+ my $unit = FS::realestate_unit->new({
+ realestatelocnum => $self->realestatelocnum,
+ agentnum => $self->agentnum,
+ unit_title => $unit_title,
+ });
+ my $err = $unit->insert;
+ die "Error creating FS::realestate_new record: $err" if $err;
+
+ return;
+}
+
+
+=item units
+
+Returns all units associated with this location
+
+=cut
+
+sub units {
+ my $self = shift;
+ return qsearch(
+ 'realestate_unit',
+ {realestatelocnum => $self->realestatelocnum}
+ );
+}
+
+
+=head1 SUBROUTINES
+
+=over 4
+
+=cut
+
+
+
+
+=back
+
+=head1 SEE ALSO
+
+L<FS::record>, L<FS::realestate_unit>, L<FS::svc_realestate>
+
+=cut
+
+1;
diff --git a/FS/FS/realestate_property.pm b/FS/FS/realestate_property.pm
deleted file mode 100644
index 4e56417..0000000
--- a/FS/FS/realestate_property.pm
+++ /dev/null
@@ -1,176 +0,0 @@
-package FS::realestate_property;
-use strict;
-use warnings;
-use Carp qw(croak);
-
-use base 'FS::Record';
-use FS::Record qw(qsearch qsearchs);
-
-=head1 NAME
-
-FS::realestate_property - Object representing a realestate_property record
-
-=head1 SYNOPSIS
-
- use FS::realestate_property;
-
- $record = new FS:realestate_property \%values;
- $record = new FS::realestate_property {
- title => 'Superdome',
- address1 => '1500 Sugar Bowl Dr',
- city => 'New Orleans',
- state => 'LA',
- zip => '70112',
- disabled => 0,
- agentnum => 1,
- };
-
- $error = $record->insert;
- $error = $new_rec->replace($record)
- $error = $record->check;
-
- $sub_record = $record->add_subproperty('Box Seat No. 42');
-
- @subprops = $record->subproperties;
- @subprops = $record->enabled_subproperties;
-
-=head1 DESCRIPTION
-
-An FS::realestate_property object represents a real estate property. This
-object may represent a single property, such as a rental house. It may also
-represent a group of properties sharing a common address or identifier, such
-as a shopping mall, apartment complex, or office building.
-
-FS::realestate_property inherits from FS::Record.
-
-The following fields are currently supported:
-
-=over 4
-
-=item propnum
-
-=item agentnum
-
-=item title
-
-=item address1 *optional
-
-=item address2 *optional
-
-=item city *optional
-
-=item state *optional
-
-=item zip *optional
-
-=item disabled
-
-=back
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF (see L<FS::Record>)
-
-=cut
-
-sub table {'realestate_property';}
-
-=item insert (see L<FS::Record>)
-
-=item delete
-
- FS::realestate_property records should never be deleted, only disabled
-
-=cut
-
-sub delete {
- # Once this record has been associated with a customer in any way, it
- # should not be deleted. todo perhaps, add a is_deletable function that
- # checks if the record has ever actually been used, and allows deletion
- # if it hasn't. (entered in error, etc).
- croak "FS::realestate_property records should never be deleted";
-}
-
-
-=item replace OLD_RECORD (see L<FS::Record>)
-
-=item check (see L<FS::Record>)
-
-=item agent
-
-Returns the associated agent, if any, for this object
-
-=cut
-
-sub agent {
- my $self = shift;
- return undef unless $self->agentnum;
- return qsearchs('agent', {agentnum => $self->agentnum} );
-}
-
-
-=item subproperties
-
-Returns all subproperties linked to this property
-
-=cut
-
-sub subproperties {
- qsearch('realestate_subproperty', {propnum => shift->propnum} );
-}
-
-
-=item enabled_subproperties
-
-Returns all subproperties linked to this property where disabled = 0
-
-=cut
-
-sub enabled_subproperties {
- qsearch( 'realestate_subproperty', {
- propnum => shift->propnum,
- disabled => 0,
- });
-}
-
-=item add_subproperty SUBPROPERTY_TITLE
-
-Create a new subproperty record for this property
-
-=cut
-
-sub add_subproperty {
- my ($self, $subtitle) = @_;
- croak "add_subproperty() requires a \$subtitle parameter" unless $subtitle;
-
- my $subp = new FS::realestate_subproperty {
- propnum => $self->propnum,
- subtitle => $subtitle,
- disabled => 0,
- };
- my $err = $subp->insert;
- die "Error inserting subproperty: $err" if $err;
- $subp;
-}
-
-
-=back
-
-=head1 SUBROUTINES
-
-=over 4
-
-=cut
-
-
-=back
-
-=head1 SEE ALSO
-
-L<FS::record>, L<FS::realestate_subproperty>, L<FS::svc_realestate>
-
-=cut
-
-1;
diff --git a/FS/FS/realestate_subproperty.pm b/FS/FS/realestate_subproperty.pm
deleted file mode 100644
index 5a93934..0000000
--- a/FS/FS/realestate_subproperty.pm
+++ /dev/null
@@ -1,125 +0,0 @@
-package FS::realestate_subproperty;
-use strict;
-use warnings;
-use Carp qw(croak);
-
-use base 'FS::Record';
-
-use FS::Record qw(qsearchs);
-
-=head1 NAME
-
-FS::realestate_subproperty - Object representing a realestate_subproperty record
-
-=head1 SYNOPSIS
-
- use FS::realestate_subproperty;
-
- $record = new FS::realestate_subproperty \%values;
- $record = new FS::realestate_subproperty {
- propnum => 65535,
- subtitle => 'Box Seat No. 42',
- };
-
- $error = $record->insert;
- $error = new_rec->replace($record);
- $error = $record->check;
-
- $parent = $record->property;
-
-=head1 DESCRIPTION
-
-An FS::realestate_subproperty object represents a unit of real estate property.
-Every L<FS::realestate_property> must contain at least one subproperty, or unit,
-which is the actual unit considered for sale, rent, etc as tied to
-L<FS::svc_realestate>.
-
-FS::realestate_subproperty inherits from FS::Record.
-
-The following fields are currently supported:
-
-=over 4
-
-=item subpropnum
-
-=item propnum
-
-=item subtitle
-
-=item disabled
-
-=back
-
-=head1 METHODS
-
-=over 4
-
-=item new HASHREF (see L<FS::Record>)
-
-=cut
-
-sub table {'realestate_subproperty';}
-
-=item insert (see L<FS::Record>)
-
-=item delete
-
- FS::realestate_subproperty records should never be deleted, only disabled
-
-=cut
-
-sub delete {
- # Once this record has been associated with a customer in any way, it
- # should not be deleted. todo perhaps, add a is_deletable function that
- # checks if the record has ever actually been used, and allows deletion
- # if it hasn't. (entered in error, etc).
- croak "FS::realestate_subproperty records should never be deleted";
-}
-
-=item replace OLD_RECORD (see L<FS::Record>)
-
-=item check (see L<FS::Record>)
-
-=item agent
-
-Returns the associated agent, if any, for the parent L<FS::realestate_property>
-
-=cut
-
-sub agent {
- shift->property->agent;
-}
-
-=item property
-
-Returns the associated parent L<FS::realestate_property> record
-
-=cut
-
-sub property {
- my $self = shift;
- exists $self->{property}
- ? $self->{property}
- : $self->{property} = qsearchs('realestate_property',$self->propnum);
-}
-
-=back
-
-=head1 SUBROUTINES
-
-=over 4
-
-=cut
-
-
-
-
-=back
-
-=head1 SEE ALSO
-
-L<FS::record>, L<FS::realestate_property>, L<FS::svc_realestate>
-
-=cut
-
-1;
diff --git a/FS/FS/realestate_unit.pm b/FS/FS/realestate_unit.pm
new file mode 100644
index 0000000..98b3337
--- /dev/null
+++ b/FS/FS/realestate_unit.pm
@@ -0,0 +1,134 @@
+package FS::realestate_unit;
+use strict;
+use warnings;
+use Carp qw(croak);
+
+use base 'FS::Record';
+use FS::Record qw(qsearch qsearchs);
+
+=head1 NAME
+
+FS::realestate_unit - Object representing a realestate_unit record
+
+=head1 SYNOPSIS
+
+ use FS::realestate_unit;
+
+ $record = new FS:realestate_unit \%values;
+ $record = new FS::realestate_unit {
+ realestatelocnum => 42,
+ agentnum => 1,
+ unit_title => 'Ste 404',
+ };
+
+ $error = $record->insert;
+ $error = $new_rec->replace($record)
+ $error = $record->check;
+
+ $location = $record->location;
+
+=head1 DESCRIPTION
+
+An FS::realestate_unit object represents an invoicable unit of real estate.
+Object may represent a single property, such as a rental house. It may also
+represent a group of properties sharing a common address or identifier, such
+as a shopping mall, apartment complex, or office building, concert hall.
+
+A FS::realestate_unit object must be associated with a FS::realestate_location
+
+FS::realestate_unit inherits from FS::Record.
+
+The following fields are currently supported:
+
+=over 4
+
+=item realestatenum
+
+=item realestatelocnum
+
+=item agentnum
+
+=item custnum
+
+=item unit_title
+
+=item disabled
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF (see L<FS::Record>)
+
+=cut
+
+sub table {'realestate_unit';}
+
+=item insert (see L<FS::Record>)
+
+=item delete
+
+ FS::realestate_unit records should never be deleted, only disabled
+
+=cut
+
+sub delete {
+ # Once this record has been associated with a customer in any way, it
+ # should not be deleted. todo perhaps, add a is_deletable function that
+ # checks if the record has ever actually been used, and allows deletion
+ # if it hasn't. (entered in error, etc).
+ croak "FS::realestate_unit records should never be deleted";
+}
+
+
+=item replace OLD_RECORD (see L<FS::Record>)
+
+=item check (see L<FS::Record>)
+
+=item agent
+
+Returns the associated agent, if any, for this object
+
+=cut
+
+sub agent {
+ my $self = shift;
+ return undef unless $self->agentnum;
+ return qsearchs('agent', {agentnum => $self->agentnum} );
+}
+
+=item location
+
+ Return the associated FS::realestate_location object
+
+=cut
+
+sub location {
+ my $self = shift;
+ return $self->{location} if exists $self->{location};
+ return $self->{location} = qsearchs(
+ 'realestate_location',
+ {realestatelocnum => $self->realestatelocnum}
+ );
+}
+
+=back
+
+=head1 SUBROUTINES
+
+=over 4
+
+=cut
+
+
+=back
+
+=head1 SEE ALSO
+
+L<FS::record>, L<FS::realestate_location>, L<FS::svc_realestate>
+
+=cut
+
+1;
diff --git a/FS/t/realestate_property.t b/FS/t/realestate_location.t
index af7f2f4..ecb1d8b 100644
--- a/FS/t/realestate_property.t
+++ b/FS/t/realestate_location.t
@@ -1,5 +1,5 @@
BEGIN { $| = 1; print "1..1\n" }
END {print "not ok 1\n" unless $loaded;}
-use FS::realestate_property;
+use FS::realestate_location;
$loaded=1;
print "ok 1\n";
diff --git a/FS/t/realestate_subproperty.t b/FS/t/realestate_unit.t
index 0f00eee..bbecc1a 100644
--- a/FS/t/realestate_subproperty.t
+++ b/FS/t/realestate_unit.t
@@ -1,5 +1,5 @@
BEGIN { $| = 1; print "1..1\n" }
END {print "not ok 1\n" unless $loaded;}
-use FS::realestate_subproperty;
+use FS::realestate_unit;
$loaded=1;
print "ok 1\n";