[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
SF.net SVN: ledger-smb:[2733] trunk
- Subject: SF.net SVN: ledger-smb:[2733] trunk
- From: ..hidden..
- Date: Wed, 15 Jul 2009 20:20:25 +0000
Revision: 2733
http://ledger-smb.svn.sourceforge.net/ledger-smb/?rev=2733&view=rev
Author: einhverfr
Date: 2009-07-15 20:20:24 +0000 (Wed, 15 Jul 2009)
Log Message:
-----------
David Mora's overpayment fixes
Modified Paths:
--------------
trunk/LedgerSMB/AM.pm
trunk/LedgerSMB/DBObject/Company.pm
trunk/LedgerSMB/DBObject/Payment.pm
trunk/LedgerSMB/DBObject.pm
trunk/LedgerSMB/ScriptLib/Company.pm
trunk/LedgerSMB/Setting.pm
trunk/LedgerSMB/User.pm
trunk/LedgerSMB/Vendor.pm
trunk/LedgerSMB.pm
trunk/UI/am-defaults.html
trunk/UI/payments/payment2.html
trunk/bin/am.pl
trunk/scripts/customer.pl
trunk/scripts/payment.pl
trunk/sql/Pg-database.sql
trunk/sql/modules/Payment.sql
Added Paths:
-----------
trunk/UI/payments/use_overpayment1.html
trunk/UI/payments/use_overpayment2.html
Modified: trunk/LedgerSMB/AM.pm
===================================================================
--- trunk/LedgerSMB/AM.pm 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/LedgerSMB/AM.pm 2009-07-15 20:20:24 UTC (rev 2733)
@@ -1630,8 +1630,10 @@
the corresponding name. inventory_accno_id is the id of the account with the
number specified in $form->{IC}. In a similar manner, income_accno_id and
$form->{IC_income}, expense_accno_id and $form->{IC_expense}, fxgain_accno_id
-and $form->{FX_gain}, and fxloss_accno_id and $form->{FX_loss} are related.
+and $form->{FX_gain}, and fxloss_accno_id and $form->{FX_loss} are related.
+Stores the templates directory for a specific company on defaults table.
+
=cut
sub save_defaults {
@@ -1646,13 +1648,11 @@
$form->{curr} =~ s/ //g;
for ( split /:/, $form->{curr} ) { push( @a, uc pack "A3", $_ ) if $_ }
$form->{curr} = join ':', @a;
-
# connect to database
my $dbh = $form->{dbh};
-
# save defaults
- $sth_plain = $dbh->prepare( "
- UPDATE defaults SET value = ? WHERE setting_key = ?" );
+# $sth_plain = $dbh->prepare( "
+# UPDATE defaults SET value = ? WHERE setting_key = ?" );
$sth_accno = $dbh->prepare(
qq|
UPDATE defaults
@@ -1673,11 +1673,11 @@
fxgain_accno_id fxloss_accno_id glnumber sinumber vinumber
sonumber ponumber sqnumber rfqnumber partnumber employeenumber
customernumber vendornumber projectnumber yearend curr
- weightunit businessnumber default_country check_prefix password_duration)
+ weightunit businessnumber default_country check_prefix password_duration templates)
+
)
{
my $val = $form->{$_};
-
if ( $translation{$_} ) {
$val = $form->{ $translation{$_} };
}
@@ -2284,8 +2284,32 @@
$sth->finish;
$self->defaultaccounts( undef, $form );
$dbh->commit;
+ my $dirname = "./templates";
+ my $subdircount = 0;
}
+=item AM->get_templates_directories;
+
+This functions gets all the directories from $LedgerSMB::Sysconfig::templates to list all the possible
+non-Ui templates.
+
+=cut
+sub get_templates_directories {
+my ( $self, $form ) = @_;
+my $subdircount = 0;
+my @dirarray;
+opendir ( DIR, $LedgerSMB::Sysconfig::templates) || $form->error("Error while opening file: ./".$LedgerSMB::Sysconfig::templates);
+while( (my $name = readdir(DIR))){
+ next if ($name =~ /\./);
+ if (-d $LedgerSMB::Sysconfig::templates.'/'.$name) {
+ $dirarray[$subdircount++] = $name;
+ }
+}
+closedir(DIR);
..hidden..>{templates_directories}} = @dirarray;
+}
+
+
1;
=back
Modified: trunk/LedgerSMB/DBObject/Company.pm
===================================================================
--- trunk/LedgerSMB/DBObject/Company.pm 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/LedgerSMB/DBObject/Company.pm 2009-07-15 20:20:24 UTC (rev 2733)
@@ -158,7 +158,14 @@
for my $ref (@{$self->{cash_acc_list}}){
$ref->{text} = "$ref->{accno}--$ref->{description}";
}
+
+ @{$self->{discount_acc_list}} =
+ $self->exec_method(funcname => 'chart_list_discount');
+ for my $ref (@{$self->{discount_acc_list}}){
+ $ref->{text} = "$ref->{accno}--$ref->{description}";
+ }
+
@{$self->{location_class_list}} =
$self->exec_method(funcname => 'location_list_class');
Modified: trunk/LedgerSMB/DBObject/Payment.pm
===================================================================
--- trunk/LedgerSMB/DBObject/Payment.pm 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/LedgerSMB/DBObject/Payment.pm 2009-07-15 20:20:24 UTC (rev 2733)
@@ -269,6 +269,28 @@
=over
+=item $payment->get_open_invoice()
+
+This function is an especific case of get_open_invoices(), because get_open_invoice()
+can search for a specific invoice, wich can be searched by the $payment->{invnumber}
+variable
+
+=back
+
+=cut
+
+sub get_open_invoice {
+ my ($self) = @_;
+ @{$self->{open_invoice}} =
+ $self->exec_method(funcname => 'payment_get_open_invoice');
+ return @{$self->{open_invoice}};
+}
+
+
+
+
+=over
+
=item $payment->get_all_contact_invoices()
This function returns a list of open accounts depending on the
@@ -396,8 +418,10 @@
=item get_open_currencies
This method gets a list of the open currencies inside the database, it requires that
-$self->{account_class} (must be 1 or 2) exist to work.
+$self->{account_class} (must be 1 or 2) exist to work.
+WARNING THIS IS NOT BEEING USED BY THE SINGLE PAYMENT SYSTEM....
+
=back
=cut
@@ -414,7 +438,7 @@
=item list_accounting
This method lists all accounts that match the role specified in account_class property and
-are availible to store the payment or receipts.
+are available to store the payment or receipts.
=back
=cut
@@ -427,7 +451,7 @@
=item list_overpayment_accounting
This method lists all accounts that match the role specified in account_class property and
-are availible to store an overpayment / advanced payment / pre-payment.
+are available to store an overpayment / advanced payment / pre-payment.
=back
=cut
@@ -501,9 +525,12 @@
=cut
sub get_vc_info {
- my ($self) = @_;
- @{$self->{vendor_customer_info}} = $self->exec_method(funcname => 'payment_get_vc_info');
- return @{$self->{vendor_customer_info}};
+ my ($self) = @_;
+ my $temp = $self->{"id"};
+ $self->{"id"} = $self->{"entity_credit_id"};
+ @{$self->{vendor_customer_info}} = $self->exec_method(funcname => 'company_get_billing_info');
+ $self->{"id"} = $temp;
+ return ${$self->{vendor_customer_info}}[0];
}
=item get_payment_detail_data
@@ -676,9 +703,8 @@
@{$self->{line_info}} = $self->exec_method(funcname => 'payment_gather_line_info');
}
+=item get_open_overpayment_entities
-=item get_open_overpayment_entities
-
This method retrieves all the entities with the specified
account_class which have unused overpayments
@@ -687,21 +713,19 @@
sub get_open_overpayment_entities {
my ($self) = @_;
@{$self->{open_overpayment_entities}} = $self->exec_method(funcname => 'payment_get_open_overpayment_entities');
-return @{$self->{open_overpayment_entities}};
+return @{$self->{open_overpayment_entities}};
}
sub get_unused_overpayments {
my ($self) = @_;
@{$self->{unused_overpayment}} = $self->exec_method(funcname => 'payment_get_unused_overpayment');
-return @{$self->{unused_overpayment}};
+return @{$self->{unused_overpayment}};
}
-sub get_availible_overpayment_amount {
+sub get_available_overpayment_amount {
my ($self) = @_;
..hidden..>{availible_overpayment_amount}} = $self->exec_method(funcname => 'payment_get_availible_overpayment_amount');
-return @{$self->{availible_overpayment_amount}};
..hidden..>{available_overpayment_amount}} = $self->exec_method(funcname => 'payment_get_available_overpayment_amount');
+return @{$self->{available_overpayment_amount}};
}
-
-
1;
Modified: trunk/LedgerSMB/DBObject.pm
===================================================================
--- trunk/LedgerSMB/DBObject.pm 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/LedgerSMB/DBObject.pm 2009-07-15 20:20:24 UTC (rev 2733)
@@ -101,6 +101,7 @@
my $funcname = $args{funcname};
my @in_args;
@in_args = @{ $args{args}} if $args{args};
+
my @call_args;
my $query = "
@@ -130,6 +131,7 @@
$ref->{pronargs} = 0 unless defined $ref->{pronargs};
# If the user provided args..
if (!defined $args{args}) {
+
@proc_args = $self->_parse_array($pargs);
if (@proc_args) {
for my $arg (@proc_args) {
Modified: trunk/LedgerSMB/ScriptLib/Company.pm
===================================================================
--- trunk/LedgerSMB/ScriptLib/Company.pm 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/LedgerSMB/ScriptLib/Company.pm 2009-07-15 20:20:24 UTC (rev 2733)
@@ -85,11 +85,10 @@
my ($request) = @_;
my $company = new_company($request);
-
set_entity_class($company);
$company->get();
$company->get_credit_id();
- $company->get_metadata();
+# $company->get_metadata(); It will be called from _render_main_screen
_render_main_screen($company);
}
@@ -410,6 +409,7 @@
sub edit{
my $request = shift @_;
my $company = LedgerSMB::DBObject::Vendor->new({base => $request});
+
$company->get();
_render_main_screen($company);
}
Modified: trunk/LedgerSMB/Setting.pm
===================================================================
--- trunk/LedgerSMB/Setting.pm 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/LedgerSMB/Setting.pm 2009-07-15 20:20:24 UTC (rev 2733)
@@ -166,8 +166,8 @@
sub get_currencies {
my $self = shift;
- $self->{settig__get_currencies} = $self->exec_method(funcname => 'setting__get_currencies');
- # @{$self->{currencies}} = $self->_parse_array($ref->{setting__get_currencies});
+ my @data = $self->exec_method(funcname => 'setting__get_currencies');
+ $self->{currencies} = $data[0]->{setting__get_currencies};
return @{$self->{currencies}};
}
-
+
Modified: trunk/LedgerSMB/User.pm
===================================================================
--- trunk/LedgerSMB/User.pm 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/LedgerSMB/User.pm 2009-07-15 20:20:24 UTC (rev 2733)
@@ -184,7 +184,6 @@
my $sth = $dbh->prepare($query);
$sth->execute($lsmb->{login});
$myconfig = $sth->fetchrow_hashref(NAME_lc);
-
return $myconfig;
}
Modified: trunk/LedgerSMB/Vendor.pm
===================================================================
--- trunk/LedgerSMB/Vendor.pm 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/LedgerSMB/Vendor.pm 2009-07-15 20:20:24 UTC (rev 2733)
@@ -10,7 +10,7 @@
# this is a fairly effective way of telling if we need to create a new
# entity or not.
-
+
if (!$self->{entity_id}) {
$entity = LedgerSMB::Entity->new(base=>$request);
Modified: trunk/LedgerSMB.pm
===================================================================
--- trunk/LedgerSMB.pm 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/LedgerSMB.pm 2009-07-15 20:20:24 UTC (rev 2733)
@@ -99,8 +99,14 @@
Removes all elements starting with a . because these elements conflict with the
ability to hide the entire structure for things like CSV lookups.
+= item get_default_value_by_key($key)
+
+Retrieves a default value for the given key, it is just a wrapper on LedgerSMB::Setting;
+
=back
+
+
=head1 Copyright (C) 2006, The LedgerSMB core team.
# This work contains copyrighted information from a number of sources
@@ -135,6 +141,7 @@
use LedgerSMB::Template;
use LedgerSMB::Locale;
use LedgerSMB::User;
+use LedgerSMB::Setting;
use strict;
$CGI::Simple::POST_MAX = -1;
@@ -927,6 +934,16 @@
return $return_hash;
}
+
+
+sub get_default_value_by_key
+{
+ my ($self, $key) = @_;
+ my $Settings = LedgerSMB::Setting->new({base => $self, copy => 'base'});
+ $Settings->{key} = $key;
+ $Settings->get;
+ $Settings->{value};
+}
1;
Modified: trunk/UI/am-defaults.html
===================================================================
--- trunk/UI/am-defaults.html 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/UI/am-defaults.html 2009-07-15 20:20:24 UTC (rev 2733)
@@ -75,6 +75,12 @@
<?lsmb PROCESS select element_data=selects.default_country ?>
</td>
</tr>
+ <tr>
+ <th align="right" nowrap="nowrap"><?lsmb text('Templates directory') ?></th>
+ <td>
+<?lsmb PROCESS select element_data=selects.templates ?>
+ </td>
+ </tr>
</table>
</td>
</tr>
Modified: trunk/UI/payments/payment2.html
===================================================================
--- trunk/UI/payments/payment2.html 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/UI/payments/payment2.html 2009-07-15 20:20:24 UTC (rev 2733)
@@ -164,7 +164,9 @@
<td align="center"><?lsmb row.memo.id=row.memo.name ; INCLUDE input element_data=row.memo; -?></td>
<?lsmb IF defaultcurrency.text != curr.value ?>
<td><?lsmb row.exchange_rate ?></td>
+ <?lsmb END ?>
<td><?lsmb row.due ?></td>
+ <?lsmb IF defaultcurrency.text != curr.value ?>
<td><div id="<?lsmb "div_topay_invoice_$i" ?>"><?lsmb row.due_fx ?></div></td>
<?lsmb END ?>
<?lsmb #This should be computed and updated to the div using ?>
Added: trunk/UI/payments/use_overpayment1.html
===================================================================
--- trunk/UI/payments/use_overpayment1.html (rev 0)
+++ trunk/UI/payments/use_overpayment1.html 2009-07-15 20:20:24 UTC (rev 2733)
@@ -0,0 +1,77 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title><?lsmb titlebar -?></title>
+ <meta http-equiv="Pragma" content="no-cache" />
+ <meta http-equiv="Expires" content="-1" />
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel="stylesheet" href="css/<?lsmb stylesheet ?>" type="text/css" />
+
+ <meta http-equiv="content-type" content="text/html; charset=<?lsmb charset ?>" />
+ <meta name="robots" content="noindex,nofollow" />
+</head>
+
+<body id="use_overpayment1">
+<form name="search" method="post" action="payment.pl">
+ <?lsmb PROCESS elements.html # Include form elements helper. -?>
+ <?lsmb login.type = 'hidden' ; INCLUDE input element_data=login -?>
+ <?lsmb account_class.type = 'hidden'; account_class.id = account_class.name; INCLUDE input element_data=account_class-?>
+<table width="100%">
+ <tr id="top-bar" class="listtop">
+ <th id="top-bar-header" class="listtop"><label id="top-bar-header-label"><?lsmb text('Use Overpayment') ?></th>
+ </tr>
+</table>
+<br/>
+<?lsmb IF entities -?>
+ <span id="disclaimer">
+ <?lsmb IF account_class.value == 1 -?>
+ <?lsmb text('Please select a vendor with unused overpayments') ?>
+ <?lsmb ELSE -?>
+ <?lsmb text('Please select a customer with unused overpayments') ?>
+ <?lsmb END -?>
+ </span>
+ <br/>
+ <table >
+ <tr id="vc-row" class="label-left">
+ <td id="vc-label-column" class="label-left">
+ <span id="disclaimer">
+ <?lsmb IF account_class.value == 1 -?>
+ <?lsmb text('Vendor') -?>
+ <?lsmb ELSE -?>
+ <?lsmb text('Customer') -?>
+ <?lsmb END ?>
+ </span>
+ </td>
+ <td id="vc-column" class="label-left">
+ <select id="entity_credit_id" name="entity_credit_id">
+ <?lsmb FOREACH item IN entities -?>
+ <option value="<?lsmb item.value ?>"><?lsmb item.name?></option>
+ <?lsmb END ?>
+ </select>
+ </td>
+ </tr>
+ <tr id="curr-row" class="label-left">
+ <td id="curr-label-column" class="label-left">
+ <?lsmb text('Currency') ?>
+ </td>
+ <td id="curr-column" class="label-left">
+ <select id="curr" name="curr">
+ <?lsmb FOREACH item IN curr -?>
+ <option value="<?lsmb item.value ?>"><?lsmb item.text?></option>
+ <?lsmb END -?>
+ </select>
+ </td>
+ </tr>
+ </table>
+ <hr/>
+ <?lsmb PROCESS button element_data=action ?>
+<?lsmb ELSE -?>
+ <?lsmb IF account_class.value == 1 -?>
+ <?lsmb text('There is no vendor with overpayments') ?>
+ <?lsmb ELSE -?>
+ <?lsmb text('There is no customer with overpayments') ?>
+ <?lsmb END -?>
+<?lsmb END -?>
+</body>
+</html>
Added: trunk/UI/payments/use_overpayment2.html
===================================================================
--- trunk/UI/payments/use_overpayment2.html (rev 0)
+++ trunk/UI/payments/use_overpayment2.html 2009-07-15 20:20:24 UTC (rev 2733)
@@ -0,0 +1,325 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title><?lsmb titlebar ?></title>
+ <meta http-equiv="Pragma" content="no-cache" />
+ <meta http-equiv="Expires" content="-1" />
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel="stylesheet" href="css/<?lsmb stylesheet ?>" type="text/css" />
+ <script language="JavaScript" src="UI/payments/javascript/maximize_minimize.js"></script>
+ <meta http-equiv="content-type" content="text/html; charset=<?lsmb charset ?>" />
+ <meta name="robots" content="noindex,nofollow" />
+</head>
+<body id="payment_2_body" onLoad="maximize_minimize_on_load('div_topay_state', 'UI/payments/img/down.gif','UI/payments/img/up.gif') ">
+ <form name="pay_single_dues" method="post" action="payment.pl">
+
+ <?lsmb PROCESS elements.html # Include form elements helper. ?>
+
+ <table width="100%" id="header_table">
+ <tr id="top_bar" class="listtop">
+ <th id="top_bar_header" class="listtop">
+ <?lsmb header.text ?>
+ </th>
+
+ </tr>
+ </table>
+ <table width="100%" id="info_table">
+ <tr valign="top" id="info_row">
+ <td width="50%" id="info_data">
+ <table id="cv_info_table">
+ <tr id="cv_row">
+ <th class="label_left" id="cv_label_column">
+ <?lsmb IF account_class == 1 -?>
+ <?lsmb text('Vendor') -?>
+ <?lsmb ELSE -?>
+ <?lsmb text('Customer') -?>
+ <?lsmb END -?>
+ </th>
+ <td id="vc_column">
+ <?lsmb vc_entity_info.legal_name -?>
+ </td>
+ </tr>
+ <tr id="vc_location_row">
+ <th valign="top" id="cv_location_label_column">
+ <?lsmb text('Location') -?>
+ </th>
+ <td id="vc_location_column">
+ <table id="cv_location_table">
+ <?lsmb IF vc_entity_info.street1 -?>
+ <tr>
+ <td><?lsmb vc_entity_info.street1 -?></td>
+ </tr>
+ <?lsmb END -?>
+ <?lsmb IF vc_entity_info.street2 -?>
+ <tr>
+ <td><?lsmb vc_entity_info.street2 -?></td>
+ </tr>
+ <?lsmb END -?>
+ <?lsmb IF vc_entity_info.street3 -?>
+ <tr>
+ <td><?lsmb vc_entity_info.street3 -?></td>
+ </tr>
+ <?lsmb END -?>
+ <?lsmb IF vc_entity_info.city -?>
+ <tr>
+ <td><?lsmb vc_entity_info.city -?></td>
+ </tr>
+ <?lsmb END -?>
+ <?lsmb IF vc_entity_info.state -?>
+ <tr>
+ <td><?lsmb vc_entity_info.state -?></td>
+ </tr>
+ <?lsmb END -?>
+ <?lsmb IF vc_entity_info.country -?>
+ <tr>
+ <td><?lsmb vc_entity_info.country -?></td>
+ </tr>
+ <?lsmb END -?>
+ </table>
+ </td>
+ </tr>
+ <tr align="right" id="notes_row">
+ <th valign="top" id="notes_column"><?lsmb text('Notes') ?></th>
+ <td id="text_notes_column"><textarea id="notes" name="notes" cols="35" rows="3"><?lsmb notes ?></textarea></td>
+ </tr>
+ </table>
+ </td>
+ <td align="right" id="curr_exrate_date_column">
+ <table id="curr_exrate_date_table">
+ <tr id="date_row"><?lsmb # here goes an input where the date can be written, we can also use a java calendar :). We can use an ajax script to call the Exchange rate of the input date wich can be called with the onChange Method ?>
+ <th align="right" nowrap id="date_label_column"><?lsmb text('Date')?>:</th>
+ <td colspan="2" id="date_column"> <?lsmb INCLUDE input element_data=datepaid ?> </td>
+ </tr>
+ <tr id="curr_row">
+ <?lsmb # here goes the selected currency in step 1 ?>
+ <th align="right" id="curr_label_column"><?lsmb text('Currency') -?>:</th>
+ <td id="curr_column">
+ <?lsmb curr -?>
+ </td>
+ </tr>
+ <?lsmb # here goes the exchange rate of the selected currency, it can be done by the ajax script or the update button ?>
+ <?lsmb IF default_curr != curr # Only process element if one exists. ?>
+ <tr id="exrate_row">
+ <th valig="top" align="right" id="exrate_label_column"><?lsmb text('Exchange Rate') ?>:</th>
+ <td id="exrate_column">
+ <?lsmb IF exrate.value -?>
+ <?lsmb exrate.text -?>
+ <?lsmb exrate.type='hidden'; INCLUDE input element_data=exrate -?>
+ <?lsmb END -?>
+ <?lsmb IF !exrate.value -?>
+ <?lsmb exrate.size = 4 -?>
+ <?lsmb INCLUDE input element_data=exrate -?>
+ <?lsmb END -?>
+ </td>
+ </tr>
+ <?lsmb ELSE -?>
+ <?lsmb exrate.type='hidden'; INCLUDE input element_data=exrate -?>
+ <?lsmb END -?>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <?lsmb # First we show the user how much overpayment is available for each account -?>
+ <table width="100%">
+ <tr><th class="listheading" colspan="4"> <?lsmb text('Available overpayments') -?></th></tr>
+ <tr class="listheading">
+ <th class="listheading"><?lsmb text('Account Number') -?></th>
+ <th class="listheading"><?lsmb text('Account Description') -?></th>
+ <th class="listheading"><?lsmb text('Available') -?></th>
+ <th class="listheading"><?lsmb text('To be used') -?></th>
+ </tr>
+ <?lsmb i = '0'; topay_subtotal = 0 -?>
+ <?lsmb FOREACH data IN overpayments # Loop through columns ?>
+ <?lsmb i = i + 1; j = i % 2; alterning_style = "listrow$j" ?>
+ <?lsmb accno = data.accno -?>
+ <tr class="<?lsmb alterning_style ?>">
+ <td><?lsmb data.accno -?></td>
+ <td><?lsmb data.description -?></td>
+ <td align="right"><?lsmb data.available -?></td>
+ <td align="right"><?lsmb data.touse -?></td>
+ </tr>
+ <?lsmb END ?>
+ <tr class="listsubtotal">
+ <th colspan="2" align="right"><?lsmb text('Subtotal') -?></th>
+ <th><?lsmb avble_subtotal -?></th>
+ <th><?lsmb to_use_subtotal -?></th>
+ </tr>
+
+ </table>
+ <br />
+ <table id="invoices" width="100%">
+ <tr><th class="listheading" colspan="8"> <?lsmb text('Select invoices') -?></th></tr>
+ <tr class="listheading">
+ <th class="listheading"><?lsmb text('Invoice Number') -?></th>
+ <th class="listheading"><?lsmb text('Vendor') -?>/<?lsmb text('Customer') -?></th>
+ <th class="listheading"><?lsmb text('Invoice date') -?></th>
+ <th class="listheading"><?lsmb text('Invoice due') -?></th>
+ <th class="listheading"><?lsmb text('Apply Disc') -?></th>
+ <th class="listheading"><?lsmb text('Overpayment Account') ?>
+ <th class="listheading"><?lsmb text('Amount to be used') -?></th>
+ <th class="listheading">X</th>
+ </tr>
+ <!-- From here starts the selected invoices -->
+ <?lsmb i = 0 -?>
+ <?lsmb subtotal_inv = 0 -?>
+ <?lsmb FOREACH data IN selected_inv # Loop through selected and found invoices -?>
+ <?lsmb i = i + 1; j = i % 2; alterning_style = "listrow$j" -?>
+ <tr class="<?lsmb alterning_style -?>">
+ <td align="center"> <a href="<?lsmb data.invoice.href ?>"><?lsmb data.invoice.number ?></a>
+ <input type="hidden" id="invnumber_<?lsmb i -?>" name="invnumber_<?lsmb i -?>" value="<?lsmb data.invoice.number -?>" />
+ <input type="hidden" id="invoice_id_<?lsmb i -?>" name="invoice_id_<?lsmb i -?>" value="<?lsmb data.invoice.id -?>" />
+ </td>
+ <td align="center"> <?lsmb data.entity_name ?>
+ <input type="hidden" id="entity_id_<?lsmb i -?>" name="entity_id_<?lsmb i -?>" value="<?lsmb data.entity_id -?>" />
+ <input type="hidden" id="vc_discount_accno_<?lsmb i -?>" name="vc_discount_accno_<?lsmb i -?>" value="<?lsmb data.vc_discount_accno -?>" />
+ </td>
+ <td align="center"> <?lsmb data.invoice_date ?>
+ <input type="hidden" id="invoice_date_<?lsmb i -?>" name="invoice_date_<?lsmb i -?>" value="<?lsmb data.invoice_date -?>" />
+ </td>
+ <td align="right"> <?lsmb data.applied_due -?>
+ <input type="hidden" id="due_<?lsmb i -?>" name="due_<?lsmb i -?>" value="<?lsmb data.due -?>" />
+ <input type="hidden" id="discount_<?lsmb i -?>" name="discount_<?lsmb i -?>" value="<?lsmb data.discount -?>" />
+ </td>
+ <?lsmb IF data.repeated_invoice == 'true' -?>
+ <td align="center">
+ <input type="hidden" id="optional_discount_<?lsmb i -?>" name="optional_discount_<?lsmb i -?>" value="<?lsmb data.optional_discount -?>"/>
+ </td>
+ <?lsmb ELSE -?>
+ <?lsmb IF data.optional_discount -?>
+ <td align="center"> <input type="checkbox" id="optional_discount_<?lsmb i -?>" name="optional_discount_<?lsmb i -?>" checked/> </td>
+ <?lsmb ELSE -?>
+ <td align="center"> <input type="checkbox" id="optional_discount_<?lsmb i -?>" name="optional_discount_<?lsmb i -?>" /> </td>
+ <?lsmb END -?>
+ <?lsmb END -?>
+ <td align="center"> <?lsmb data.selected_accno.ovp_accno ?>
+ <input type="hidden" id="selected_accno_<?lsmb i -?>" name="selected_accno_<?lsmb i -?>" value="<?lsmb data.selected_accno.id -?>--<?lsmb data.selected_accno.ovp_accno -?>" />
+ </td>
+ <td align="center">
+ <input name="amount_<?lsmb i -?>" id="amount_<?lsmb i -?>" value="<?lsmb data.amount -?>">
+ <?lsmb subtotal_inv = subtotal_inv + data.amount -?>
+ </td>
+ <td align="center"><input type="checkbox" name="checkbox_<?lsmb i -?>"></td>
+ </tr>
+ <?lsmb END -?>
+ <?lsmb FOREACH data IN avble_invoices # Loop through selected entity invoices -?>
+ <?lsmb i = i + 1; j = i % 2; alterning_style = "listrow$j" -?>
+ <tr class="<?lsmb alterning_style ?>">
+ <td align="center"> <a href="<?lsmb data.invoice.href ?>"><?lsmb data.invoice.number ?></a>
+ <input type="hidden" id="invnumber_<?lsmb i -?>" name="invnumber_<?lsmb i -?>" value="<?lsmb data.invoice.number -?>" />
+ <input type="hidden" id="invoice_id_<?lsmb i -?>" name="invoice_id_<?lsmb i -?>" value="<?lsmb data.invoice.id-?>" />
+ </td>
+ <td align="center"> <?lsmb data.entity_name ?>
+ <input type="hidden" id="entity_id_<?lsmb i -?>" name="entity_id_<?lsmb i -?>" value="<?lsmb data.entity_id -?>" />
+ <input type="hidden" id="vc_discount_accno_<?lsmb i -?>" name="vc_discount_accno_<?lsmb i -?>" value="<?lsmb data.vc_discount_accno -?>" />
+ </td>
+ <td align="center"> <?lsmb data.invoice_date ?>
+ <input type="hidden" id="invoice_date_<?lsmb i -?>" name="invoice_date_<?lsmb i -?>" value="<?lsmb data.invoice_date -?>" />
+ </td >
+ <td align="right"> <?lsmb data.due ?>
+ <input type="hidden" id="due_<?lsmb i -?>" name="due_<?lsmb i -?>" value="<?lsmb data.due -?>" />
+ <input type="hidden" id="discount_<?lsmb i -?>" name="discount_<?lsmb i -?>" value="<?lsmb data.discount -?>" />
+ </td>
+ <?lsmb IF data.repeated_invoice == 'true' -?>
+ <td align="center"> </td>
+ <?lsmb ELSE -?>
+ <td align="center"> <input type="checkbox" id="optional_discount_<?lsmb i -?>" name="optional_discount_<?lsmb i ?>" checked/> </td>
+ <?lsmb END -?>
+ <td align="center"> <?lsmb data.selected_accno.ovp_accno ?>
+ <input type="hidden" id="selected_accno_<?lsmb i -?>" name="selected_accno_<?lsmb i -?>" value="<?lsmb data.selected_accno.id -?>--<?lsmb data.selected_accno.ovp_accno -?>" />
+ </td>
+ <td align="center">
+ <input name="amount_<?lsmb i -?>" id="amount_<?lsmb i -?>" value="<?lsmb data.amount -?>">
+ <?lsmb subtotal_inv = subtotal_inv + data.amount -?>
+ </td>
+ <td align="center"><input type="checkbox" name="checkbox_<?lsmb i ?>"></td>
+ </tr>
+ <?lsmb END -?>
+ <?lsmb i = i + 1; j = i % 2; alterning_style = "listrow$j" -?>
+ <tr class="<?lsmb alterning_style ?>">
+ <td align="center"><input name="new_invoice" id="new_invoice" value=""></td>
+ <td align="center">
+ <select id="new_entity_id" name="new_entity_id">
+ <?lsmb FOREACH item IN vc_list -?>
+ <?lsmb IF item.value == entity_credit_id #by default, select the entity wich was chosen in the previous screen -?>
+ <option value="<?lsmb item.value -?>--<?lsmb item.name -?>--<?lsmb item.vc_discount_accno -?>" selected><?lsmb item.name?></option>
+ <?lsmb ELSE -?>
+ <option value="<?lsmb item.value -?>--<?lsmb item.name -?>--<?lsmb item.vc_discount_accno -?>"><?lsmb item.name?></option>
+ <?lsmb END -?>
+ <?lsmb END -?>
+ </select>
+ </td>
+ <td align="center">N/A</td>
+ <td align="center">N/A</td>
+ <td align="center"> </td>
+ <td align="center">
+ <select id="new_accno" name="new_accno">
+ <?lsmb FOREACH item IN overpayments ?>
+ <option value="<?lsmb item.id -?>--<?lsmb item.accno -?>"><?lsmb item.accno -?></option>
+ <?lsmb END ?>
+ </select>
+ </td>
+ <td align="center">
+ <input name="new_amount" id="new_amount" value="">
+ </td>
+ <td align="center">
+ <?lsmb IF dont_search_inv -?>
+ <input type="checkbox" name="new_checkbox" checked>
+ <?lsmb ELSE -?>
+ <input type="checkbox" name="new_checkbox">
+ <?lsmb END -?>
+ </td>
+ </tr>
+ <tr class="listsubtotal" >
+ <th class="listsubtotal" colspan="6" align="right"> <?lsmb text('Subtotal') -?></th>
+ <th class="listsubtotal"> <?lsmb subtotal_inv -?>
+ <input type="hidden" id="subtotal_inv" name="subtotal_inv" value="<?lsmb subtotal_inv -?>" />
+ </th>
+ <th class="listsubtotal" align="center"> </th>
+ </tr>
+
+ </table>
+ <hr />
+ <table id="footer" width="100%">
+ <tr id="footer_row">
+ <td valing="top" id="button_column">
+ <?lsmb update.accesskey = "U";
+ update.title = "UPDATE ALT+U";
+ update.name = "action";
+ update.value = "use_overpayment2";
+ update.text = text("UPDATE");
+ INCLUDE button element_data=update -?>
+ <?lsmb post.accesskey = "P";
+ post.title = "POST ALT+P";
+ post.name = "action";
+ post.value = "post_overpayment";
+ post.text = text("POST");
+ INCLUDE button element_data=post -?>
+ <?lsmb post_and_print.accesskey = "R";
+ post_and_print.title = "POST AND PRINT ALT+R";
+ post_and_print.name = "action";
+ post_and_print.value = "";
+ post_and_print.text = text("POST AND PRINT");;
+ INCLUDE button element_data=post_and_print ?>
+ <?lsmb INCLUDE select element_data=format ?>
+ <?lsmb INCLUDE select element_data=media ?>
+ <?lsmb FOREACH element_data IN selectedcheckboxes ?>
+ <?lsmb # We should use a cipher here, to avoid XSS
+ element_data.type ='hidden';
+ element_data.value ='checked';
+ INCLUDE input element_data?>
+ <?lsmb END ?>
+ </td>
+ <td id="warning_column" align="right">
+ <?lsmb IF warning -?>
+ <textarea id="warning_text" name="warning_text" cols="35" readonly="true" style="transparent;"><?lsmb warning ?></textarea>
+ <?lsmb END -?>
+ </td>
+ </tr>
+ </table>
+ <?lsmb FOREACH item IN hiddens -?>
+ <?lsmb INCLUDE input element_data=item ?>
+ <?lsmb END -?>
+ </form>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/bin/am.pl
===================================================================
--- trunk/bin/am.pl 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/bin/am.pl 2009-07-15 20:20:24 UTC (rev 2733)
@@ -1377,10 +1377,8 @@
}
sub defaults {
-
# get defaults for account numbers and last numbers
AM->get_all_defaults( \%$form );
-
my %selects = (
'FX_loss' => {name => 'FX_loss', options => []},
'FX_gain' => {name => 'FX_gain', options => []},
@@ -1394,6 +1392,7 @@
text_attr => 'name',
value_attr => 'id',
},
+ 'templates' => {name => 'templates', options => []}
);
foreach $key ( keys %{ $form->{accno} } ) {
foreach $accno ( sort keys %{ $form->{accno}{$key} } ) {
@@ -1405,15 +1404,18 @@
($form->{defaults}{$key} == $form->{accno}{$key}{$accno}{id});
}
}
-
for (qw(accno defaults)) { delete $form->{$_} }
-
##SC: temporary commenting out
## if ( $form->{lynx} ) {
## require "bin/menu.pl";
## &menubar;
## }
-
+ # get_templates_directories the NON-UI templates options - David Mora
+ AM->get_templates_directories( \%$form );
+ foreach my $ref (@{$form->{templates_directories}}) {
+ push @{$selects{templates}{options}}, {text => $ref,value => $ref};
+ }
+ $selects{templates}{default_values} = $form->{templates};
my %hiddens = (
path => $form->{path},
login => $form->{login},
Modified: trunk/scripts/customer.pl
===================================================================
--- trunk/scripts/customer.pl 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/scripts/customer.pl 2009-07-15 20:20:24 UTC (rev 2733)
@@ -23,8 +23,6 @@
use LedgerSMB::DBObject::Customer;
use base qw(LedgerSMB::ScriptLib::Company);
-#require 'lsmb-request.pl';
-
sub set_entity_class {
my ($null, $request) = @_;
$request->{entity_class} = 2;
Modified: trunk/scripts/payment.pl
===================================================================
--- trunk/scripts/payment.pl 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/scripts/payment.pl 2009-07-15 20:20:24 UTC (rev 2733)
@@ -453,7 +453,8 @@
sub payment {
my ($request) = @_;
my $locale = $request->{_locale};
- my $dbPayment = LedgerSMB::DBObject::Payment->new({'base' => $request});
+ my $dbPayment = LedgerSMB::DBObject::Payment->new({'base' => $request});
+ my $Settings = LedgerSMB::Setting->new({'base' => $request});
# Lets get the project data...
my @projectOptions;
my @arrayOptions = $dbPayment->list_open_projects();
@@ -474,10 +475,12 @@
}
# Lets get the currencies (this uses the $dbPayment->{account_class} property)
my @currOptions;
- @arrayOptions = $dbPayment->get_open_currencies();
+ @arrayOptions = $Settings->get_currencies();
+
for my $ref (0 .. $#arrayOptions) {
- push @currOptions, { value => $arrayOptions[$ref]->{payments_get_open_currencies},
- text => $arrayOptions[$ref]->{payments_get_open_currencies} };
+ push @currOptions, { value => $arrayOptions[$ref],
+ text => $arrayOptions[$ref]};
+
}
# Lets build filter by period
my $date = LedgerSMB::DBObject::Date->new({base => $request});
@@ -558,18 +561,18 @@
my $locale = $request->{_locale};
my $dbPayment = LedgerSMB::DBObject::Payment->new({'base' => $request});
my @array_options = $dbPayment->get_entity_credit_account();
- if ($#array_options == -1) {
+if ($#array_options == -1) {
&payment($request);
- } elsif ($#array_options == 0) {
+} elsif ($#array_options == 0) {
$request->{'vendor-customer'} = $array_options[0]->{id}.'--'.$array_options[0]->{name};
&payment2($request);
- } else {
+} else {
# Lets call upon the template system
-
my @company_options;
for my $ref (0 .. $#array_options) {
push @company_options, { id => $array_options[$ref]->{id},
- name => $array_options[$ref]->{name}};
+ name => $array_options[$ref]->{name},
+ meta_number => $array_options[$ref]->{meta_number}};
}
my $select = {
companies => ..hidden..,
@@ -681,8 +684,7 @@
if ($default_currency ne $request->{curr} ) {
# FIRST WE PUSH THE OTHER COLUMN HEADERS WE NEED
push @column_headers, {text => $locale->text('Exchange Rate')},
- {text => $locale->text('Amount Due').$currency_text},
- {text => $locale->text('To pay').$currency_text};
+ {text => $locale->text('Amount Due').$currency_text};
# WE SET THEM IN THE RIGHT ORDER FOR THE TABLE INSIDE THE UI
@column_headers[7,8] = @column_headers[8,7];
# DOES THE CURRENCY IN USE HAS AN EXCHANGE RATE?, IF SO
@@ -714,7 +716,8 @@
};
}
# FINALLY WE ADD TO THE COLUMN HEADERS A LAST FIELD TO PRINT THE CLOSE INVOICE CHECKBOX TRICK :)
- push @column_headers, {text => 'X'};
+ push @column_headers, {text => $locale->text('To pay').$currency_text},
+ {text => 'X'};
# WE NEED TO QUERY THE DATABASE TO CHECK FOR OPEN INVOICES
# WE WONT DO ANYTHING IF WE DONT FIND ANY INVOICES, THE USER CAN STILL POST A PREPAYMENT
my @invoice_data;
@@ -833,14 +836,16 @@
}
}
}
-# We need to set the availible media and format from printing
+# We need to set the available media and format from printing
my @media_options;
push @media_options, {value => 1, text => "Screen"};
if ($#{LedgerSMB::Sysconfig::printer}) {
for (keys %{LedgerSMB::Sysconfig::printer}) {
push @media_options, {value => 1, text => $_};
}
-}
+}
+push @media_options, {value => 1, text => "e-mail"};
+
#$request->error("@media_options");
my @format_options;
push @format_options, {value => 1, text => "HTML"};
@@ -951,7 +956,7 @@
# since we are using two tables there is no need to use doubled information,
# we could specify this gl is the result of a payment movement...
#
-$Payment->{gl_description} = $locale->text('This gl movement, is the result of a payment transaction');
+$Payment->{gl_description} = $locale->text('This gl movement, is a consecuence of a payment transaction');
#
# Im not sure what this is for... gotta comment this later
$Payment->{approved} = 'true';
@@ -988,7 +993,7 @@
my $discount_account_id = $array_options[0]->{discount};
@array_options = $Payment->get_open_invoices();
for my $ref (0 .. $#array_options) {
- if ( !$request->{"checkbox_$array_options[$ref]->{invoice_id}"}) {
+ if ((!$request->{"checkbox_$array_options[$ref]->{invoice_id}"})&&($request->{"topay_fx_$array_options[$ref]->{invoice_id}"})) {
# First i have to determine if discounts will apply
# we will assume that a discount should apply only
# if this is the last payment of an invoice
@@ -1005,12 +1010,12 @@
$unhandled_overpayment = $request->round_amount($unhandled_overpayment + $request->{"topay_fx_$array_options[$ref]->{invoice_id}"} + $temporary_discount - $array_options[$ref]->{amount}) ;
}
- if ($request->{"optional_discount_$array_options[$ref]->{invoice_id}"}) {
- push @amount, $array_options[$ref]->{discount_fx};
+ if ($temporary_discount != 0) {
+ push @amount, $temporary_discount;
push @cash_account_id, $discount_account_id;
push @source, $locale->text('Applied discount');
push @transaction_id, $array_options[$ref]->{invoice_id};
- }
+ }
push @amount, $request->{"topay_fx_$array_options[$ref]->{invoice_id}"}; # We'll use this for both cash and ap/ar accounts
push @cash_account_id, $request->{"optional_pay_$array_options[$ref]->{invoice_id}"} ? $request->{"account_$array_options[$ref]->{invoice_id}"} : $request->{account};
push @source, $request->{"optional_pay_$array_options[$ref]"} ?
@@ -1060,6 +1065,7 @@
$Payment->{op_memo} = $Payment->_db_array_scalars(@op_memo);
$Payment->{op_account_id} = $Payment->_db_array_scalars(@op_account_id);
# Ok, passing the control to postgresql and hoping for the best...
+
$Payment->post_payment();
if ($request->{continue_to_calling_sub}){ return $Payment->{payment_id} ;}
else {
@@ -1097,21 +1103,20 @@
# The next code will enable number to text conversion
$Payment->init();
$header->{amount2text} = $Payment->num2text($header->{amount});
-
-
############################################################################
# $Payment->{format_amount} = sub {return $Payment->format_amount(@_); };
-
# IF YOU NEED MORE INFORMATION ON THE HEADER AND ROWS ITEMS CHECK SQL FUNCTIONS
# payment_gather_header_info AND payment_gather_line_info
my $select = {
header => $header,
- rows => ..hidden..
+ rows => ..hidden..,
+ format_amount => sub {$Payment->format_amount(@_)}
};
+ $Payment->{templates_path} = 'templates/'.$Payment->get_default_value_by_key('templates').'/';
my $template = LedgerSMB::Template->new(
user => $Payment->{_user},
locale => $Payment->{_locale},
- path => "templates/test/",
+ path => $Payment->{templates_path},
template => 'printPayment',
format => 'HTML' );
eval {$template->render($select) };
@@ -1138,7 +1143,6 @@
&print_payment($Payment);
}
-
=pod
=item use_overpayment
@@ -1154,18 +1158,32 @@
my ($request) = @_;
my $locale = $request->{_locale};
my $Payment = LedgerSMB::DBObject::Payment->new({'base' => $request});
+my $Settings = LedgerSMB::Setting->new({'base' => $request});
+my @arrayOptions;
my @entities;
#We will use $ui to handle all the data needed by the User Interface
my $ui = { stylesheet => $request->{_user}->{stylesheet}};
-$ui->{accountclass} = {name => 'account_class', value => $request->{account_class}};
+$ui->{account_class} = {name => 'account_class', value => $request->{account_class}};
+
#We want to get all the customer/vendor with unused overpayment
my @data = $Payment->get_open_overpayment_entities();
for my $ref (0 .. $#data) {
push @entities, { value => $data[$ref]->{id},
name => $data[$ref]->{name}};
}
-$ui->{entities} = ..hidden..;
+
+my @currOptions;
..hidden.. = $Settings->get_currencies();
+
+for my $ref (0 .. $#arrayOptions) {
+ push @currOptions, { value => $arrayOptions[$ref],
+ text => $arrayOptions[$ref]};
+}
+
+
+$ui->{curr} = ..hidden..;
+$ui->{entities} = ..hidden..;
$ui->{action} = {name => 'action', value => 'use_overpayment2', text => $locale->text('Continue')};
my $template = LedgerSMB::Template->new(
user => $request->{_user},
@@ -1193,16 +1211,28 @@
my ($request) = @_;
my $locale = $request->{_locale};
my $Payment = LedgerSMB::DBObject::Payment->new({'base' => $request});
-my @array_options;
-my @vc_options;
+my $Selected_entity;
+my @vc_info;
+my @vc_list;
my @overpayments;
+my @ui_overpayments;
+my @avble_invoices;
+my @ui_avble_invoices;
+my @ui_selected_inv;
my $exchangerate;
+my $ui_exchangerate;
my @selected_checkboxes;
-my $availible_subtotal = 0;
-my $touse_subtotal = 0;
+my $ui_to_use_subtotal = 0;
+my $ui_avble_subtotal = 0;
my @hiddens;
+my $vc_entity_info;
+my $default_currency;
+my %amount_to_be_used;
+my %ovp_repeated_invoices;
+my %invoice_id_amount_to_pay;
+my $count;
+my $warning = $Payment->{"warning"};
-
# First we need to insert some hidden information
push @hiddens, { id => 'entity_credit_id',
@@ -1217,51 +1247,485 @@
name => 'login',
type => 'hidden',
value => $request->{login} };
+push @hiddens, { id => 'curr',
+ name => 'curr',
+ type => 'hidden',
+ value => $request->{curr} };
+#lets search the entity default currency
+$default_currency = $Payment->get_default_currency();
-# need to get all the availible overpayments
..hidden.. = $Payment->get_availible_overpayment_amount();
-for my $ref (0 .. $#array_options) {
- push @overpayments, { id => $array_options[$ref]->{payment_id},
- accno => $array_options[$ref]->{accno},
- description => $array_options[$ref]->{description},
- amount => "$array_options[$ref]->{movements}",
- availible => "$array_options[$ref]->{availible}",
- touse => $array_options[$ref]->{'ovp_'."$array_options[$ref]->{payment_id}"}
+
+# WE NEED TO KNOW IF WE ARE USING A CURRENCY THAT NEEDS AN EXCHANGERATE
+if ($default_currency ne $request->{curr} ) {
+# DOES THE CURRENCY IN USE HAS AN EXCHANGE RATE?, IF SO
+# WE MUST SET THE VALUE, OTHERWISE THE UI WILL HANDLE IT
+ $exchangerate = $Payment->{exrate} ?
+ $Payment->{exrate} :
+ $Payment->get_exchange_rate($request->{curr},
+ $Payment->{datepaid} ? $Payment->{datepaid} : $Payment->{current_date});
+ if ($exchangerate) {
+ $ui_exchangerate = {
+ id => 'exrate',
+ name => 'exrate',
+ value => "$exchangerate", #THERE IS A STRANGE BEHAVIOUR WITH THIS,
+ text => "$exchangerate" #IF I DONT USE THE DOUBLE QUOTES, IT WILL PRINT THE ADDRESS
+ #THERE MUST BE A REASON FOR THIS, I MUST RETURN TO IT LATER
+ };
+ } else {
+ $ui_exchangerate = {
+ id => 'exrate',
+ name => 'exrate'};
+ }
+
+} else {
+# WE MUST SET EXCHANGERATE TO 1 FOR THE MATHS SINCE WE
+# ARE USING THE DEFAULT CURRENCY
+ $exchangerate = 1;
+ $ui_exchangerate = {
+ id => 'exrate',
+ name => 'exrate',
+ value => 1,
+ text => 1
+ };
+}
+
+#get the owner of the overpayment info
+$vc_entity_info = $Payment->get_vc_info();
+
+
+
+#list all the vendor/customer
..hidden.. = $Payment->get_entity_credit_account();
+for my $ref (0 .. $#vc_info) {
+ my ($name) = split(/:/, $vc_info[$ref]->{name});
+ push @vc_list, { value => $vc_info[$ref]->{id},
+ name => $name,
+ vc_discount_accno => $vc_info[$ref]->{discount}};
+}
+
+
+$count=1;
+#lets see which invoice do we have printed
+while ($Payment->{"entity_id_$count"})
+{
+ if ($Payment->{"checkbox_$count"})
+ {
+ $count++;
+ next;
+ }
+
+ if ($ovp_repeated_invoices{qq|$Payment->{"invoice_id_$count"}|}->{qq|$Payment->{"selected_accno_$count"}|} != $Payment->{"selected_accno_$count"}){
+
+ #the "ovp_repeated_invoices" hash will store the convination of invoice id and overpayment account, if this convination has already printed
+ #do not print it again
+ $ovp_repeated_invoices{qq|$Payment->{"invoice_id_$count"}|}->{qq|$Payment->{"selected_accno_$count"}|} = $Payment->{"selected_accno_$count"};
+
+ #the "repeated invoice" flag will check if this invoice has already been printed, if it does, do not print the apply discount checkbox in the UI
+ if (!$ovp_repeated_invoices{qq|$Payment->{"invoice_id_$count"}|}->{"repeated_invoice"}){
+ $ovp_repeated_invoices{qq|$Payment->{"invoice_id_$count"}|}->{"optional_discount"} = $Payment->{"optional_discount_$count"};
+ $ovp_repeated_invoices{qq|$Payment->{"invoice_id_$count"}|}->{"repeated_invoice"} = 'false';
+ } else{
+ $ovp_repeated_invoices{qq|$Payment->{"invoice_id_$count"}|}->{"repeated_invoice"} = 'true';
+ }
+
+ $ui_to_use_subtotal += $Payment->{"amount_$count"};
+
+ my ($id,$name) = split(/--/, $Payment->{"entity_id_$count"});
+ my ($ovp_chart_id, $ovp_selected_accno) = split(/--/, $Payment->{"selected_accno_$count"});
+ my $applied_due = ($ovp_repeated_invoices{qq|$Payment->{"invoice_id_$count"}|}->{"optional_discount"})? $Payment->{"due_$count"}: $Payment->{"due_$count"} + $Payment->{"discount_$count"};
+
+ $amount_to_be_used{"$ovp_selected_accno"} += $Payment->{"amount_$count"};
+ #this hash will keep track of the amount to be paid of an specific invoice_id, this amount could not be more than the due of that invoice.
+ $invoice_id_amount_to_pay{qq|$Payment->{"invoice_id_$count"}|} += $Payment->{"amount_$count"};
+ if($invoice_id_amount_to_pay{qq|$Payment->{"invoice_id_$count"}|} > $applied_due){
+ $warning .= $locale->text('The amount of the invoice number').qq| $Payment->{"invnumber_$count"} |.$locale->text('is lesser than the amount to be paid').qq|\n|;
+ }
+ ###################################################################
+ # ojo no me gusta como esta implementado
+ ###################################################################
+ if($Payment->{"amount_$count"} < 0){
+ $warning .= $locale->text('The amount of the invoice number').qq| $Payment->{"invnumber_$count"} |.$locale->text('is lesser than 0').qq|\n|;
+ }
+ #lets make the href for the invoice
+ my $uri = $Payment->{account_class} == 1 ? 'ap' : 'ar';
+ $uri .= '.pl?action=edit&id='.$Payment->{"invoice_id_$count"}.'&path=bin/mozilla&login='.$request->{login};
+
+ push @ui_selected_inv, { invoice => { number => $Payment->{"invnumber_$count"},
+ id => $Payment->{"invoice_id_$count"},
+ href => $uri},
+ entity_name => $name,
+ entity_id => $Payment->{"entity_id_$count"},
+ vc_discount_accno => $Payment->{"vc_discount_accno_$count"},
+ invoice_date => $Payment->{"invoice_date_$count"},
+ applied_due => $applied_due,
+ optional_discount => $ovp_repeated_invoices{qq|$Payment->{"invoice_id_$count"}|}->{"optional_discount"},
+ repeated_invoice => $ovp_repeated_invoices{qq|$Payment->{"invoice_id_$count"}|}->{"repeated_invoice"},
+ due => $Payment->{"due_$count"},
+ discount => $Payment->{"discount_$count"},
+ selected_accno => {id => $ovp_chart_id,
+ ovp_accno => $ovp_selected_accno},
+ amount => $Payment->{"amount_$count"}};
+ }
+ $count++;
+}
+
+
+#lets search wich available invoice do we have for the selected entity
+if ($Payment->{"new_entity_id"} && !$Payment->{"new_checkbox"})
+{
+ #lets create an object who has the entity_credit_id of the selected entity
+ $Selected_entity = LedgerSMB::DBObject::Payment->new({'base' => $Payment});
+ $Selected_entity->{"invnumber"} = $Selected_entity->{new_invoice} ;
+
+ my ($id,$name,$vc_discount_accno) = split(/--/, $Selected_entity->{"new_entity_id"});
+ my ($ovp_chart_id, $ovp_selected_accno) = split(/--/, $Selected_entity->{"new_accno"});
+
+ $Selected_entity->{"entity_credit_id"} = $id;
+
+ @avble_invoices = $Selected_entity->get_open_invoice();
+ for my $ref (0 .. $#avble_invoices) {
+
+ #this hash will store the convination of invoice id and overpayment account, if this convination has already printed
+ #do not print it again
+ if ($ovp_repeated_invoices{qq|$avble_invoices[$ref]->{invoice_id}|}->{qq|$Selected_entity->{"new_accno"}|} != $Selected_entity->{"new_accno"}){
+ $ovp_repeated_invoices{qq|$avble_invoices[$ref]->{invoice_id}|}->{qq|$Selected_entity->{"new_accno"}|} = $Selected_entity->{"new_accno"};
+
+ #the "repeated invoice" flag will check if this invoice has already been printed, if it does, do not print the apply discount checkbox in the UI
+ if (!$ovp_repeated_invoices{qq|$avble_invoices[$ref]->{invoice_id}|}->{"repeated_invoice"}){
+ $ovp_repeated_invoices{qq|$avble_invoices[$ref]->{invoice_id}|}->{"repeated_invoice"} = 'false';
+ } else{
+ $ovp_repeated_invoices{qq|$avble_invoices[$ref]->{invoice_id}|}->{"repeated_invoice"} = 'true';
+ }
+
+
+ if (!$ovp_repeated_invoices{qq|$avble_invoices[$ref]->{invoice_id}|}->{"optional_discount"}){
+ $ovp_repeated_invoices{qq|$avble_invoices[$ref]->{invoice_id}|}->{"optional_discount"} = 'true';
+ }
+
+ $invoice_id_amount_to_pay{qq|$avble_invoices[$ref]->{invoice_id}|} += $Selected_entity->{"new_amount"};
+ $ui_to_use_subtotal += $Selected_entity->{"new_amount"};
+ $amount_to_be_used{"$ovp_selected_accno"} += $Selected_entity->{"new_amount"};
+
+ #lets make the href for the invoice
+ my $uri = $Payment->{account_class} == 1 ? 'ap' : 'ar';
+ $uri .= '.pl?action=edit&id='.$avble_invoices[$ref]->{invoice_id}.'&path=bin/mozilla&login='.$request->{login};
+
+ push @ui_avble_invoices, { invoice => { number => $avble_invoices[$ref]->{invnumber},
+ id => $avble_invoices[$ref]->{invoice_id},
+ href => $uri},
+ entity_name => $name,
+ vc_discount_accno => $vc_discount_accno,
+ entity_id => qq|$Selected_entity->{"entity_credit_id"}--$name|,
+ invoice_date => $avble_invoices[$ref]->{invoice_date},
+ applied_due => $Payment->{"due_$count"},
+ repeated_invoice => $ovp_repeated_invoices{qq|$avble_invoices[$ref]->{invoice_id}|}->{"repeated_invoice"},
+ due => "$avble_invoices[$ref]->{due}",
+ discount => "$avble_invoices[$ref]->{discount}",
+ selected_accno => { id => $ovp_chart_id,
+ ovp_accno => $ovp_selected_accno},
+ amount => $Selected_entity->{"new_amount"}}
+ }
+ }
+}
+
+
+# we need to get all the available overpayments
..hidden.. = $Payment->get_available_overpayment_amount();
+
+for my $ref (0 .. $#overpayments) {
+ push @ui_overpayments, { id => $overpayments[$ref]->{chart_id},
+ accno => $overpayments[$ref]->{accno},
+ description => $overpayments[$ref]->{description},
+ amount => "$overpayments[$ref]->{movements}",
+ available => "$overpayments[$ref]->{available}",
+ touse => qq|$amount_to_be_used{"$overpayments[$ref]->{accno}"}|
};
- $availible_subtotal += "$array_options[$ref]->{availible}";
- $touse_subtotal += $array_options[$ref]->{'ovp_'."$array_options[$ref]->{payment_id}"};
+ $ui_avble_subtotal += "$overpayments[$ref]->{available}";
}
-
+
# We start with our data selection called ui
-my $ui = { overpayments => ..hidden..,
- availible_subtotal => $availible_subtotal,
- touse_subtotal => $touse_subtotal,
- stylesheet => $request->{_user}->{stylesheet},
- header => { text => $locale->text('Use overpayment/prepayment')},
+my $ui = { exrate => $ui_exchangerate,
+ datepaid => {name => 'datepaid',
+ value => $Payment->{"datepaid"}? $Payment->{"datepaid"} : $Payment->{"current_date"},
+ size => '10'},
+ notes => $Payment->{"notes"},
+ vc_entity_info => $vc_entity_info,
+ curr => $request->{curr},
+ default_curr => $default_currency,
+ dont_search_inv => $Payment->{"new_checkbox"},
+ vc_list => ..hidden..,
+ entity_credit_id => $Payment->{entity_credit_id},
+ selected_inv => ..hidden..,
+ avble_invoices => ..hidden..,
+ account_class => $request->{account_class},
+ overpayments => ..hidden..,
+ to_use_subtotal => $ui_to_use_subtotal,
+ avble_subtotal => $ui_avble_subtotal,
+ stylesheet => $request->{_user}->{stylesheet},
+ warning => $warning,
+ header => { text => $locale->text('Use overpayment/prepayment')},
};
-
# Lastly we include the hiddens on the UI
$ui->{hiddens} = ..hidden..;
-my $template = LedgerSMB::Template->new(
- user => $request->{_user},
- locale => $request->{_locale},
- path => 'UI/payments',
- template => 'use_overpayment2',
- format => 'HTML' );
+my $template = LedgerSMB::Template->new(
+ user => $request->{_user},
+ locale => $request->{_locale},
+ path => 'UI/payments',
+ template => 'use_overpayment2',
+ format => 'HTML' );
+
eval {$template->render($ui) };
if ($@) { $request->error("$@"); } # PRINT ERRORS ON THE UI
-}# End SUB
+}
+=pod
+=item post_overpayment
+This method reorganize the selected invoices by customer/vendor and adapt them to make them fit with the post_payment sql method, calling it once by customer/vendor id
+=cut
+
+
+sub post_overpayment {
+my ($request) = @_;
+my $locale = $request->{_locale};
+my %entity_list;
+my %invoice_id_amount_to_pay;
+my @amount;
+my @discount;
+my @cash_account_id;
+my @memo;
+my @source;
+my @transaction_id;
+#this variables will store all the unused overpayment wich will be used to pay the invoices
+my %entity_unused_ovp;
+my $unused_ovp_index;
+
+#let's store all unused invoice in entity_unused_ovp, it will be
+
+#lets see which invoice do we have, and reorganize them by vendor/customer
+my $count=1;
+while ($request->{"entity_id_$count"})
+{
+
+ if ($request->{"checkbox_$count"})
+ {
+ $count++;
+ next;
+ }
+
+ my ($entity_id,$entity_name) = split(/--/, $request->{"entity_id_$count"});
+ my ($ovp_chart_id, $ovp_selected_accno) = split(/--/, $request->{"selected_accno_$count"});
+
+ #Let's see wich will the amount of the invoice due that will be paid from an overpayment
+ my $applied_due = ($request->{"optional_discount_$count"} && $request->{"amount_$count"} == $request->{"due_$count"})?
+ $request->{"due_$count"}:
+ $request->{"due_$count"} + $request->{"discount_$count"};
+
+ #let's check if the overpayment movements of the $ovp_chart_id accno has already been searched, if not, search and store it
+ #to later use
+ if(!$entity_unused_ovp{"$ovp_chart_id"})
+ {
+ $entity_unused_ovp{"$ovp_chart_id"} = LedgerSMB::DBObject::Payment->new({'base' => $request});
+ $entity_unused_ovp{"$ovp_chart_id"}->{"chart_id"} = $ovp_chart_id;
+ #this call will store the unused overpayments in $entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"} just check the .pm
+ $entity_unused_ovp{"$ovp_chart_id"}->get_unused_overpayments();
+ #this counter will keep track of the ovp that had been used to pay the invoices
+ $entity_unused_ovp{"$ovp_chart_id"}->{"unused_ovp_index"} = 0;
+ }
+ $unused_ovp_index = $entity_unused_ovp{"$ovp_chart_id"}->{"unused_ovp_index"};
+
+ ###############################################################
+ # Warnings Section
+ ###############################################################
+ #In this section, the post_overpayment will check some user inputs and verify if those are apted to call the post method, if not just store a warning message in the
+ #$request->{warning} variable and then call the use_overpayment2 method and it will manage it
+
+ #the $invoice_id_amount_to_pay hash will keep track of the amount to be paid of an specific invoice_id, this amount could not be more than the due of that invoice
+ $invoice_id_amount_to_pay{qq|$request->{"invoice_id_$count"}|} += $request->{"amount_$count"};
+ if($invoice_id_amount_to_pay{qq|$request->{"invoice_id_$count"}|} > $applied_due){
+ $request->{"warning"} .= "Warning\n"
+ }
+
+ #The amount to be paid shouldn't be negative
+ if ($request->{"amount_$count"} < 0){
+ $request->{"warning"} .= "Warning\n"
+ }
+
+ #Is the amount to be paid null?, tell the user and he/she will be able to manage it
+ if ($request->{"amount_$count"} == 0 )
+ {
+ $request->{"warning"} .= $locale->text('The amount to be pay of the invoice number').qq| $request->{"invnumber_$count"} |.$locale->text('is null').qq|\n|;
+ }
+
+ #if the amount to be paid is bigger than the amount of the invoice, just call the update method and it will manage it
+ if($request->{"warning"}){
+ &use_overpayment2($request);
+ return 0;
+ }
+
+ #lets fill our entity_list by it's entity ID
+ if($entity_list{"$entity_id"})
+ {
+
+ #Let's fill all our entity invoice info, if it has a discount, store it into the discount accno
+ if ($entity_list{"$entity_id"}->{"optional_discount_$count"} && $entity_list{"$entity_id"}->{"amount_$count"} == $entity_list{"$entity_id"}->{"due_$count"}) {
+ push @{$entity_list{"$entity_id"}->{"array_amount"}}, $entity_list{"$entity_id"}->{"discount_$count"};
+ push @{$entity_list{"$entity_id"}->{"array_cash_account_id"}}, $entity_list{"$entity_id"}->{"vc_discount_accno_$count"};
+ push @{$entity_list{"$entity_id"}->{"array_source"}}, $locale->text('Applied discount by an overpayment');
+ push @{$entity_list{"$entity_id"}->{"array_transaction_id"}}, $entity_list{"$entity_id"}->{"invoice_id_$count"};
+ push @{$entity_list{"$entity_id"}->{"array_memo"}}, 'NULL';
+ push @{$entity_list{"$entity_id"}->{"ovp_payment_id"}}, 'NULL';
+ }
+
+ #this is the amount of the present invoice that will be paid from the $ovp_chart_id accno
+ my $tmp_ovp_amount = $entity_list{"$entity_id"}->{"amount_$count"};
+
+ #let's store the AR/AP movement vs the overpayment accno, and keep track of all the ovp_id that will be use
+ while($tmp_ovp_amount > 0)
+ {
+ #Send a warning if there are no more available amount in the $ovp_chart_id accno
+ if (@{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"available"} eq '')
+ {
+ $request->{"warning"} .= $locale->text('The amount to be pay from the accno').qq| $ovp_chart_id |.$locale->text('is bigger than the amount available').qq|\n|;
+ $tmp_ovp_amount = -1;
+ next;
+ }
+ if (@{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"available"} >= $tmp_ovp_amount)
+ {
+ push @{$entity_list{"$entity_id"}->{"array_amount"}}, $tmp_ovp_amount;
+ push @{$entity_list{"$entity_id"}->{"array_cash_account_id"}}, $ovp_chart_id;
+ push @{$entity_list{"$entity_id"}->{"array_source"}}, $locale->text('use of an overpayment');
+ push @{$entity_list{"$entity_id"}->{"array_transaction_id"}}, $entity_list{"$entity_id"}->{"invoice_id_$count"};
+ push @{$entity_list{"$entity_id"}->{"array_memo"}}, 'NULL';
+ push @{$entity_list{"$entity_id"}->{"ovp_payment_id"}}, @{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"payment_id"};
+
+ $tmp_ovp_amount = 0;
+ #lets see if there is more amount on the present overpayment movement
+ my $tmp_residual_ovp_amount = @{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"available"} - $tmp_ovp_amount;
+ if ($tmp_residual_ovp_amount == 0)
+ {
+ $entity_unused_ovp{"$ovp_chart_id"}->{"unused_ovp_index"}++;
+ }
+ } else{
+ $tmp_ovp_amount -= @{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"available"};
+
+ push @{$entity_list{"$entity_id"}->{"array_amount"}}, @{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"available"};
+ push @{$entity_list{"$entity_id"}->{"array_cash_account_id"}}, $ovp_chart_id;
+ push @{$entity_list{"$entity_id"}->{"array_source"}}, $locale->text('use of an overpayment');
+ push @{$entity_list{"$entity_id"}->{"array_transaction_id"}}, $entity_list{"$entity_id"}->{"invoice_id_$count"};
+ push @{$entity_list{"$entity_id"}->{"array_memo"}}, 'NULL';
+ push @{$entity_list{"$entity_id"}->{"ovp_payment_id"}}, @{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"payment_id"};
+
+ $unused_ovp_index = $entity_unused_ovp{"$ovp_chart_id"}->{"unused_ovp_index"}++;
+ }
+
+ }
+
+ }else {
+ #Create an Payment object if this entity has not been saved, this object will encapsulate all the entity info wich will be needed to
+ #call the sql payment_post method
+ $entity_list{"$entity_id"} = LedgerSMB::DBObject::Payment->new({'base' => $request});
+ $entity_list{"$entity_id"}->{"entity_credit_id"} = $entity_id;
+
+ # LETS GET THE DEPARTMENT INFO
+ # ******************************************, Falta implementarlo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ #if ($request->{department}) {
+ #}
+ #$entity_list{"$entity_id"}->{"department_id"} = $request->{department};
+ #********************************************************
+
+ # We want to set a gl_description,
+ # since we are using two tables there is no need to use doubled information,
+ # we could specify this gl is the result of a overpayment movement...
+ #
+ $entity_list{"$entity_id"}->{"gl_description"} = $locale->text('This gl movement, is the result of a overpayment transaction');
+
+ # Im not sure what this is for... gotta comment this later
+ $entity_list{"$entity_id"}->{"approved"} = 'true';
+ #
+
+ #Let's fill all our entity invoice info, if it has a discount, store it into the discount accno
+ if ($entity_list{"$entity_id"}->{"optional_discount_$count"} && $entity_list{"$entity_id"}->{"amount_$count"} == $entity_list{"$entity_id"}->{"due_$count"}) {
+ push @{$entity_list{"$entity_id"}->{"array_amount"}}, $entity_list{"$entity_id"}->{"discount_$count"};
+ push @{$entity_list{"$entity_id"}->{"array_cash_account_id"}}, $entity_list{"$entity_id"}->{"vc_discount_accno_$count"};
+ push @{$entity_list{"$entity_id"}->{"array_source"}}, $locale->text('Applied discount by an overpayment');
+ push @{$entity_list{"$entity_id"}->{"array_transaction_id"}}, $entity_list{"$entity_id"}->{"invoice_id_$count"};
+ push @{$entity_list{"$entity_id"}->{"array_memo"}}, 'NULL';
+ push @{$entity_list{"$entity_id"}->{"ovp_payment_id"}}, 'NULL';
+
+ }
+
+ #this is the amount of the present invoice that will be paid from the $ovp_chart_id accno
+ my $tmp_ovp_amount = $entity_list{"$entity_id"}->{"amount_$count"};
+
+ #let's store the AR/AP movement vs the overpayment accno, and keep track of all the ovp_id that will be use
+ while($tmp_ovp_amount > 0)
+ {
+ if (@{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"available"} >= $tmp_ovp_amount)
+ {
+ push @{$entity_list{"$entity_id"}->{"array_amount"}}, $tmp_ovp_amount;
+ push @{$entity_list{"$entity_id"}->{"array_cash_account_id"}}, $ovp_chart_id;
+ push @{$entity_list{"$entity_id"}->{"array_source"}}, $locale->text('use of an overpayment');
+ push @{$entity_list{"$entity_id"}->{"array_transaction_id"}}, $entity_list{"$entity_id"}->{"invoice_id_$count"};
+ push @{$entity_list{"$entity_id"}->{"array_memo"}}, 'NULL';
+ push @{$entity_list{"$entity_id"}->{"ovp_payment_id"}}, @{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"payment_id"};
+
+ $tmp_ovp_amount = 0;
+ #lets see if there is more amount on the present overpayment movement
+ my $tmp_residual_ovp_amount = @{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"available"} - $tmp_ovp_amount;
+ if ($tmp_residual_ovp_amount == 0)
+ {
+ $entity_unused_ovp{"$ovp_chart_id"}->{"unused_ovp_index"}++;
+ }
+ } else{
+ $tmp_ovp_amount -= @{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"available"};
+
+ push @{$entity_list{"$entity_id"}->{"array_amount"}}, @{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"available"};
+ push @{$entity_list{"$entity_id"}->{"array_cash_account_id"}}, $ovp_chart_id;
+ push @{$entity_list{"$entity_id"}->{"array_source"}}, $locale->text('use of an overpayment');
+ push @{$entity_list{"$entity_id"}->{"array_transaction_id"}}, $entity_list{"$entity_id"}->{"invoice_id_$count"};
+ push @{$entity_list{"$entity_id"}->{"array_memo"}}, 'NULL';
+ push @{$entity_list{"$entity_id"}->{"ovp_payment_id"}}, @{$entity_unused_ovp{"$ovp_chart_id"}->{"unused_overpayment"}}[$unused_ovp_index]->{"payment_id"};
+
+ $unused_ovp_index = $entity_unused_ovp{"$ovp_chart_id"}->{"unused_ovp_index"}++;
+ }
+ }
+
+
+ }
+
+ $count++;
+}
+
+
+
+# Now we have all our movements organized by vendor/customer, it is time to call the post_payment sql method by each one of them
+for my $key (keys %entity_list)
+{
+ # Finally we store all the data inside the LedgerSMB::DBObject::Payment object.
+ $entity_list{"$key"}->{"amount"} = $entity_list{"$key"}->_db_array_scalars(@{$entity_list{"$key"}->{"array_amount"}});
+ $entity_list{"$key"}->{"cash_account_id"} = $entity_list{"$key"}->_db_array_scalars(@{$entity_list{"$key"}->{"array_cash_account_id"}});
+ $entity_list{"$key"}->{"source"} = $entity_list{"$key"}->_db_array_scalars(@{$entity_list{"$key"}->{"array_source"}});
+ $entity_list{"$key"}->{"memo"} = $entity_list{"$key"}->_db_array_scalars(@{$entity_list{"$key"}->{"array_memo"}});
+ $entity_list{"$key"}->{"transaction_id"} = $entity_list{"$key"}->_db_array_scalars(@{$entity_list{"$key"}->{"array_transaction_id"}});
+ $entity_list{"$key"}->{"ovp_payment_id"} = $entity_list{"$key"}->_db_array_scalars(@{$entity_list{"$key"}->{"ovp_payment_id"}});
+
+ $entity_list{"$key"}->post_payment();
+}
+
+&use_overpayment($request);
+
+}
+
eval { do "scripts/custom/payment.pl"};
1;
Modified: trunk/sql/Pg-database.sql
===================================================================
--- trunk/sql/Pg-database.sql 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/sql/Pg-database.sql 2009-07-15 20:20:24 UTC (rev 2733)
@@ -2180,12 +2180,14 @@
36 module payment.pl 84
36 action payment 85
36 type receipt 86
+36 account_class 2 551
37 module cp.pl 87
-38 module cp.pl 90
-38 action payment 91
37 type receipt 89
37 action payments 88
+38 module payment.pl 90
+38 action payment 91
38 type check 92
+38 account_class 1 554
194 module ar.pl 538
194 action add 539
40 module gl.pl 96
@@ -2604,7 +2606,6 @@
194 type credit_note 548
195 type credit_invoice 542
197 type debit_invoice 546
-36 account_class 1 551
202 batch_type payment_reversal 570
204 batch_type receipt_reversal 573
200 menu 1 552
@@ -2691,7 +2692,6 @@
DECLARE
item menu_item;
arg menu_attribute%ROWTYPE;
-
BEGIN
FOR item IN
SELECT n.position, n.id, c.level, n.label, c.path, '{}'
Modified: trunk/sql/modules/Payment.sql
===================================================================
--- trunk/sql/modules/Payment.sql 2009-07-15 20:07:26 UTC (rev 2732)
+++ trunk/sql/modules/Payment.sql 2009-07-15 20:20:24 UTC (rev 2733)
@@ -13,7 +13,8 @@
id int,
name text,
entity_class int,
- discount int
+ discount int,
+ meta_number character varying(32)
);
CREATE OR REPLACE FUNCTION payment_type__get_label(in_payment_type_id int) RETURNS SETOF payment_types AS
@@ -38,9 +39,9 @@
BEGIN
FOR out_entity IN
- SELECT ec.id, cp.legal_name as name, e.entity_class, ec.discount_account_id
- FROM entity e
- JOIN entity_credit_account ec ON (ec.entity_id = e.id)
+ SELECT ec.id, cp.legal_name||': '||ec.description as name, e.entity_class, ec.discount_account_id, ec.meta_number
+ FROM entity_credit_account ec
+ JOIN entity e ON (ec.entity_id = e.id)
JOIN company cp ON (cp.entity_id = e.id)
WHERE ec.entity_class = in_account_class
AND (cp.legal_name ilike coalesce('%'||in_vc_name||'%','%%') OR cp.tax_id = in_vc_idn)
@@ -63,15 +64,15 @@
JOIN entity_credit_account ec ON (ec.entity_id = e.id)
JOIN company cp ON (cp.entity_id = e.id)
WHERE ec.entity_class = in_account_class
- -- AND CASE WHEN in_account_class = 1 THEN
- -- e.id IN (SELECT entity_id FROM ap
- -- WHERE amount <> paid
- -- GROUP BY entity_id)
- -- WHEN in_account_class = 2 THEN
- -- e.id IN (SELECT entity_id FROM ar
- -- WHERE amount <> paid
- -- GROUP BY entity_id)
- -- END
+ AND CASE WHEN in_account_class = 1 THEN
+ e.id IN (SELECT entity_id FROM ap
+ WHERE amount <> paid
+ GROUP BY entity_id)
+ WHEN in_account_class = 2 THEN
+ e.id IN (SELECT entity_id FROM ar
+ WHERE amount <> paid
+ GROUP BY entity_id)
+ END
LOOP
RETURN NEXT out_entity;
END LOOP;
@@ -99,7 +100,7 @@
END;
$$ LANGUAGE PLPGSQL;
-COMMENT ON FUNCTION payment_get_open_accounts(int) IS
+COMMENT ON FUNCTION payment_get_all_accounts(int) IS
$$ This function takes a single argument (1 for vendor, 2 for customer as
always) and returns all entities with accounts of the appropriate type. $$;
@@ -178,14 +179,14 @@
THEN ex.buy
ELSE ex.sell END)
END) AS exchangerate
- FROM (SELECT id, invnumber, transdate, amount, entity_id,
+ FROM (SELECT id, invnumber, transdate, amount, entity_id,
1 as invoice_class, paid, curr,
- entity_credit_account, department_id
+ entity_credit_account, department_id, approved
FROM ap
UNION
SELECT id, invnumber, transdate, amount, entity_id,
2 AS invoice_class, paid, curr,
- entity_credit_account, department_id
+ entity_credit_account, department_id, approved
FROM ar
) a
@@ -216,7 +217,8 @@
OR in_amountto IS NULL)
AND (a.department_id = in_department_id
OR in_department_id IS NULL)
- AND due <> 0
+ AND due <> 0
+ AND a.approved = true
GROUP BY a.invnumber, a.transdate, a.amount, amount_fx, discount, discount_fx, ac.due, a.id, c.discount_terms, ex.buy, ex.sell, a.curr
LOOP
RETURN NEXT payment_inv;
@@ -224,15 +226,42 @@
END;
$$ LANGUAGE PLPGSQL;
+COMMENT ON FUNCTION payment_get_open_invoices(int, int, char(3), date, date, numeric, numeric, int) IS
+$$ This function is the base for get_open_invoice and returns all open invoices for the entity_credit_id
+it has a lot of options to enable filtering and use the same logic for entity_class_id and currency. $$;
+CREATE OR REPLACE FUNCTION payment_get_open_invoice
+(in_account_class int,
+ in_entity_credit_id int,
+ in_curr char(3),
+ in_datefrom date,
+ in_dateto date,
+ in_amountfrom numeric,
+ in_amountto numeric,
+ in_department_id int,
+ in_invnumber text)
+RETURNS SETOF payment_invoice AS
+$$
+DECLARE payment_inv payment_invoice;
+BEGIN
+ FOR payment_inv IN
+ SELECT * from payment_get_open_invoices(in_account_class, in_entity_credit_id, in_curr, in_datefrom, in_dateto, in_amountfrom,
+ in_amountto, in_department_id)
+ WHERE (invnumber like in_invnumber OR in_invnumber IS NULL)
+ LOOP
+ RETURN NEXT payment_inv;
+ END LOOP;
+END;
-COMMENT ON FUNCTION payment_get_open_invoices(int, int, char(3), date, date, numeric, numeric, int) IS
-$$ This function takes three arguments:
-Type: 1 for vendor, 2 for customer
-Entity_id: The entity_id of the customer or vendor
-Currency: 3 characters for currency ('USD' for example).
-Returns all open invoices for the entity in question. $$;
+$$ LANGUAGE PLPGSQL;
+COMMENT ON FUNCTION payment_get_open_invoice(int, int, char(3), date, date, numeric, numeric, int, text) IS
+$$
+This function is based on payment_get_open_invoices and returns only one invoice if the in_invnumber is set.
+if no in_invnumber is passed this function behaves the same as payment_get_open_invoices
+$$;
+
+
CREATE TYPE payment_contact_invoice AS (
contact_id int,
econtrol_code text,
@@ -548,7 +577,7 @@
payment_date date default current_date,
closed bool default FALSE,
entity_credit_id integer references entity_credit_account(id),
- employee_id integer references entity_employee(entity_id),
+ employee_id integer references person(id),
currency char(3),
notes text,
department_id integer default 0);
@@ -599,7 +628,8 @@
in_op_cash_account_id int[],
in_op_source text[],
in_op_memo text[],
- in_op_account_id int[],
+ in_op_account_id int[],
+ in_ovp_payment_id int[],
in_approved bool)
RETURNS INT AS
$$
@@ -621,7 +651,10 @@
SELECT * INTO current_exchangerate FROM currency_get_exchangerate(in_curr, in_datepaid, in_account_class);
- SELECT INTO var_employee entity_id FROM users WHERE username = SESSION_USER LIMIT 1;
+ SELECT INTO var_employee p.id
+ FROM users u
+ JOIN person p ON (u.entity_id=p.entity_id)
+ WHERE username = SESSION_USER LIMIT 1;
--
-- WE HAVE TO INSERT THE PAYMENT, USING THE GL INFORMATION
-- THE ID IS GENERATED BY payment_id_seq
@@ -642,6 +675,7 @@
-- FIRST WE SHOULD INSERT THE CASH ACCOUNTS
--
-- WE SHOULD HAVE THE DATA STORED AS (ACCNO, AMOUNT), SO
+ IF (array_upper(in_cash_account_id, 1) > 0) THEN
FOR out_count IN
array_lower(in_cash_account_id, 1) ..
array_upper(in_cash_account_id, 1)
@@ -656,6 +690,10 @@
in_source[out_count], in_memo[out_count]);
INSERT INTO payment_links
VALUES (var_payment_id, currval('acc_trans_entry_id_seq'), 1);
+ IF (in_ovp_payment_id IS NOT NULL AND in_ovp_payment_id[out_count] IS NOT NULL) THEN
+ INSERT INTO payment_links
+ VALUES (in_ovp_payment_id[out_count], currval('acc_trans_entry_id_seq'), 0);
+ END IF;
END LOOP;
-- NOW LETS HANDLE THE AR/AP ACCOUNTS
@@ -726,6 +764,7 @@
INSERT INTO payment_links
VALUES (var_payment_id, currval('acc_trans_entry_id_seq'), 1);
END LOOP;
+ END IF; -- END IF
--
-- WE NEED TO HANDLE THE OVERPAYMENTS NOW
--
@@ -757,13 +796,14 @@
INSERT INTO acc_trans (chart_id, amount,
trans_id, transdate, approved, source, memo)
VALUES (in_op_cash_account_id[out_count],
- CASE WHEN in_account_class = 2 THEN in_op_amount[out_count]
+ CASE WHEN in_account_class = 1 THEN in_op_amount[out_count]
ELSE in_op_amount[out_count] * - 1
END,
var_gl_id, in_datepaid, coalesce(in_approved, true),
in_op_source[out_count], in_op_memo[out_count]);
INSERT INTO payment_links
VALUES (var_payment_id, currval('acc_trans_entry_id_seq'), 2);
+
END LOOP;
-- NOW LETS HANDLE THE OVERPAYMENT ACCOUNTS
FOR out_count IN
@@ -773,7 +813,7 @@
INSERT INTO acc_trans (chart_id, amount,
trans_id, transdate, approved, source, memo)
VALUES (in_op_account_id[out_count],
- CASE WHEN in_account_class = 2 THEN in_op_amount[out_count] * -1
+ CASE WHEN in_account_class = 1 THEN in_op_amount[out_count] * -1
ELSE in_op_amount[out_count]
END,
var_gl_id, in_datepaid, coalesce(in_approved, true),
@@ -1112,15 +1152,16 @@
c.legal_name as legal_name, am.amount as amount, em.first_name, em.last_name, p.currency, p.notes
FROM payment p
JOIN employee em ON (em.entity_id = p.employee_id)
- JOIN company c ON (c.entity_id = p.entity_id)
- JOIN ( SELECT sum(a.amount) as amount
- FROM acc_trans a
- JOIN chart c ON (a.chart_id = c.id)
- JOIN payment_links pl ON (pl.entry_id=a.entry_id)
- WHERE
- ( ((c.link like '%AP_paid%' OR c.link like '%AP_discount%') AND in_account_class = 1)
- OR ((c.link like '%AR_paid%' OR c.link like '%AR_discount%') AND in_account_class = 2))
- AND pl.payment_id = in_payment_id ) am ON (1=1)
+ JOIN entity_credit_account eca ON (eca.id = p.entity_credit_id)
+ JOIN company c ON (c.entity_id = eca.entity_id)
+ JOIN payment_links pl ON (p.id = pl.payment_id)
+ -- JOIN ( SELECT sum(a.amount) as amount
+ -- FROM acc_trans a
+ -- JOIN chart ch ON (a.chart_id = ch.id)
+ -- JOIN payment_links pl ON (pl.entry_id=a.entry_id)
+ -- WHERE
+ -- ((ch.link like '%AP_paid%' OR ch.link like '%AP_discount%') AND in_account_class = 1)
+ -- OR ((ch.link like '%AR_paid%' OR ch.link like '%AR_discount%') AND in_account_class = 2) ) am ON (1=1)
WHERE p.id = in_payment_id
LOOP
RETURN NEXT out_payment;
@@ -1139,12 +1180,12 @@
entry_id int,
link_type int,
trans_id int,
- invoice_number int,
+ invoice_number text,
chart_id int,
- chart_accno int,
+ chart_accno text,
chart_description text,
chart_link text,
- amount int,
+ amount numeric,
trans_date date,
source text,
cleared bool,
@@ -1186,3 +1227,88 @@
COMMENT ON FUNCTION payment_gather_line_info(int,int) IS
$$ This function finds a payment based on the id and retrieves all the line records,
it is usefull for printing payments and build reports :) $$;
+
+-- We will use a view to handle all the overpayments
+DROP VIEW overpayments CASCADE;
+CREATE VIEW overpayments AS
+SELECT p.id as payment_id, p.reference as payment_reference, p.payment_class, p.closed as payment_closed,
+ p.payment_date, ac.chart_id, c.accno, c.description as chart_description,
+ p.department_id, abs(sum(ac.amount)) as available, cmp.legal_name,
+ eca.id as entity_credit_id, eca.entity_id, eca.discount, eca.meta_number
+FROM payment p
+JOIN payment_links pl ON (pl.payment_id=p.id)
+JOIN acc_trans ac ON (ac.entry_id=pl.entry_id)
+JOIN chart c ON (c.id=ac.chart_id)
+JOIN entity_credit_account eca ON (eca.id = p.entity_credit_id)
+JOIN company cmp ON (cmp.entity_id=eca.entity_id)
+WHERE p.gl_id IS NOT NULL
+ AND (pl.type = 2 OR pl.type = 0)
+ AND c.link LIKE '%overpayment%'
+GROUP BY p.id, c.accno, p.reference, p.payment_class, p.closed, p.payment_date,
+ ac.chart_id, chart_description, p.department_id, legal_name, eca.id,
+ eca.entity_id, eca.discount, eca.meta_number;
+
+CREATE OR REPLACE FUNCTION payment_get_open_overpayment_entities(in_account_class int)
+ returns SETOF payment_vc_info AS
+ $$
+ DECLARE out_entity payment_vc_info;
+ BEGIN
+ FOR out_entity IN
+ SELECT DISTINCT entity_credit_id, legal_name, e.entity_class, discount, o.meta_number
+ FROM overpayments o
+ JOIN entity e ON (e.id=o.entity_id)
+ WHERE available <> 0 AND in_account_class = payment_class
+ LOOP
+ RETURN NEXT out_entity;
+ END LOOP;
+ END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION payment_get_unused_overpayment(
+in_account_class int, in_entity_credit_id int, in_chart_id int)
+returns SETOF overpayments AS
+$$
+DECLARE out_overpayment overpayments%ROWTYPE;
+BEGIN
+ FOR out_overpayment IN
+ SELECT DISTINCT *
+ FROM overpayments
+ WHERE payment_class = in_account_class
+ AND entity_credit_id = in_entity_credit_id
+ AND available <> 0
+ AND (in_chart_id IS NULL OR chart_id = in_chart_id )
+ ORDER BY payment_date
+
+ LOOP
+ RETURN NEXT out_overpayment;
+ END LOOP;
+END;
+$$ LANGUAGE PLPGSQL;
+
+
+CREATE TYPE payment_overpayments_available_amount AS (
+ chart_id int,
+ accno text,
+ description text,
+ available numeric
+);
+
+CREATE OR REPLACE FUNCTION payment_get_available_overpayment_amount(
+in_account_class int, in_entity_credit_id int)
+returns SETOF payment_overpayments_available_amount AS
+$$
+DECLARE out_overpayment payment_overpayments_available_amount;
+BEGIN
+ FOR out_overpayment IN
+ SELECT chart_id, accno, chart_description, abs(sum(available))
+ FROM overpayments
+ WHERE payment_class = in_account_class
+ AND entity_credit_id = in_entity_credit_id
+ AND available <> 0
+ GROUP BY chart_id, accno, chart_description
+ LOOP
+ RETURN NEXT out_overpayment;
+ END LOOP;
+END;
+$$ LANGUAGE PLPGSQL;
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.