Files
pmgr/scripts/sitelink2pmgr.pl

1604 lines
58 KiB
Perl

#perl -w
use strict;
use DBI;
use Data::Dumper;
use File::Copy;
my $closing_one_transaction = 0;
my $work_from_scratch = 1;
# Internally adjust all numbers coming from the database to
# be in inches. Not necessary to go to this detail, but the
# actual units used is irrelevant, provided everything is to
# scale, and this factor ensures that any fractional units
# become whole (e.g. 7.5 "feet" becomes 90 "units")
my $internal_adjustment_factor = 12;
my $schema_file = shift || die("Must specify schema file\n");
my $slink_file = shift || die("Must specify sitelink file\n");
my $slink_file = ";Data Source=$slink_file";
my $slink_pass = ";Jet OLEDB:Database Password=2web";
my $sdsn="Provider=Microsoft.Jet.OLEDB.4.0$slink_pass$slink_file";
my $sdbh = DBI->connect("dbi:ADO:$sdsn", undef, undef, {PrintError => 1,
RaiseError => 1});
# Connect to the database.
my($hostname, $database, $user, $password) = ('localhost',
'property_manager',
'pmgr', 'pmgruser');
$database = shift if @ARGV;
$user = shift if @ARGV;
$password = shift if @ARGV;
print "Connecting to $database as $user\n";
my $db_handle = DBI->connect("DBI:mysql:database=$database;host=$hostname",
$user, $password,
{'PrintError' => 1,
'RaiseError' => 0});
$SIG{__DIE__} = \&Die;
my ($query, $result, $nrows, $row);
my (%newdb) = ( 'schema' => [],
'tables' => {},
'ids' => {},
'lookup' => {'state' => { 1=>'AK', 14=>'ID', 48=>'WA' }} );
######################################################################
######################################################################
## Die
sub Die {
my @text = @_;
warn "----------------------------------------------------------\n";
warn "FATAL ERROR: @text\n";
my $count = 0;
{
my ($package, $filename, $line, $sub) = caller($count);
last unless defined $line;
warn sprintf("%02i %5i %-35s %-20s\n", $count++, $line, $sub,
$filename);
redo;
}
exit 1;
}
######################################################################
######################################################################
## addRow
sub addRow {
my ($table, $cols, $noid) = @_;
die unless $table;
die unless ref($cols) eq 'HASH';
die "Table `$table` is unknown!"
unless defined $newdb{'tables'}{$table};
my $id;
if ($noid) {
$id = $cols->{'id'};
}
if (!defined $id) {
$id = ++$newdb{'tables'}{$table}{'autoid'};
}
$cols->{'id'} = $id
unless ($noid);
# For debug purposes
my $line = (caller())[2];
$cols->{'--LINE--'} = "addRow called from line: $line";
$newdb{'tables'}{$table}{'rows'}[$id] = $cols;
return $id;
}
######################################################################
######################################################################
## updateRow
sub updateRow {
my ($table, $id, $cols) = @_;
die unless $table;
die unless $id;
die unless ref($cols) eq 'HASH';
die "Table `$table` is unknown!"
unless defined $newdb{'tables'}{$table};
die "Table `$table` : ID `$id` does not exist!"
unless $newdb{'tables'}{$table}{'rows'}[$id];
# For debug purposes
my $line = (caller())[2];
$cols->{'--UPDATE-LINE--'} = [] unless $cols->{'--UPDATE-LINE--'};
push(@{$cols->{'--UPDATE-LINE--'}}, "updateRow called from line: $line");
#$newdb{'tables'}{$table}{'rows'}[$id] = $cols;
return $id;
}
######################################################################
######################################################################
## query
sub query {
my ($dbh, $sql, $data, $ignore) = @_;
#print("$sql\n\n"); #return [ { 'id' => 7 } ];
#print("$sql\n\n") if $sql =~ /^\s*UPDATE/i;
#return 1 unless $sql =~ /^\s*SELECT/i;
my ($sth, $result);
if ($sql =~ /^\s*SELECT/i) {
$sth = $dbh->prepare($sql);
$sth->execute();
$result = $sth->fetchall_arrayref({});
} else {
$result = $dbh->do($sql);
}
if (!$result && !$ignore) {
print STDERR "SQL Query FAILED:\n";
print STDERR "$sql\n\n";
print STDERR Dumper $data
if defined $data;
die;
}
return ($sth, $result);
}
######################################################################
######################################################################
## executeSchema
sub executeSchema {
foreach (@{$newdb{'schema'}}) {
query($db_handle, $_);
}
foreach my $table (values %{$newdb{'tables'}}) {
foreach (@{$table->{'schema'}}) {
query($db_handle, $_);
}
}
}
######################################################################
######################################################################
## buildTables
sub buildTables {
foreach my $table_name (sort keys %{$newdb{'tables'}}) {
my $table = $newdb{'tables'}{$table_name};
my $count = 0;
foreach (@{$table->{'rows'}}) {
next unless defined $_;
++$count;
}
printf("%-30s : %d rows\n", $table->{'name'}, $count);
foreach (@{$table->{'rows'}}) {
next unless defined $_;
my %row = %$_;
delete $row{'--LINE--'};
my $query;
$query = "INSERT INTO " . $table->{'name'};
$query .= " (" . join(", ", map({"`$_`"} keys(%row))) . ")";
$query .= " VALUES (" . join(", ", map({s/'/''/g if defined $_;
defined $_
? (/^\w+\(.*\)$/
? $_
: "'$_'" )
: "NULL" }
values(%row))) . ")";
query($db_handle, $query, $_);
}
}
}
######################################################################
######################################################################
## helper functions
sub sizeCode {
my ($width, $depth) = @_;
return "YARD"
if ($width == 12 && $depth == 40);
return "APARTMENT"
if ($width == 20 && $depth == 30);
return sprintf("%02dx%02d", $width, $depth);
}
sub datefmt {
my ($dt) = @_;
return undef unless $dt;
my @dt = split(/\/|\s/, $dt);
#print("$dt : " . sprintf("%04d-%02d-%02d", $dt[2], $dt[0], $dt[1]) . "\n");
return sprintf("%04d-%02d-%02d%s", $dt[2], $dt[0], $dt[1], $dt[3] ? ' '.$dt[3] : "");
}
sub dates {
my ($type, $dt, $dt_end, $comment, $ledger_id) = @_;
# Nothing should be stamped before possession
my $stamp = $dt;
if ($stamp =~ m%^0?[12]/% || ($stamp =~ m%^0?3/(\d+)/% && $1 <= 25)) {
$stamp = "3/25/2009 16:00";
}
my $effective_dt = $dt;
my $through_dt = $dt_end;
# Use different dates for security deposits
if ($type eq 'charge' && $comment eq 'Security Deposit') {
$effective_dt = $newdb{'lookup'}{'ledger'}{$ledger_id}{'lease_date'};
$through_dt = undef;
}
# REVISIT <AP>: 20090708
# Do we want to have effective dates on invoices?
# Do we want to have effective dates for payments?
# The Receipt already has an effective date.
if ($type eq 'invoice') {
$effective_dt = undef;
$through_dt = undef;
}
return (datefmt($stamp), datefmt($effective_dt), datefmt($through_dt));
}
######################################################################
######################################################################
######################################################################
######################################################################
## BUILD THE DATABASE
open(SCHEMA, "<$schema_file") || die ("Can't open schema ($!)\n");
my $schema_query = "";
my $table;
while (<SCHEMA>) {
next if /^\s*--/;
if (/DROP\s+TABLE\s.*`?(pmgr_(\w+))/i) {
$table = $2;
$newdb{'tables'}{$table} = { 'name' => $1,
'schema' => [],
'autoid' => 0,
'rows' => [] };
}
$schema_query .= $_;
if (/;\s*$/) {
$schema_query =~ s/^\s+//;
$schema_query =~ s/\s*;\s*$//;
if (!$table) {
push(@{$newdb{'schema'}}, $schema_query);
} else {
push(@{$newdb{'tables'}{$table}{'schema'}}, $schema_query);
}
$schema_query = "";
}
}
close(SCHEMA);
executeSchema();
#################################################################
## Test Contact
addRow('contacts', {
'first_name' => 'Abijah',
# 'middle_name' => 'M',
'last_name' => 'Perkins' });
addRow('contact_addresses', {
'address' => '1324 N Liberty Lake Rd\nPMB 263',
'city' => 'Liberty Lake',
'state' => 'WA',
'postcode' => '99019',
'country' => 'USA' });
addRow('contacts_methods', {
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
'method_id' => $newdb{'tables'}{'contact_addresses'}{'autoid'},
'method' => 'ADDRESS',
'type' => 'MAIN',
'preference' => 'PRIMARY' },
1);
addRow('contact_addresses', {
'address' => '5221 W Myrtlewood Ct',
'city' => 'Spokane',
'state' => 'WA',
'postcode' => '99208',
'country' => 'USA' });
addRow('contacts_methods', {
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
'method_id' => $newdb{'tables'}{'contact_addresses'}{'autoid'},
'method' => 'ADDRESS',
'type' => 'HOME',
'preference' => 'ALTERNATE' },
1);
# addRow('contact_addresses',
# { 'address' => 'PO Box 69',
# 'city' => 'Granger',
# 'state' => 'WA',
# 'postcode' => '98932',
# 'country' => 'USA' });
# addRow('contacts_methods',
# { 'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
# 'method_id' => $newdb{'tables'}{'contact_addresses'}{'autoid'},
# 'method' => 'ADDRESS',
# 'type' => 'HOME',
# 'preference' => 'ALTERNATE' },
# 1);
addRow('contact_phones', {
'type' => 'MOBILE',
'phone' => '5098445573' });
addRow('contacts_methods', {
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
'method_id' => $newdb{'tables'}{'contact_phones'}{'autoid'},
'method' => 'PHONE',
'type' => 'MAIN',
'preference' => 'PRIMARY' },
1);
addRow('contact_phones', {
'type' => 'MOBILE',
'phone' => '5098445973' });
addRow('contacts_methods', {
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
'method_id' => $newdb{'tables'}{'contact_phones'}{'autoid'},
'method' => 'PHONE',
'type' => 'MAIN',
'preference' => 'ALTERNATE' },
1);
addRow('contact_phones', {
'type' => 'VIRTUAL',
'phone' => '5095901112' });
addRow('contacts_methods', {
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
'method_id' => $newdb{'tables'}{'contact_phones'}{'autoid'},
'method' => 'PHONE',
'type' => 'BUSINESS',
'preference' => 'WORK' },
1);
# addRow('contact_phones',
# { 'type' => 'LANDLINE',
# 'phone' => '5098541491' });
# addRow('contacts_methods',
# { 'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
# 'method_id' => $newdb{'tables'}{'contact_phones'}{'autoid'},
# 'method' => 'PHONE',
# 'type' => 'HOME',
# 'preference' => 'ALTERNATE' },
# 1);
addRow('contact_phones', {
'type' => 'VIRTUAL',
'phone' => '8774488664' });
addRow('contacts_methods', {
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
'method_id' => $newdb{'tables'}{'contact_phones'}{'autoid'},
'method' => 'PHONE',
'type' => 'BUSINESS',
'preference' => 'WORK' },
1);
addRow('contact_phones', {
'type' => 'FAX',
'phone' => '8662960131' });
addRow('contacts_methods', {
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
'method_id' => $newdb{'tables'}{'contact_phones'}{'autoid'},
'method' => 'PHONE',
'type' => 'BUSINESS',
'preference' => 'WORK' },
1);
addRow('contact_emails', {
'email' => 'abijah\@PerkinsHouse.com' });
addRow('contacts_methods', {
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
'method_id' => $newdb{'tables'}{'contact_emails'}{'autoid'},
'method' => 'EMAIL',
'type' => 'HOME',
'preference' => 'PRIMARY' },
1);
addRow('contact_emails', {
'email' => 'abijah\@PerkinsREI.com' });
addRow('contacts_methods', {
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
'method_id' => $newdb{'tables'}{'contact_emails'}{'autoid'},
'method' => 'EMAIL',
'type' => 'HOME',
'preference' => 'WORK' },
1);
addRow('contact_emails', {
'email' => 'abijah\@ValleyStorage.info' });
addRow('contacts_methods', {
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'},
'method_id' => $newdb{'tables'}{'contact_emails'}{'autoid'},
'method' => 'EMAIL',
'type' => 'BUSINESS',
'preference' => 'WORK' },
1);
#################################################################
## GROUPS
addRow('groups', {
'code' => 'Owner',
'name' => 'Owner Group' });
addRow('group_permissions', {
'group_id' => $newdb{'tables'}{'groups'}{'autoid'},
'name' => 'EVERYTHING',
'access' => 'FORCED' },
1);
#################################################################
## USERS
addRow('users', {
'code' => 'AP',
'login' => 'abijah',
'contact_id' => $newdb{'tables'}{'contacts'}{'autoid'} });
#################################################################
## SITES
addRow('sites', {
'code' => 'VSS',
'name' => 'Valley Storage' });
addRow('site_memberships', {
'site_id' => $newdb{'tables'}{'sites'}{'autoid'},
'user_id' => $newdb{'tables'}{'users'}{'autoid'},
'group_id' => $newdb{'tables'}{'groups'}{'autoid'} },
1);
addRow('site_areas', {
'site_id' => $newdb{'tables'}{'sites'}{'autoid'},
'code' => 'Main',
'name' => 'Main Facility Area' });
#################################################################
## LEASES
addRow('lease_types', {
'code' => 'SL',
'name' => 'Storage Lease' });
#################################################################
## LEDGERS
$newdb{'lookup'}{'account'} = {};
$query = "SELECT * FROM pmgr_accounts";
$result = query($db_handle, $query);
foreach $row (@$result) {
addRow('ledgers', {
'account_id' => $row->{'id'},
'name' => $row->{'id'} . '-1',
'comment' => undef });
$newdb{'lookup'}{'account'}{$row->{'name'}}
= {'account_id' => $row->{'id'},
'ledger_id' => $newdb{'tables'}{'ledgers'}{'autoid'} };
if ((!defined $newdb{'tables'}{'accounts'}{'autoid'}) ||
$row->{'id'} > $newdb{'tables'}{'accounts'}{'autoid'}) {
$newdb{'tables'}{'accounts'}{'autoid'} = $row->{'id'};
}
}
# For compatibility, while deciding on account names
if (!defined $newdb{'lookup'}{'account'}{'Cash'}) {
$newdb{'lookup'}{'account'}{'Cash'}
= $newdb{'lookup'}{'account'}{'Till'};
}
$newdb{'lookup'}{'charge_type'} = {};
$newdb{'lookup'}{'charge_type'}{'Rent'} =
$newdb{'lookup'}{'account'}{'Rent'};
$newdb{'lookup'}{'charge_type'}{'Late Fee'} =
$newdb{'lookup'}{'account'}{'Late Charge'};
$newdb{'lookup'}{'charge_type'}{'Security Deposit'} =
$newdb{'lookup'}{'account'}{'Security Deposit'};
#################################################################
## MONETARY TYPES
$newdb{'lookup'}{'tender_type'} = {};
foreach my $tender_name ('Cash', 'Check', 'Money Order', 'ACH',
'Concession', # REVISIT <AP>: 20090723 Do we really want this??
#'Debit Card', 'Credit Card',
) {
my ($tillable, $fields) = (0, 0);
my ($name1, $name2, $name3, $name4);
my ($name_field) = ('id');
$tillable = 1
if ($tender_name =~ /^Cash|Check|Money Order$/);
($name1, $name_field) = ('Check Number', 'data1')
if ($tender_name eq 'Check');
($name1, $name_field) = ('Money Order Number', 'data1')
if ($tender_name eq 'Money Order');
($name1, $name2, $name3, $name_field) = ('Routing Number', 'Account Number', 'Batch Number', 'data3')
if ($tender_name eq 'ACH');
($name1, $name2) = ('Debit Card Number', 'Expiration Date')
if ($tender_name eq 'Debit Card');
($name1, $name2, $name3) = ('Debit Card Number', 'Expiration Date', 'Billing Zip Code')
if ($tender_name eq 'Credit Card');
addRow('tender_types', {
'name' => $tender_name,
'account_id' => $newdb{'lookup'}{'account'}{$tender_name}{'account_id'},
'deposit_account_id' => $newdb{'lookup'}{'account'}{'Bank'}{'account_id'},
'tillable' => $tillable,
'auto_deposit' => ($tender_name eq 'ACH') ? 1 : 0,
'data1_name' => $name1,
'data2_name' => $name2,
'data3_name' => $name3,
'data4_name' => $name4,
'naming_field' => $name_field,
});
$newdb{'lookup'}{'tender_type'}{$tender_name}
= { 'tender_type_id' => $newdb{'tables'}{'tender_types'}{'autoid'},
'account_id' => $newdb{'lookup'}{'account'}{$tender_name}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{$tender_name}{'ledger_id'},
};
}
#################################################################
## MONETARY
$newdb{'lookup'}{'payment_type'} = {};
# SITELINK PAYMENT TYPE CODES
my %SITELINK_ACCOUNT_TYPE =
( 1 => 'Cash',
2 => 'Check',
3 => 'Money Order',
4 => 'ACH',
12 => 'Concession',
);
foreach my $account_type (keys(%SITELINK_ACCOUNT_TYPE)) {
my $payment_name = $SITELINK_ACCOUNT_TYPE{$account_type};
my ($ttid, $aid, $lid);
if (defined $newdb{'lookup'}{'tender_type'}{$payment_name}) {
($ttid, $aid, $lid) = ( $newdb{'lookup'}{'tender_type'}{$payment_name}{'tender_type_id'},
$newdb{'lookup'}{'tender_type'}{$payment_name}{'account_id'},
$newdb{'lookup'}{'tender_type'}{$payment_name}{'ledger_id'} );
}
else {
($ttid, $aid, $lid) = ( undef,
$newdb{'lookup'}{'account'}{$payment_name}{'account_id'},
$newdb{'lookup'}{'account'}{$payment_name}{'ledger_id'} );
}
$newdb{'lookup'}{'payment_type'}{$account_type}
= { 'name' => $payment_name,
'tender_type_id' => $ttid,
'account_id' => $aid,
'ledger_id' => $lid,
};
}
#################################################################
## SPECIAL CASE FOR CLOSING
$newdb{'lookup'}{'_closing'}
= { 'name' => 'Closing',
'stamp' => (dates('receipt', '01/01/01'))[0],
'amount' => 0,
'tender_type_id' => undef,
'debit_account_id' => $newdb{'lookup'}{'account'}{'Closing'}{'account_id'},
'debit_ledger_id' => $newdb{'lookup'}{'account'}{'Closing'}{'ledger_id'},
'credit_account_id' => $newdb{'lookup'}{'account'}{'A/R'}{'account_id'},
'credit_ledger_id' => $newdb{'lookup'}{'account'}{'A/R'}{'ledger_id'},
};
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
##
## UNITS
##
my @unit_sort_order =
qw(
A01 A02 A03 A04 A05 A06
B01 B02 B03 B04 B05 B06 B07
C01 C02 C03 C04 C05 C06 C07 C08 C09
10 11 12 13 14 15 16 17 18 19 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
D01 D02 D03 D04 D05 D06 D07 D08 D09 D10 D11
APT
Y01 Y02 Y03 Y04 Y05 Y06 Y07 Y08 Y09 Y10
);
my $unit_sort_order = 0;
my %unit_sort_order;
foreach (@unit_sort_order) {
$unit_sort_order += 1; # use 100 for later insertion
$unit_sort_order{$_} = $unit_sort_order;
}
my @unit_walk_order =
qw(
19 18 17 16 15 14 13 12 11 10
C01 C02 C03 C04 C05 C06 C07 C08 C09
APT
38 37 36 35 34 33 32 31 30 29 28
B01 B02 B03 B04 B05 B06 B07
A01 A02 A03 A04 A05 A06
27 26 25 24 23 22
D11 D10 D09 D08 D07 D06 D05 D04 D03 D02 D01
45 44 43 42 41 40 39
Y01 Y02 Y03 Y04 Y05 Y06 Y07 Y08 Y09 Y10
);
my $unit_walk_order = 0;
my %unit_walk_order;
foreach (@unit_walk_order) {
$unit_walk_order += 1; # use 100 for later insertion
$unit_walk_order{$_} = $unit_walk_order;
}
######################################################################
## Unit Types
$newdb{'lookup'}{'unit_type'} = {};
$query = "SELECT * FROM UnitType ORDER BY TypeID";
foreach $row (@{query($sdbh, $query)}) {
addRow('unit_types', {
'code' => 'xxx',
'name' => $row->{'UnitType'} });
$newdb{'lookup'}{'unit_type'}{$row->{'TypeID'}} =
$newdb{'tables'}{'unit_types'}{'autoid'};
}
######################################################################
## Unit Sizes
$newdb{'lookup'}{'unit_size'} = {};
$query = "SELECT * FROM UnitInfo WHERE UnitID <> 'POS\$' ORDER BY UnitID";
foreach $row (@{query($sdbh, $query)}) {
my $sz = sizeCode($row->{'Width'}, $row->{'Depth'});
next if defined $newdb{'lookup'}{'unit_size'}{$sz};
addRow('unit_sizes', {
'unit_type_id' => $row->{'Type'},
'code' => $sz,
'name' => $sz,
'width' => $internal_adjustment_factor * $row->{'Width'},
'depth' => $internal_adjustment_factor * $row->{'Depth'},
'deposit' => $row->{'StdSecDep'},
'rent' => $row->{'StdRent'} });
$newdb{'lookup'}{'unit_size'}{$sz}
= { 'id' => $newdb{'tables'}{'unit_sizes'}{'autoid'},
'rent' => $row->{'StdRent'},
'dep' => $row->{'StdSecDep'} };
}
######################################################################
## Units
$newdb{'lookup'}{'unit'} = {};
foreach $row (@{query($sdbh, $query)}) {
my $sz = sizeCode($row->{'Width'}, $row->{'Depth'});
my $szid = $newdb{'lookup'}{'unit_size'}{$sz}{'id'};
addRow('units', {
'unit_size_id' => $szid,
'code' => $row->{'UnitID'},
'name' => $row->{'UnitID'},
'status' => $row->{'Rented'} ?'OCCUPIED' :($row->{'Rentable'} ?'VACANT' :'UNAVAILABLE'),
'sort_order' => $unit_sort_order{$row->{'UnitID'}},
'walk_order' => $unit_walk_order{$row->{'UnitID'}},
'deposit' => $row->{'StdSecDep'},
'rent' => $row->{'StdRent'} });
$newdb{'lookup'}{'unit'}{$row->{'UnitID'}}
= { 'id' => $newdb{'tables'}{'units'}{'autoid'} };
}
######################################################################
## Map
my %info = ('extents' => {}, 'units' => {});
# Get the overall site limits
$query = "SELECT MIN(M.Top) AS mintop, MIN(M.Left) AS minlft,";
$query .= " MAX(M.Top + IIF(M.reverseWL, U.Width, U.Depth)) AS bot,";
$query .= " MAX(M.Left + IIF(M.reverseWL, U.Depth, U.Width)) AS rgt";
$query .= ' FROM UnitInfo U INNER JOIN mapUnitsV2 M ON M.unitID = U.UnitID';
$result = query($sdbh, $query);
# Fetch and verify the result
my $row = shift(@$result);
die("MIN query failed!") unless $row;
# Compute the actual boundaries, adjusting for a (0,0) origin
my $top_adjustment = 0 - $row->{'mintop'};
my $left_adjustment = 0 - $row->{'minlft'};
$info{'extents'}{'top'} = 0;
$info{'extents'}{'left'} = 0;
$info{'extents'}{'bottom'} = $internal_adjustment_factor * ($top_adjustment + $row->{'bot'} + 0);
$info{'extents'}{'right'} = $internal_adjustment_factor * ($left_adjustment + $row->{'rgt'} + 0);
addRow('maps', {
'name' => 'Main Facility Map',
'site_area_id' => $newdb{'tables'}{'site_areas'}{'autoid'},
'width' => $info{'extents'}{'right'} - $info{'extents'}{'left'},
'depth' => $info{'extents'}{'bottom'} - $info{'extents'}{'top'} });
# Get list of units and positions
$query = "SELECT U.UnitID, U.UnitID as name,";
$query .= " ($top_adjustment + M.Top) AS pt_t,";
$query .= " ($left_adjustment + M.Left) AS pt_l,";
$query .= " IIF(M.reverseWL, U.Depth, U.Width) AS Width,";
$query .= " IIF(M.reverseWL, U.Width, U.Depth) AS Depth,";
$query .= " M.reverseWL, U.Rented, U.Rentable";
$query .= " FROM UnitInfo U INNER JOIN mapUnitsV2 M ON M.unitID = U.UnitID";
# Go through each one, calculating the map location
foreach $row (@{query($sdbh, $query)}) {
addRow('maps_units', {
'map_id' => $newdb{'tables'}{'maps'}{'autoid'},
'unit_id' => $newdb{'lookup'}{'unit'}{$row->{'UnitID'}}{'id'},
'pt_top' => $internal_adjustment_factor * ($row->{'pt_t'}),
'pt_left' => $internal_adjustment_factor * ($row->{'pt_l'}),
'transpose' => $row->{'reverseWL'} });
}
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
##
## TENANTS
##
######################################################################
## Tenants
$newdb{'lookup'}{'tenant'} = {};
$query = "SELECT * FROM TenantInfo WHERE FirstName <> 'POS' ORDER BY TenantID";
foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}
= { 'name' => "$row->{'LastName'}, $row->{'FirstName'}" };
addRow('contacts', {
'first_name' => $row->{'FirstName'},
'middle_name' => $row->{'MiddleName'},
'last_name' => $row->{'LastName'},
'id_local' => $row->{'IDNum'} || undef,
'id_local_state' => $row->{'IDNum'} ? $newdb{'lookup'}{'state'}{$row->{'DLStateID'}} : undef });
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'} =
$newdb{'tables'}{'contacts'}{'autoid'};
addRow('customers', {
'name' => "$row->{'LastName'}, $row->{'FirstName'}",
'primary_contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'},
});
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'} =
$newdb{'tables'}{'customers'}{'autoid'};
addRow('contacts_customers', {
'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'},
'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'},
'type' => 'TENANT' },
1);
if ($row->{'City'}) {
addRow('contact_addresses', {
'address' => $row->{'HomeAddress'} . ($row->{'HomeAddr2'} ? "\n".$row->{'HomeAddr2'} : "") || undef,
'city' => $row->{'City'},
'state' => $newdb{'lookup'}{'state'}{$row->{'StateID'}},
'postcode' => $row->{'Zip'} || undef,
'country' => 'USA' });
addRow('contacts_methods', {
'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'},
'method_id' => $newdb{'tables'}{'contact_addresses'}{'autoid'},
'method' => 'ADDRESS',
'type' => 'HOME',
'preference' => 'PRIMARY' },
1);
}
foreach ({'type' => 'LANDLINE', 'preference' => 'PRIMARY', 'phone' => $row->{'Phone'}},
{'type' => 'LANDLINE', 'preference' => 'WORK',
'phone' => $row->{'BusinessPhone'}, 'ext' => $row->{'BusinessExt'}},
{'type' => 'FAX', 'preference' => 'PRIMARY', 'phone' => $row->{'FAX'}},
{'type' => 'PAGER', 'preference' => 'PRIMARY', 'phone' => $row->{'Pager'}},
{'type' => 'MOBILE', 'preference' => 'ALTERNATE', 'phone' => $row->{'CellPhone'}})
{
if ($_->{'phone'}) {
addRow('contact_phones', {
'type' => $_->{'type'},
'phone' => $_->{'phone'},
'ext' => $_->{'ext'} });
addRow('contacts_methods', {
'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'},
'method_id' => $newdb{'tables'}{'contact_phones'}{'autoid'},
'method' => 'PHONE',
'type' => 'MAIN',
'preference' => $_->{'preference'} },
1);
}
}
if ($row->{'Email'}) {
addRow('contact_emails', {
'email' => $row->{'Email'} });
addRow('contacts_methods', {
'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'},
'method_id' => $newdb{'tables'}{'contact_emails'}{'autoid'},
'method' => 'EMAIL',
'type' => 'MAIN',
'preference' => 'PRIMARY' },
1);
}
next unless $row->{'AltFirstName'} || $row->{'AltLastName'} || $row->{'AltAddress'} || $row->{'AltPhone'};
addRow('contacts', {
'first_name' => $row->{'AltFirstName'} || undef,
'middle_name' => $row->{'AltMI'} || undef,
'last_name' => $row->{'AltLastName'} || undef });
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'alt'} =
$newdb{'tables'}{'contacts'}{'autoid'};
addRow('contacts_customers', {
'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'},
'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'alt'},
'type' => 'ALTERNATE' },
1);
if ($row->{'AltCity'}) {
addRow('contact_addresses', {
'address' => $row->{'AltAddress'} . ($row->{'AltAddr2'} ? "\n".$row->{'AltAddr2'} : ""),
'city' => $row->{'AltCity'},
'state' => $newdb{'lookup'}{'state'}{$row->{'AltStateID'}},
'postcode' => $row->{'AltZip'},
'country' => 'USA' });
addRow('contacts_methods', {
'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'alt'},
'method_id' => $newdb{'tables'}{'contact_addresses'}{'autoid'},
'method' => 'ADDRESS',
'type' => 'MAIN',
'preference' => 'PRIMARY' },
1);
}
if ($row->{'AltPhone'}) {
addRow('contact_phones', {
'type' => 'LANDLINE',
'phone' => $row->{'AltPhone'},
'ext' => undef });
addRow('contacts_methods', {
'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'alt'},
'method_id' => $newdb{'tables'}{'contact_phones'}{'autoid'},
'method' => 'PHONE',
'type' => 'MAIN',
'preference' => 'PRIMARY' },
1);
}
}
######################################################################
## Tenant Leases
$newdb{'lookup'}{'ledger'} = {};
$query = "SELECT L.*, A.TenantID FROM TenantLedger L LEFT JOIN `Access` A ON A.LedgerID = L.LedgerID WHERE L.UnitID <> 'POS\$' ORDER BY L.DateIn";
foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}
= { 'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'},
'lease_date' => $row->{'DateIn'},
};
addRow('leases', {
'number' => $newdb{'tables'}{'leases'}{'autoid'}+1,
#'number' => $row->{'LedgerID'},
'lease_type_id' => $newdb{'tables'}{'lease_types'}{'autoid'},
'unit_id' => $newdb{'lookup'}{'unit'}{$row->{'UnitID'}}{'id'},
'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'},
'lease_date' => datefmt($row->{'DateIn'}),
'movein_date' => datefmt($row->{'DateIn'}),
'moveout_date' => datefmt($row->{'DateOut'}),
#'close_date' => datefmt($row->{'DateClosed'}),
'rent' => $row->{'Rent'},
#'comment' => "LedgerID: $row->{'LedgerID'}",
});
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'lease_id'} =
$newdb{'tables'}{'leases'}{'autoid'};
}
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
##
## INVOICES
##
######################################################################
## Invoices
$newdb{'lookup'}{'charge'} = {};
$query = "SELECT *, ChargeAmount+TaxAmount AS InvoiceAmount FROM Charges ORDER BY ChargeID";
foreach $row (@{query($sdbh, $query)}) {
my ($stamp, $effective_date, $through_date) =
dates('invoice', $row->{'ChargeDate'}, $row->{'EndDate'},
$row->{'ChargeDescription'}, $row->{'LedgerID'});
addRow('transactions', {
'type' => 'INVOICE',
'stamp' => $stamp,
'customer_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'customer_id'},
'account_id' => $newdb{'lookup'}{'account'}{'A/R'}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{'A/R'}{'ledger_id'},
'crdr' => 'DEBIT',
#'amount' => $row->{'InvoiceAmount'},
#'comment' => "Invoice Transaction",
});
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}
= { 'invoice' => {'id' => $newdb{'tables'}{'transactions'}{'autoid'},
'amount' => $row->{'InvoiceAmount'} },
};
# Charges are the only way we have to figure out security
# deposit requirements for a lease. So, if we encounter
# a security deposit charge, update the lease to reflect.
if ($row->{'ChargeDescription'} eq 'Security Deposit') {
$newdb{'tables'}{'leases'}{'rows'}[
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'lease_id'}
]{'deposit'} = $row->{'ChargeAmount'};
}
}
######################################################################
## Charges
$query = "SELECT * FROM Charges ORDER BY ChargeID";
foreach $row (@{query($sdbh, $query)}) {
my (undef, $effective_date, $through_date) =
dates('charge', $row->{'ChargeDate'}, $row->{'EndDate'},
$row->{'ChargeDescription'}, $row->{'LedgerID'});
# Fix Brenda Harmon bug
$row->{'ChargeAmount'} = 50
if ($row->{'ChargeID'} == 19);
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'amount'}
= $row->{'ChargeAmount'};
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'}
= $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'customer_id'},
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'}
= $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'lease_id'};
# Charge must credit the Charge ledger...
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'credit_account_id'}
= $newdb{'lookup'}{'charge_type'}{$row->{'ChargeDescription'}}{'account_id'};
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'credit_ledger_id'}
= $newdb{'lookup'}{'charge_type'}{$row->{'ChargeDescription'}}{'ledger_id'};
# ...and debit the A/R ledger.
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'debit_account_id'}
= $newdb{'lookup'}{'account'}{'A/R'}{'account_id'};
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'debit_ledger_id'}
= $newdb{'lookup'}{'account'}{'A/R'}{'ledger_id'};
# debit: A/R credit: Rent/LateCharge/Etc
foreach ('debit', 'credit') {
my $CRDR = $_;
$CRDR =~ tr/a-z/A-Z/;
addRow('ledger_entries', {
'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'id'},
'account_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{$_.'_account_id'},
'ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{$_.'_ledger_id'},
'crdr' => $CRDR,
'amount' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'amount'},
#'comment' => "$_ Ledger Entry: $row->{'ChargeID'}; Ledger: $row->{'LedgerID'}",
});
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{$_.'_entry_id'}
= $newdb{'tables'}{'ledger_entries'}{'autoid'};
}
addRow('double_entries', {
#'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'id'},
'debit_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'debit_entry_id'},
'credit_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'credit_entry_id'},
#'comment' => "Double Entry: $row->{'ChargeID'}; Ledger: $row->{'LedgerID'}",
});
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'double_entry_id'}
= $newdb{'tables'}{'double_entries'}{'autoid'};
# Add the Charge Statement Entry
addRow('statement_entries', {
'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'id'},
'type' => 'CHARGE',
'effective_date' => $effective_date,
'through_date' => $through_date,
'customer_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'},
'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'},
'account_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'credit_account_id'},
'amount' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'amount'},
#'comment' => "Charge: $row->{'ChargeID'}; Ledger: $row->{'LedgerID'}",
});
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'statement_entry_id'}
= $newdb{'tables'}{'statement_entries'}{'autoid'};
next unless $row->{'TaxAmount'};
# # Add the tax charge entry
# # debit: Invoice credit: Tax
# addRow('ledger_entries',
# { 'effective_date' => $effective_date,
# 'through_date' => $through_date,
# 'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'id'},
# 'debit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'debit_ledger_id'},
# 'credit_ledger_id' => $newdb{'lookup'}{'account'}{'Tax'}{'ledger_id'},
# 'amount' => $row->{'TaxAmount'},
# #'comment' => "Tax for ChargeID:$row->{'ChargeID'}",
# });
# $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tax_ledger_entry_id'}
# = $newdb{'tables'}{'ledger_entries'}{'autoid'};
}
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
######################################################################
##
## RECEIPTS
##
######################################################################
## Receipts
$newdb{'lookup'}{'receipt'} = {};
# Sitelink splits one physical payment into multiple "payments" to match each charge.
# The solution here is kludgy, but for our cases at least, it brings those pseudo-payments
# back into a single one. This presumes there is only one PaymentType per receipt.
$query =
"SELECT R.ReceiptNum, R.ReceiptDate, P.PaymentType, P.CheckNum, SUM(P.PaymentAmount) AS ReceiptAmount" .
" FROM Receipts R, Payments P" .
" WHERE P.ReceiptNum = R.ReceiptNum" .
" GROUP BY R.ReceiptNum, R.ReceiptDate, P.PaymentType, P.CheckNum" .
" ORDER BY R.ReceiptNum, P.PaymentType";
# print Dumper query($sdbh, $query);
# exit;
foreach $row (@{query($sdbh, $query)}) {
# if ($newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'}) {
# next;
# }
my ($stamp, $effective_date, $through_date) =
dates('receipt', $row->{'ReceiptDate'}, undef);
if ($newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}) {
print Dumper $newdb{'lookup'}{'receipt'};
print Dumper $row;
die "REALLY?";
}
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}
= { 'date' => $stamp,
'effective_date' => $effective_date,
'through_date' => $through_date,
'amount' => $row->{'ReceiptAmount'},
};
if ($stamp eq $newdb{'lookup'}{'_closing'}{'stamp'}) {
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'name'}
= $newdb{'lookup'}{'_closing'}{'name'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'tender_type_id'}
= $newdb{'lookup'}{'_closing'}{'tender_type_id'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'debit_account_id'}
= $newdb{'lookup'}{'_closing'}{'debit_account_id'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'debit_ledger_id'}
= $newdb{'lookup'}{'_closing'}{'debit_ledger_id'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_account_id'}
= $newdb{'lookup'}{'_closing'}{'credit_account_id'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_ledger_id'}
= $newdb{'lookup'}{'_closing'}{'credit_ledger_id'};
$newdb{'lookup'}{'_closing'}{'amount'} +=
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'amount'};
if ($newdb{'lookup'}{'_closing'}{'transaction_id'}) {
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'receipt_id'} =
$newdb{'lookup'}{'_closing'}{'transaction_id'};
next;
}
}
else {
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'name'}
= $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'name'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'tender_type_id'}
= $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'tender_type_id'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'debit_account_id'}
= $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'account_id'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'debit_ledger_id'}
= $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'ledger_id'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_account_id'}
= $newdb{'lookup'}{'account'}{'A/R'}{'account_id'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_ledger_id'}
= $newdb{'lookup'}{'account'}{'A/R'}{'ledger_id'};
if ($SITELINK_ACCOUNT_TYPE{$row->{'PaymentType'}} eq 'Check') {
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'data1'}
= $row->{'CheckNum'};
}
}
addRow('transactions', {
'type' => 'RECEIPT',
'stamp' => $stamp,
'customer_id' => undef, # Must be set later
'account_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_account_id'},
'ledger_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_ledger_id'},
'crdr' => 'CREDIT',
#'comment' => "Receipt: $row->{'ReceiptNum'}; Type: $row->{'PaymentType'}",
});
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'receipt_id'}
= $newdb{'tables'}{'transactions'}{'autoid'};
# Receipt must debit the "money" asset (bank, cash, check, etc)...
# ...and credit the A/R ledger
# (These were set above, based on whether part of closing or not)
foreach ('debit', 'credit') {
my $CRDR = $_;
$CRDR =~ tr/a-z/A-Z/;
addRow('ledger_entries', {
'transaction_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'receipt_id'},
'account_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{$_.'_account_id'},
'ledger_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{$_.'_ledger_id'},
'crdr' => $CRDR,
'amount' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'amount'},
#'comment' => "$_ Entry Receipt: $row->{'ReceiptNum'}; Type: $row->{'PaymentType'}",
});
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{$_.'_entry_id'}
= $newdb{'tables'}{'ledger_entries'}{'autoid'};
}
addRow('double_entries', {
#'transaction_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'receipt_id'},
'debit_entry_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'debit_entry_id'},
'credit_entry_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_entry_id'},
#'comment' => "Double Entry: $row->{'ReceiptNum'}; Type: $row->{'PaymentType'}",
});
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'double_entry_id'}
= $newdb{'tables'}{'double_entries'}{'autoid'};
# Add the physical payment
addRow('tenders', {
'ledger_entry_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'debit_entry_id'},
'name' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'name'},
'tender_type_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'tender_type_id'},
'data1' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'data1'},
#'comment' => "Physical Payment: $row->{'ReceiptNum'}; Type: $row->{'PaymentType'}",
});
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'tender_id'}
= $newdb{'tables'}{'tenders'}{'autoid'};
# Special case for closing
if ($closing_one_transaction && $stamp eq $newdb{'lookup'}{'_closing'}{'stamp'}) {
$newdb{'lookup'}{'_closing'}{'transaction_id'} =
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'receipt_id'};
$newdb{'lookup'}{'_closing'}{'debit_entry_id'} =
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'debit_entry_id'};
$newdb{'lookup'}{'_closing'}{'credit_entry_id'} =
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_entry_id'};
$newdb{'lookup'}{'_closing'}{'tender_id'} =
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'tender_id'};
}
}
######################################################################
## Payments to Charges assignments
$newdb{'lookup'}{'payment'} = {};
$query = "SELECT * FROM Payments ORDER BY PaymentID";
foreach $row (@{query($sdbh, $query)})
{
my (undef, $effective_date, $through_date) =
dates('payment', $row->{'PaymentDate'});
# Figure out how much of the charge can be reconciled
my $charge_amount = $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'amount'};
my $payment_amount = $row->{'PaymentAmount'};
my $reconcile_amount = ($charge_amount < $payment_amount) ? $charge_amount : $payment_amount;
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}
= { 'receipt_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'receipt_id'},
'tender_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'tender_id'},
# 'effective_date' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'effective_date'},
# 'effective_date' => $effective_date;
# 'through_date' => $through_date;
'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'},
'customer_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'},
'amount' => $reconcile_amount,
'account_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'debit_account_id'},
};
# Update the receipt & tender customer_id, now that we have payment info
$newdb{'tables'}{'transactions'}{'rows'}[
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'receipt_id'}
]{'customer_id'} = $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'customer_id'};
$newdb{'tables'}{'tenders'}{'rows'}[
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'tender_id'}
]{'customer_id'} = $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'customer_id'};
# Use the Memo as our comment, if it exists
my $comment = $row->{'Memo'}
#|| "Payment: $row->{'ReceiptNum'}; Type: $row->{'PaymentType'}; Charge: $row->{'ChargeID'}"
;
# Add the Payment Statement Entry
addRow('statement_entries', {
'transaction_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'receipt_id'},
'type' => 'DISBURSEMENT',
# 'effective_date' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'effective_date'},
# 'through_date' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'through_date'},
'effective_date' => $effective_date,
'through_date' => $through_date,
'customer_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'customer_id'},
'lease_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'lease_id'},
'account_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'account_id'},
'amount' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'amount'},
'charge_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'statement_entry_id'},
'comment' => $comment,
});
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'statement_entry_id'}
= $newdb{'tables'}{'statement_entries'}{'autoid'};
}
######################################################################
## Special case - Fix the entries for our closing transaction
if ($newdb{'lookup'}{'_closing'}{'debit_entry_id'}) {
$newdb{'tables'}{'ledger_entries'}{'rows'}[
$newdb{'lookup'}{'_closing'}{'debit_entry_id'}
]{'amount'} = $newdb{'lookup'}{'_closing'}{'amount'};
}
if ($newdb{'lookup'}{'_closing'}{'credit_entry_id'}) {
$newdb{'tables'}{'ledger_entries'}{'rows'}[
$newdb{'lookup'}{'_closing'}{'credit_entry_id'}
]{'amount'} = $newdb{'lookup'}{'_closing'}{'amount'};
}
######################################################################
## Special case - Equities / Loans / Petty Cash
my ($stamp, $effective_date, $through_date);
print("Set up Petty Cash...\n");
# Add the first loan
# debit: Equity credit: Loan
addRow('transactions', {
'type' => 'TRANSFER',
'stamp' => datefmt('03/25/2009 16:00'),
'account_id' => $newdb{'lookup'}{'account'}{'Equity'}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{'Equity'}{'ledger_id'},
'crdr' => 'DEBIT',
'comment' => "HTP Loan #1",
});
addRow('ledger_entries', {
'transaction_id' => $newdb{'tables'}{'transactions'}{'autoid'},
'account_id' => $newdb{'lookup'}{'account'}{'Equity'}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{'Equity'}{'ledger_id'},
'crdr' => 'DEBIT',
'amount' => 5000,
'comment' => "Equity: HTP Loan #1",
});
addRow('ledger_entries', {
'transaction_id' => $newdb{'tables'}{'transactions'}{'autoid'},
'account_id' => $newdb{'lookup'}{'account'}{'Loan'}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{'Loan'}{'ledger_id'},
'crdr' => 'CREDIT',
'amount' => 5000,
'comment' => "Loan: HTP Loan #1",
});
addRow('double_entries', {
'debit_entry_id' => $newdb{'tables'}{'ledger_entries'}{'autoid'}-1,
'credit_entry_id' => $newdb{'tables'}{'ledger_entries'}{'autoid'},
});
# Add the second loan
# debit: Equity credit: Loan
addRow('transactions', {
'type' => 'TRANSFER',
'stamp' => datefmt('04/01/2009 16:00'),
'account_id' => $newdb{'lookup'}{'account'}{'Equity'}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{'Equity'}{'ledger_id'},
'crdr' => 'DEBIT',
'comment' => "HTP Loan #2",
});
addRow('ledger_entries', {
'transaction_id' => $newdb{'tables'}{'transactions'}{'autoid'},
'account_id' => $newdb{'lookup'}{'account'}{'Equity'}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{'Equity'}{'ledger_id'},
'crdr' => 'DEBIT',
'amount' => 1000,
'comment' => "Equity: HTP Loan #2",
});
addRow('ledger_entries', {
'transaction_id' => $newdb{'tables'}{'transactions'}{'autoid'},
'account_id' => $newdb{'lookup'}{'account'}{'Loan'}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{'Loan'}{'ledger_id'},
'crdr' => 'CREDIT',
'amount' => 1000,
'comment' => "Loan: HTP Loan #2",
});
addRow('double_entries', {
'debit_entry_id' => $newdb{'tables'}{'ledger_entries'}{'autoid'}-1,
'credit_entry_id' => $newdb{'tables'}{'ledger_entries'}{'autoid'},
});
# Cheat for now, using equity for Petty Cash
# debit: Petty Cash credit: Equity
addRow('transactions', {
'type' => 'TRANSFER',
'stamp' => datefmt('03/25/2009 16:00'),
'account_id' => $newdb{'lookup'}{'account'}{'Petty Cash'}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{'Petty Cash'}{'ledger_id'},
'crdr' => 'DEBIT',
'comment' => "Petty Cash Funding",
});
addRow('ledger_entries', {
'transaction_id' => $newdb{'tables'}{'transactions'}{'autoid'},
'account_id' => $newdb{'lookup'}{'account'}{'Petty Cash'}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{'Petty Cash'}{'ledger_id'},
'crdr' => 'DEBIT',
'amount' => 750,
'comment' => "Petty Cash: Petty Cash Funding",
});
addRow('ledger_entries', {
'transaction_id' => $newdb{'tables'}{'transactions'}{'autoid'},
'account_id' => $newdb{'lookup'}{'account'}{'Equity'}{'account_id'},
'ledger_id' => $newdb{'lookup'}{'account'}{'Equity'}{'ledger_id'},
'crdr' => 'CREDIT',
'amount' => 750,
'comment' => "Equity: Petty Cash Funding",
});
addRow('double_entries', {
'debit_entry_id' => $newdb{'tables'}{'ledger_entries'}{'autoid'}-1,
'credit_entry_id' => $newdb{'tables'}{'ledger_entries'}{'autoid'},
});
######################################################################
## Debug ... work from scratch
if ($work_from_scratch) {
# delete $newdb{'tables'}{'contacts'}{'rows'};
# delete $newdb{'tables'}{'contacts_methods'}{'rows'};
# delete $newdb{'tables'}{'contacts_addresses'}{'rows'};
# delete $newdb{'tables'}{'contacts_emails'}{'rows'};
# delete $newdb{'tables'}{'contacts_phones'}{'rows'};
delete $newdb{'tables'}{'contacts_customers'}{'rows'};
delete $newdb{'tables'}{'customers'}{'rows'};
delete $newdb{'tables'}{'double_entries'}{'rows'};
delete $newdb{'tables'}{'leases'}{'rows'};
delete $newdb{'tables'}{'ledger_entries'}{'rows'};
delete $newdb{'tables'}{'statement_entries'}{'rows'};
delete $newdb{'tables'}{'tenders'}{'rows'};
delete $newdb{'tables'}{'transactions'}{'rows'};
foreach (@{$newdb{'tables'}{'units'}{'rows'}}) {
$_->{'status'} = 'VACANT'
if defined $_ && ($_->{'status'} =~ /^(OCCUPIED)$/ || $_->{'name'} =~ /^Y/);
}
}
######################################################################
## Build the Database
$Data::Dumper::Sortkeys = 1;
# print Dumper \%newdb;
# exit;
buildTables();
######################################################################
## Special cases - Name corrections
print("Special Cases...\n");
$query =
"UPDATE pmgr_contacts" .
" SET first_name = 'Krystan'" .
" WHERE first_name = 'Kristan' AND last_name = 'Mancini'";
query($db_handle, $query);
$query =
"UPDATE pmgr_customers" .
" SET name = 'Mancini, Krystan'" .
" WHERE name = 'Mancini, Kristan'";
query($db_handle, $query);
$query =
"UPDATE pmgr_contacts" .
" SET first_name = NULL, last_name = NULL, company_name = 'Valley Bible Church'" .
" WHERE first_name = 'VBC' AND last_name = 'Tenant'";
query($db_handle, $query);
$query =
"UPDATE pmgr_customers" .
" SET name = 'Valley Bible Church'" .
" WHERE name = 'Tenant, VBC'";
query($db_handle, $query);
######################################################################
## Contact Display Names
print("Set Contact Display Names...\n");
$query =
"UPDATE pmgr_contacts".
" SET display_name =" .
" IF(first_name IS NOT NULL AND last_name IS NOT NULL," .
" CONCAT(last_name, ', ', first_name)," .
" IF(first_name IS NOT NULL, first_name, last_name))";
query($db_handle, $query);
######################################################################
## Unit Lease Assignments
print("Set Current Leases...\n");
$query = "UPDATE pmgr_units U, pmgr_leases L
SET U.`current_lease_id` = L.id
WHERE L.unit_id = U.id AND L.close_date IS NULL";
query($db_handle, $query);
# All current_lease_counts will be zero at the moment, since
# everything was just created. This will update any customers
# that have ever leased anything.
$query = "UPDATE pmgr_customers C,
(SELECT L.customer_id,
SUM(IF(L.close_date IS NULL, 1, 0)) AS current,
SUM(IF(L.close_date IS NULL, 0, 1)) AS closed
FROM pmgr_leases L
GROUP BY L.customer_id) AS X
SET C.`lease_count` = X.current + X.closed,
C.`current_lease_count` = X.current,
C.`past_lease_count` = X.closed
WHERE X.customer_id = C.id";
query($db_handle, $query);
######################################################################
## Invoice/Receipt totals
print("Set Invoice/Receipt Totals...\n");
$query = "UPDATE pmgr_transactions T, pmgr_ledger_entries E
SET T.`amount` = COALESCE(T.`amount`,0) + E.amount
WHERE E.transaction_id = T.id AND E.account_id = T.account_id";
query($db_handle, $query);
######################################################################
## Tender Names
print("Set Tender Names...\n");
$query = "UPDATE pmgr_tenders T, pmgr_tender_types TT
SET T.`name` = CONCAT(T.`name`, ' #',
IF(T.tender_type_id IN (2,3), T.data1, T.id))
WHERE T.tender_type_id IS NULL OR TT.id = T.tender_type_id";
query($db_handle, $query);
######################################################################
## Invoice date fixes
# print("Fix Invoice Dates...\n");
# $query = "UPDATE pmgr_transactions T, pmgr_statement_entries E
# SET T.`stamp` =
# WHERE E.transaction_id = T.id AND E.account_id = T.account_id";
# query($db_handle, $query);