[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SF.net SVN: ledger-smb:[2733] trunk



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"> &nbsp;
+    	<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"> &nbsp; </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"> &nbsp; </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">&nbsp;<?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">&nbsp;</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.