[freeside-commits] branch rt74031_svc_realestate created. efa77ef0e8309528eb3b613a5b28d173f765b6c3
Mitch Jackson
mitch at freeside.biz
Tue Dec 19 19:31:47 PST 2017
The branch, rt74031_svc_realestate has been created
at efa77ef0e8309528eb3b613a5b28d173f765b6c3 (commit)
- Log -----------------------------------------------------------------
commit efa77ef0e8309528eb3b613a5b28d173f765b6c3
Author: Mitch Jackson <mitch at freeside.biz>
Date: Tue Dec 19 13:09:13 2017 -0600
rt# 74031 implementing svc_realestate
- updated schema
- updated includes
- begin writing FS::svc_realestate.pm
- progress adding a "Real estate unit" selection to
provision a real estate service
diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm
index 068f5b6c0..cbfeca020 100644
--- a/FS/FS/Mason.pm
+++ b/FS/FS/Mason.pm
@@ -223,8 +223,6 @@ 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;
@@ -422,6 +420,9 @@ if ( -e $addl_handler_use_file ) {
use FS::commission_rate;
use FS::saved_search;
use FS::sector_coverage;
+ use FS::realestate_location;
+ use FS::realestate_unit;
+ use FS::svc_realestate;
# Sammath Naur
if ( $FS::Mason::addl_handler_use ) {
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index e1301b6ca..f2817f5cb 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -7652,7 +7652,7 @@ sub tables_hashref {
['custnum'],
['realestatelocnum'],
['disabled'],
- ['title']
+ ['unit_title']
],
'foreign_keys' => [
{columns => ['agentnum'], table => 'agent'},
@@ -7681,6 +7681,16 @@ sub tables_hashref {
],
},
+ svc_realestate => {
+ columns => [
+ 'svcnum', 'serial', '', '', '', '',
+ 'description', 'varchar', 'NULL', $char_d, '', '',
+ 'property', 'varchar', 'NULL', $char_d, '', '',
+ ],
+ primary_key => 'svcnum',
+ index => [],
+ },
+
# name type nullability length default local
#'new_table' => {
diff --git a/FS/FS/h_svc_realestate.pm b/FS/FS/h_svc_realestate.pm
new file mode 100644
index 000000000..55f6edf60
--- /dev/null
+++ b/FS/FS/h_svc_realestate.pm
@@ -0,0 +1,31 @@
+package FS::h_svc_realestate;
+
+use strict;
+use vars qw( @ISA );
+use FS::h_Common;
+
+
+ at ISA = qw( FS::h_Common );
+
+sub table { 'h_svc_realestate' };
+
+=head1 NAME
+
+FS::h_svc_circuit - Historical telecom circuit service objects
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+An FS::h_svc_realestate object
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::h_Common>, L<FS::svc_realestate>, L<FS::Record>, schema.html from the base
+documentation.
+
+=cut
+
+1;
diff --git a/FS/FS/part_svc_column.pm b/FS/FS/part_svc_column.pm
index 75a2dfb1a..7d6e57c85 100644
--- a/FS/FS/part_svc_column.pm
+++ b/FS/FS/part_svc_column.pm
@@ -97,7 +97,7 @@ sub check {
;
return $error if $error;
- $self->columnflag =~ /^([DFSMAHX]?)$/
+ $self->columnflag =~ /^([DFSMAHXR]?)$/
or return "illegal columnflag ". $self->columnflag;
$self->columnflag(uc($1));
@@ -133,4 +133,3 @@ schema.html from the base documentation.
=cut
1;
-
diff --git a/FS/FS/svc_realestate.pm b/FS/FS/svc_realestate.pm
new file mode 100644
index 000000000..27012d047
--- /dev/null
+++ b/FS/FS/svc_realestate.pm
@@ -0,0 +1,99 @@
+package FS::svc_realestate;
+use base qw(FS::svc_Common);
+
+use strict;
+use warnings;
+use vars qw($conf);
+
+use FS::Record qw(qsearchs qsearch dbh);
+
+$FS::UID::callback{'FS::svc_realestate'} = sub {
+ $conf = new FS::Conf;
+};
+
+=head1 NAME
+
+FS::svc_realestate - Object methods for svc_realestate records
+
+=head1 SYNOPSIS
+
+ {...} TODO
+
+=head1 DESCRIPTION
+
+A FS::svc_realestate object represents a billable real estate trasnaction,
+such as renting a home or office.
+
+FS::svc_realestate inherits from FS::svc_Common. The following fields are
+currently supported:
+
+=over 4
+
+=item svcnum - primary key
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Instantiates a new svc_realestate object.
+
+=cut
+
+sub table_info {{
+ name => 'Real estate',
+ name_plural => 'Real estate services',
+ longname_plural => 'Real estate services',
+ display_weight => 100,
+ cancel_weight => 100,
+ fields => {
+ svcnum => 'Service',
+ description => 'Descriptive label',
+ property => 'Real estate property',
+ },
+}}
+
+sub table {'svc_realestate'};
+
+=item search_sql
+
+I have an unfounded suspicion this method serves no purpose in this context
+
+=cut
+
+sub search_sql {die "search_sql called on FS::svc_realestate"}
+
+=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 record. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+and replace methods.
+
+=back 4
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
diff --git a/httemplate/docs/part_svc-table.html b/httemplate/docs/part_svc-table.html
index 820d0b9cc..56a4d0e8c 100644
--- a/httemplate/docs/part_svc-table.html
+++ b/httemplate/docs/part_svc-table.html
@@ -39,6 +39,7 @@
<TR>
<TH ALIGN="left">Hosting</TH>
<TH ALIGN="left">Colocation</TH>
+ <TH ALIGN="left">Real Estate</TH>
</TR>
<TD VALIGN="top">
<UL STYLE="margin:0">
@@ -54,6 +55,11 @@
<LI><B>svc_port</B>: Customer router/switch port
</UL>
</TD>
+ <TD VALIGN="top">
+ <UL STYLE="margin:0">
+ <LI><B>svc_realestate</B>: Real estate properties
+ </UL>
+ </TD>
</TR>
<TABLE>
<!-- <LI>svc_charge - One-time charges (Partially unimplemented)
@@ -62,4 +68,3 @@
</BODY>
</HTML>
-
diff --git a/httemplate/edit/elements/part_svc_column.html b/httemplate/edit/elements/part_svc_column.html
index 816f3428b..ecf8eff9a 100644
--- a/httemplate/edit/elements/part_svc_column.html
+++ b/httemplate/edit/elements/part_svc_column.html
@@ -35,6 +35,9 @@ tie my %flag, 'Tie::IxHash',
'A' => { 'desc' => 'Automatically fill in from inventory',
'condition' => $inv_sub,
},
+ 'R' => { 'desc' => 'Manual selection from real estate',
+ 'condition' => $inv_sub,
+ },
'H' => { 'desc' => 'Select from hardware class',
'condition' => sub { $_[0]->{type} ne 'select-hardware' },
},
diff --git a/httemplate/edit/part_svc.cgi b/httemplate/edit/part_svc.cgi
index fed21256f..3018e3a0a 100755
--- a/httemplate/edit/part_svc.cgi
+++ b/httemplate/edit/part_svc.cgi
@@ -68,7 +68,7 @@ function flag_changed(obj) {
// for fields that have both 'input' and 'select', 'select' is 'select from
// inventory class'.
var select = document.getElementById(layer + '__' + field + '_select');
- if (newflag == "" || newflag == "X") { // disable
+ if (newflag == "" || newflag == "X" || newflag == 'R' ) { // disable
if ( input ) {
input.disabled = true;
input.className = 'disabled';
@@ -280,6 +280,3 @@ my $widget = new HTML::Widgets::SelectLayers(
}
);
</%init>
-
-
-
commit 8c04f3676f1e83393432a0ba899ec5b7fea4afe0
Author: Mitch Jackson <mitch at freeside.biz>
Date: Wed Dec 13 18:14:43 2017 -0600
rt# 74031 Implement forms for editing real estate inventory
diff --git a/httemplate/browse/realestate_location.html b/httemplate/browse/realestate_location.html
new file mode 100644
index 000000000..be2cd11f8
--- /dev/null
+++ b/httemplate/browse/realestate_location.html
@@ -0,0 +1,43 @@
+<% include( 'elements/browse.html',
+ title => emt('Real Estate Locations'),
+ name => 'real estate locations',
+
+ menubar => [
+ 'Edit units' => "${p}browse/realestate_unit.html",
+ 'Add a new location' => "${p}edit/realestate_location.html",
+ 'Add a new unit' => "${p}edit/realestate_unit.html",
+ ],
+
+ query => { table => 'realestate_location' },
+ count_query => 'SELECT COUNT(*) FROM realestate_location',
+
+ header => [ 'Location', 'Address', 'Address 2', 'City', 'State', 'Zip' ],
+ fields => [
+ 'location_title',
+ 'address1',
+ 'address2',
+ 'city',
+ 'state',
+ 'zip'
+ ],
+ links => [
+ ["${p}edit/realestate_location.html?", 'realestatelocnum' ],
+ ],
+
+ agent_virt => 1,
+ agent_pos => 0,
+ disableable => 1,
+)
+%>
+<%init>
+
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+die("access denied")
+ unless $curuser->access_right('Edit inventory')
+ || $curuser->access_right('Edit global inventory')
+ || $curuser->access_right('Configuration');
+
+
+
+</%init>
diff --git a/httemplate/browse/realestate_unit.html b/httemplate/browse/realestate_unit.html
new file mode 100644
index 000000000..e71a59819
--- /dev/null
+++ b/httemplate/browse/realestate_unit.html
@@ -0,0 +1,63 @@
+<% include( 'elements/browse.html',
+ title => emt('Real Estate Inventory'),
+ name => 'real estate inventory',
+
+ menubar => [
+ 'Edit locations' => "${p}browse/realestate_location.html",
+ 'Add a new location' => "${p}edit/realestate_location.html",
+ 'Add a new unit' => "${p}edit/realestate_unit.html",
+ ],
+
+ query => {
+ table => 'realestate_unit',
+ select => join(', ',qw(
+ realestate_unit.*
+ realestate_location.location_title
+ cust_main.first
+ cust_main.last
+ cust_main.company
+ )),
+ addl_from => "
+ LEFT JOIN realestate_location
+ ON realestate_location.realestatelocnum
+ = realestate_unit.realestatelocnum
+ LEFT JOIN cust_main
+ ON realestate_unit.custnum = cust_main.custnum
+ ",
+ },
+
+ count_query => 'SELECT COUNT(*) FROM realestate_unit',
+
+ header => [ 'Location', 'Unit', 'Customer' ],
+ fields => [
+ 'location_title',
+ 'unit_title',
+ sub {
+ return '' unless $_[0]->custnum;
+ return $_[0]->company if $_[0]->company;
+ return $_[0]->first.' '.$_[0]->last;
+ },
+ ],
+ links => [
+ ["${p}edit/realestate_location?", 'realestatelocnum' ],
+ ["${p}edit/realestate_unit.html?", 'realestatenum' ],
+ ["${p}view/cust_main.cgi?", 'custnum' ]
+ ],
+
+ agent_virt => 1,
+ agent_pos => 0,
+ disableable => 1,
+)
+%>
+<%init>
+
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+die("access denied")
+ unless $curuser->access_right('Edit inventory')
+ || $curuser->access_right('Edit global inventory')
+ || $curuser->access_right('Configuration');
+
+
+
+</%init>
diff --git a/httemplate/edit/process/realestate_location.html b/httemplate/edit/process/realestate_location.html
new file mode 100644
index 000000000..ab5cf230f
--- /dev/null
+++ b/httemplate/edit/process/realestate_location.html
@@ -0,0 +1,14 @@
+<% include( 'elements/process.html',
+ table => 'realestate_location',
+ viewall_dir => 'browse',
+ )
+%>
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+die "access denied"
+ unless $curuser->access_right('Edit inventory')
+ || $curuser->access_right('Edit global inventory')
+ || $curuser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/edit/process/realestate_unit.html b/httemplate/edit/process/realestate_unit.html
new file mode 100644
index 000000000..ba9b5dc92
--- /dev/null
+++ b/httemplate/edit/process/realestate_unit.html
@@ -0,0 +1,13 @@
+<& elements/process.html,
+ 'table' => 'realestate_unit',
+ 'viewall_dir' => 'browse',
+&>
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+die("access denied")
+ unless $curuser->access_right('Edit inventory')
+ || $curuser->access_right('Edit global inventory')
+ || $curuser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/edit/realestate_location.html b/httemplate/edit/realestate_location.html
new file mode 100644
index 000000000..254e57f5e
--- /dev/null
+++ b/httemplate/edit/realestate_location.html
@@ -0,0 +1,71 @@
+<% include( 'elements/edit.html',
+ 'name_singular' => 'Real Estate Location',
+ 'table' => 'realestate_location',
+
+ 'labels' => {
+ realestatelocnum => 'Location',
+ location_title => "Location",
+ address1 => "Address",
+ address2 => "Address",
+ city => "City",
+ state => "State",
+ zip => "Zip-Code",
+ disabled => "Disabled",
+ },
+ 'fields' => [
+ { field => 'realestatelocnum', type => 'hidden' },
+
+ { field => 'location_title',
+ type=>'text',
+ size => 40,
+ maxlength => 80,
+ },
+ { field => 'address1',
+ type=>'text',
+ size => 40,
+ maxlength => 80,
+ },
+ { field => 'address2',
+ type=>'text',
+ size => 40,
+ maxlength => 80,
+ },
+ { field => 'city',
+ type=>'text',
+ size => 40,
+ maxlength => 80,
+ },
+ { field => 'state',
+ type=>'text',
+ size => 40,
+ maxlength => 80,
+ },
+ { field => 'zip',
+ type=>'text',
+ size => 5,
+ maxlength => 5,
+ },
+
+ { field => 'agentnum',
+ type => 'select-agent',
+ },
+ { field => 'disabled',
+ type=>'checkbox',
+ value=>'Y'
+ },
+ ],
+
+ 'viewall_dir' => 'browse',
+ 'agent_virt' => 1,
+)
+%>
+
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+die("access denied")
+ unless $curuser->access_right('Edit inventory')
+ || $curuser->access_right('Edit global inventory')
+ || $curuser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/edit/realestate_unit.html b/httemplate/edit/realestate_unit.html
new file mode 100644
index 000000000..b8bf1fa22
--- /dev/null
+++ b/httemplate/edit/realestate_unit.html
@@ -0,0 +1,49 @@
+<% include( 'elements/edit.html',
+ 'name_singular' => 'Real Estate Unit',
+ 'table' => 'realestate_unit',
+
+ 'labels' => {
+ realestatenum => 'Ref No',
+ unit_title => 'Unit Title',
+ agentnum => 'Agent',
+ realestatelocnum => 'Location',
+ },
+ 'fields' => [
+ { field => 'realestatenum', type => 'hidden' },
+ { field => 'custnum', type => 'hidden' },
+
+ { field => 'unit_title',
+ type=>'text',
+ size => 40,
+ },
+ { field => 'realestatelocnum',
+ type => 'select-realestate_location',
+
+ # possible todo:
+ # I'd like to have this field disabled for editing on existing records,
+ # and only show the full selectbox for new records.
+
+ },
+ { field => 'agentnum',
+ type => 'select-agent',
+ },
+ { field => 'disabled',
+ type=>'checkbox',
+ value=>'Y'
+ },
+ ],
+
+ 'viewall_dir' => 'browse',
+ 'agent_virt' => 1,
+)
+%>
+
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+die("access denied")
+ unless $curuser->access_right('Edit inventory')
+ || $curuser->access_right('Edit global inventory')
+ || $curuser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index 3532e6074..0a73d71a6 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -829,12 +829,12 @@ $config_misc{'Custom fields'} = [ $fsurl.'browse/part_virtual_field.html', 'Loca
if $curuser->access_right('Edit custom fields');
$config_misc{'Translation strings'} = [ $fsurl.'browse/msgcat.html', 'Translations and other customizable labels for each locale' ]
if $curuser->access_right('Configuration');
-$config_misc{'Inventory classes and inventory'} = [ $fsurl.'browse/realestate_inventory.html', 'Setup inventory classes and stock inventory' ]
+$config_misc{'Inventory classes and inventory'} = [ $fsurl.'browse/inventory_class.html', 'Setup inventory classes and stock inventory' ]
if $curuser->access_right('Edit inventory')
|| $curuser->access_right('Edit global inventory')
|| $curuser->access_right('Configuration');
-$config_misc{'Real estate inventory'} = [ $fsurl.'browse/inventory_realestate.html', 'Setup real estate inventory' ]
+$config_misc{'Real estate inventory'} = [ $fsurl.'browse/realestate_unit.html', 'Setup real estate inventory' ]
if $curuser->access_right('Edit realestate inventory')
|| $curuser->access_right('Edit global inventory')
|| $curuser->access_right('Configuration');
diff --git a/httemplate/elements/select-realestate_location.html b/httemplate/elements/select-realestate_location.html
new file mode 100644
index 000000000..001ed3e89
--- /dev/null
+++ b/httemplate/elements/select-realestate_location.html
@@ -0,0 +1,32 @@
+<%doc>
+
+ Displays a selectbox populated with values from realestate_location.
+ key: realestate_location.realestatenum
+ value: realestate_location.location_title
+
+</%doc>
+
+<% include( '/elements/select-table.html',
+ %opt,
+ table => 'realestate_location',
+ name_col => 'location_title',
+ hashref => { 'disabled' => '' },
+ value => $select_value,
+ disable_empty => 1,
+ )
+%>
+
+<%init>
+
+#
+# possible todo:
+# I'd like to change the behavior of this select based on if
+# a new item is being created, or an existing item being edited
+
+my %opt = @_;
+my $select_value = $opt{'curr_value'} || $opt{'value'};
+
+# use Data::Dumper qw(Dumper);
+# print Dumper(\%opt);
+
+</%init>
diff --git a/httemplate/elements/tr-select-realestate_location.html b/httemplate/elements/tr-select-realestate_location.html
new file mode 100644
index 000000000..1367886ed
--- /dev/null
+++ b/httemplate/elements/tr-select-realestate_location.html
@@ -0,0 +1,17 @@
+<TR>
+ <TH ALIGN="right"><% $opt{'label'} || 'Real Estate Location' %></TD>
+ <TD>
+ <% include( '/elements/select-realestate_location.html',
+ 'curr_value' => $curr_value,
+ %opt
+ )
+ %>
+ </TD>
+</TR>
+
+<%init>
+
+my %opt = @_;
+my $curr_value = $opt{'curr_value'} || $opt{'value'};
+
+</%init>
commit 1650732b0a3a3d52a2072d72aa75b2c6939bacfe
Author: Mitch Jackson <mitch at freeside.biz>
Date: Wed Dec 13 18:13:01 2017 -0600
rt# 74031 reworked realestate schema as locations and units
- Update schemas
- Original approach discarded and rewritten as locations with units
diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm
index 7bdb6059e..068f5b6c0 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 b94407bc8..e1301b6ca 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 000000000..08d6dd3fa
--- /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 4e564175a..000000000
--- 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 5a93934da..000000000
--- 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 000000000..98b333765
--- /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
similarity index 77%
rename from FS/t/realestate_property.t
rename to FS/t/realestate_location.t
index af7f2f4de..ecb1d8be9 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
similarity index 75%
rename from FS/t/realestate_subproperty.t
rename to FS/t/realestate_unit.t
index 0f00eeec5..bbecc1a4c 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";
commit 4c1510910211827eec5cb6a4bd3726857e6fb94c
Author: Mitch Jackson <mitch at freeside.biz>
Date: Sun Dec 10 03:40:06 2017 +0000
rt# 74031 work in progress
- Update schemas
- First draft for FS::realestate_property
- and FS::realestate_subproperty
- worthless test for new modules
- Add a menuitem for property management
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 6d882046f..b94407bc8 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -7658,14 +7658,14 @@ sub tables_hashref {
'realestate_subproperty' => {
'columns' => [
- 'spropnum', 'serial', '', '', '', '',
- 'propnum', 'int', '', '', '', '',
- 'subtitle', 'varchar', '', $char_d, '', '',
- 'disabled', 'char', '', 1, '0', '',
+ 'subpropnum', 'serial', '', '', '', '',
+ 'propnum', 'int', '', '', '', '',
+ 'subtitle', 'varchar', '', $char_d, '', '',
+ 'disabled', 'char', '', 1, '0', '',
],
- 'primary_key' => 'spropnum',
+ 'primary_key' => 'subpropnum',
'unique' => [],
- 'index' => [ ['propnum'] ],
+ 'index' => [ ['propnum'],['subtitle'] ],
'foreign_keys' => [
{columns => ['propnum'], table => 'realestate_property'}
],
diff --git a/FS/FS/realestate_property.pm b/FS/FS/realestate_property.pm
new file mode 100644
index 000000000..4e564175a
--- /dev/null
+++ b/FS/FS/realestate_property.pm
@@ -0,0 +1,176 @@
+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
new file mode 100644
index 000000000..5a93934da
--- /dev/null
+++ b/FS/FS/realestate_subproperty.pm
@@ -0,0 +1,125 @@
+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/t/realestate_property.t b/FS/t/realestate_property.t
new file mode 100644
index 000000000..af7f2f4de
--- /dev/null
+++ b/FS/t/realestate_property.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::realestate_property;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/realestate_subproperty.t b/FS/t/realestate_subproperty.t
new file mode 100644
index 000000000..0f00eeec5
--- /dev/null
+++ b/FS/t/realestate_subproperty.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::realestate_subproperty;
+$loaded=1;
+print "ok 1\n";
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index defcc494f..3532e6074 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -829,11 +829,16 @@ $config_misc{'Custom fields'} = [ $fsurl.'browse/part_virtual_field.html', 'Loca
if $curuser->access_right('Edit custom fields');
$config_misc{'Translation strings'} = [ $fsurl.'browse/msgcat.html', 'Translations and other customizable labels for each locale' ]
if $curuser->access_right('Configuration');
-$config_misc{'Inventory classes and inventory'} = [ $fsurl.'browse/inventory_class.html', 'Setup inventory classes and stock inventory' ]
+$config_misc{'Inventory classes and inventory'} = [ $fsurl.'browse/realestate_inventory.html', 'Setup inventory classes and stock inventory' ]
if $curuser->access_right('Edit inventory')
|| $curuser->access_right('Edit global inventory')
|| $curuser->access_right('Configuration');
+$config_misc{'Real estate inventory'} = [ $fsurl.'browse/inventory_realestate.html', 'Setup real estate inventory' ]
+ if $curuser->access_right('Edit realestate inventory')
+ || $curuser->access_right('Edit global inventory')
+ || $curuser->access_right('Configuration');
+
$config_misc{'Upload targets'} = [ $fsurl.'browse/upload_target.html', 'Billing and payment upload destinations' ]
if $curuser->access_right('Configuration');
@@ -1038,4 +1043,3 @@ sub submenu {
}
</%init>
-
commit 0521301227e488e4bef7a65dd814b1489cd06972
Author: Mitch Jackson <mitch at freeside.biz>
Date: Sat Dec 9 23:00:21 2017 +0000
rt# 74031 Update database schema
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 6d7520bd9..6d882046f 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -495,7 +495,42 @@ sub tables_hashref {
my $username_len = 64; #usernamemax config file
- # name type nullability length default local
+ # Returns a hashref defining the entire application database schema
+ # Each key of the hashref contains a structure describing a database table
+ #
+ # table_name => {
+ # columns => [...],
+ # primary_key => 'column',
+ # unique => [column,column,...],
+ # index => [[column],[column,column],...],
+ # foreign_keys => [{...},{...},...],
+ # }
+ #
+ #
+ # columns => [
+ #
+ # 'column_name',
+ #
+ # 'column_type',
+ #
+ # 'NULL' or '', # 'NULL' : Allow null values
+ # # '' : Disallow null values
+ #
+ # 'length', # Column size value. eg:
+ # # 40 : VARCHAR(40)
+ # # '10,2' : FLOAT(10,2)
+ #
+ # 'default', # Default column value for a new record
+ # # (Unclear is setting this to '' results in a default
+ # # value of NULL or empty string)
+ #
+ # '', # local ?
+ #
+ # name, type, nullability, length, default, local,
+ # name, type, nullability, length, default, local,
+ # ...
+ #
+ # ],
return {
@@ -7601,6 +7636,41 @@ sub tables_hashref {
'foreign_keys' => [],
},
+ 'realestate_property' => {
+ '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', '',
+ ],
+ 'primary_key' => 'propnum',
+ 'unique' => [],
+ 'index' => [ ['agentnum'] ],
+ 'foreign_keys' => [
+ {columns => ['agentnum'], table => 'agent'}
+ ],
+ },
+
+ 'realestate_subproperty' => {
+ 'columns' => [
+ 'spropnum', 'serial', '', '', '', '',
+ 'propnum', 'int', '', '', '', '',
+ 'subtitle', 'varchar', '', $char_d, '', '',
+ 'disabled', 'char', '', 1, '0', '',
+ ],
+ 'primary_key' => 'spropnum',
+ 'unique' => [],
+ 'index' => [ ['propnum'] ],
+ 'foreign_keys' => [
+ {columns => ['propnum'], table => 'realestate_property'}
+ ],
+ },
+
# name type nullability length default local
#'new_table' => {
@@ -7627,4 +7697,3 @@ L<DBIx::DBSchema>
=cut
1;
-
-----------------------------------------------------------------------
More information about the freeside-commits
mailing list