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

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



Revision: 2200
          http://ledger-smb.svn.sourceforge.net/ledger-smb/?rev=2200&view=rev
Author:   einhverfr
Date:     2008-07-09 10:52:06 -0700 (Wed, 09 Jul 2008)

Log Message:
-----------
Correcting parse errors on Form.pm
Including David Mora's discount handling patches to single-payment interfaces

Modified Paths:
--------------
    trunk/LedgerSMB/Form.pm
    trunk/LedgerSMB/Sysconfig.pm
    trunk/UI/payments/payment1.html
    trunk/UI/payments/payment2.html
    trunk/scripts/payment.pl
    trunk/sql/modules/Payment.sql

Modified: trunk/LedgerSMB/Form.pm
===================================================================
--- trunk/LedgerSMB/Form.pm	2008-07-09 14:47:33 UTC (rev 2199)
+++ trunk/LedgerSMB/Form.pm	2008-07-09 17:52:06 UTC (rev 2200)
@@ -89,7 +89,7 @@
 
     my $argstr = shift;
 
-    if ($ENV{CONTENT_LENGTH} > $LedgerSMB::Sysconfig::max_post_size; ) {
+    if ($ENV{CONTENT_LENGTH} > $LedgerSMB::Sysconfig::max_post_size) {
         print "Status: 413\n Request entity too large\n\n";
         die "Error: Request entity too large\n";
     }

Modified: trunk/LedgerSMB/Sysconfig.pm
===================================================================
--- trunk/LedgerSMB/Sysconfig.pm	2008-07-09 14:47:33 UTC (rev 2199)
+++ trunk/LedgerSMB/Sysconfig.pm	2008-07-09 17:52:06 UTC (rev 2200)
@@ -7,7 +7,6 @@
 use LedgerSMB::Form;
 use Config::Std;
 use DBI qw(:sql_types);
-
 binmode STDOUT, ':utf8';
 binmode STDERR, ':utf8';
 

Modified: trunk/UI/payments/payment1.html
===================================================================
--- trunk/UI/payments/payment1.html	2008-07-09 14:47:33 UTC (rev 2199)
+++ trunk/UI/payments/payment1.html	2008-07-09 17:52:06 UTC (rev 2200)
@@ -17,11 +17,15 @@
 
 <form name="search" method="post" action="payment.pl">
 <?lsmb PROCESS elements.html  # Include form elements helper. -?>
-<?lsmb login.type = 'hidden' ; PROCESS input element_data=login -?>
-<?lsmb accountclass.type = 'hidden'; PROCESS input element_data=accountclass -?>
-<?lsmb type.type = "hidden";
-       PROCESS input element_data=type;
- -?>
+<?lsmb login.type = 'hidden' ; INCLUDE input element_data=login -?>
+<?lsmb accountclass.type = 'hidden'; INCLUDE input element_data=accountclass -?>
+<?lsmb # The first_load field is required on payment2.html to initialize discounts the first time, on each subsequent update it wont exist-?>
+<?lsmb INCLUDE input element_data={
+            name => 'first_load',
+            id   => 'first_load',
+            type => 'hidden',
+            value => 'on'} ?>
+<?lsmb type.type = "hidden"; INCLUDE input element_data=type; -?>
 <table width="100%">
   <tr id="top-bar" class="listtop">
     <th id="top-bar-header" class="listtop"><label  id="top-bar-header-label"><?lsmb text('Receipts') ?></th>

Modified: trunk/UI/payments/payment2.html
===================================================================
--- trunk/UI/payments/payment2.html	2008-07-09 14:47:33 UTC (rev 2199)
+++ trunk/UI/payments/payment2.html	2008-07-09 17:52:06 UTC (rev 2200)
@@ -157,12 +157,19 @@
     <td><?lsmb row.invoice_date ?></td>
     <td><?lsmb row.amount ?></td>
     <td><?lsmb row.paid ?></td>
+<<<<<<< .mine
     <td><?lsmb row.discount ?></td>
+    <td align="center"><input  name="<?lsmb "optional_discount_$row.invoice.id" -?>"  id="<?lsmb
+       "optional_discount_$row.invoice.id" -?>" type="checkbox"  class="checkbox"<?lsmb IF
+       row.optional_discount OR first_load -?> checked <?lsmb END -?> ></td>
+=======
+    <td><?lsmb row.discount ?></td>
+>>>>>>> .r2199
     <td><?lsmb row.due ?></td>
     <?lsmb IF defaultcurrency.text != curr.value ?>
     <td><?lsmb row.exchange_rate ?></td>
-    <td><?lsmb row.due_fx ?></td>
-    <td><div id="<?lsmb "div_topay_invoice_$i" ?>"><?lsmb row.topay ?></div></td>
+    <td><?lsmb row.due ?></td>
+    <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  ?> 
     <td><?lsmb  row.topay_fx.id = row.topay_fx.name ;INCLUDE input element_data=row.topay_fx;
@@ -290,11 +297,24 @@
            <option value="<?lsmb item -?>"><?lsmb item -?></option>
           <?lsmb END -?>
          </select>
-         <input name="overpayment_source2_<?lsmb overpayment_item ?>"     id="overpayment_source2_<?lsmb overpayment_item ?>"  />
+         <input name="overpayment_source2_<?lsmb overpayment_item -?>"  id="overpayment_source2_<?lsmb overpayment_item -?>"/>
          <input type="hidden" name="overpayment_qty" id="overpayment_qty" value="<?lsmb overpayment_item ?>" />
      </td>
+<<<<<<< .mine
      <td align="center"><input name="overpayment_memo_<?lsmb overpayment_item -?>" id="overpayment_memo_<?lsmboverpayment_item ?>" /></td>     
+     <td align="center">
+      <input 
+      	name="overpayment_topay_<?lsmb overpayment_item -?>"
+      	id="overpayment_topay_<?lsmboverpayment_item ?>"
+        value="<?lsmb IF unhandled_overpayment.value > 0 -?>
+                    <?lsmb unhandled_overpayment.value -?>
+                <?lsmb END -?>"      
+      />
+     </td>
+=======
+     <td align="center"><input name="overpayment_memo_<?lsmb overpayment_item -?>" id="overpayment_memo_<?lsmboverpayment_item ?>" /></td>     
      <td align="center"><input name="overpayment_topay_<?lsmb overpayment_item -?>" id="overpayment_topay_<?lsmboverpayment_item ?>" /></td>
+>>>>>>> .r2199
      <td align="center"><input type="checkbox" name="overpayment_checkbox_<?lsmb overpayment_item -?>"/></td>
    </tr>
    <tr class="listsubtotal">

Modified: trunk/scripts/payment.pl
===================================================================
--- trunk/scripts/payment.pl	2008-07-09 14:47:33 UTC (rev 2199)
+++ trunk/scripts/payment.pl	2008-07-09 17:52:06 UTC (rev 2200)
@@ -555,6 +555,7 @@
 my @currency_options;
 my $exchangerate;
 # LETS GET THE CUSTOMER/VENDOR INFORMATION	
+
 ($Payment->{entity_credit_id}, $Payment->{company_name}) = split /--/ , $request->{'vendor-customer'};
 
 # WE NEED TO RETRIEVE A BILLING LOCATION, THIS IS HARDCODED FOR NOW... Should we change it? 
@@ -579,7 +580,8 @@
 # LETS GET THE POSSIBLE SOURCES
 my @sources_options = $Payment->get_sources(\%$locale);
 # WE MUST PREPARE THE ENTITY INFORMATION
..hidden.. = $Payment->get_vc_info();
..hidden.. = $Payment->get_vc_info();# IS THIS WORKING?
+
 # LETS BUILD THE CURRENCIES INFORMATION 
 # FIRST, WE NEED TO KNOW THE DEFAULT CURRENCY
 my $default_currency = $Payment->get_default_currency(); 
@@ -595,6 +597,7 @@
                        {text => $locale->text('Total').$default_currency_text},
                        {text => $locale->text('Paid').$default_currency_text},
                        {text => $locale->text('Discount').$default_currency_text},
+                       {text => $locale->text('Apply Disc')},
                        {text => $locale->text('Amount Due').$default_currency_text},
                        {text => $locale->text('To pay').$default_currency_text}
                        );
@@ -642,27 +645,46 @@
 my @invoice_data;
 my @topay_state; # WE WILL USE THIS TO HELP UI TO DETERMINE WHAT IS VISIBLE
 @array_options  = $Payment->get_open_invoices(); 
-
+my $unhandled_overpayment;
 for my $ref (0 .. $#array_options) {
  if (  !$request->{"checkbox_$array_options[$ref]->{invoice_id}"}) {
 # SHOULD I APPLY DISCCOUNTS?   
-
+      $request->{"optional_discount_$array_options[$ref]->{invoice_id}"} = $request->{first_load}? "on":  $request->{"optional_discount_$array_options[$ref]->{invoice_id}"};
+      
 # LETS SET THE EXCHANGERATE VALUES
    my $due_fx; my $topay_fx_value;
    if ("$exchangerate") {
        $topay_fx_value =   $due_fx = "$array_options[$ref]->{due}"/"$exchangerate" - "$array_options[$ref]->{discount}"/"$exchangerate";
+       if ($request->{"optional_discount_$array_options[$ref]->{invoice_id}"}) {
+       $topay_fx_value = $due_fx = $due_fx - "$array_options[$ref]->{discount}"/"$exchangerate";
+        }
    } else {
        $topay_fx_value = $due_fx = "N/A";
    }
+# We need to check for unhandled overpayment, see the post function for details
+# First we will see if the discount should apply?
+     my  $temporary_discount = 0;
+     if (($request->{"optional_discount_$array_options[$ref]->{invoice_id}"})&&($due_fx <=  $request->{"topay_fx_$array_options[$ref]->{invoice_id}"} +  $array_options[$ref]->{discount}/"$exchangerate")) {
+         $temporary_discount = "$array_options[$ref]->{discount}"/"$exchangerate";
+      
+     } 
+# We need to compute the unhandled_overpayment, notice that all the values inside the if already have 
+# the exchangerate applied       
+      if ( $due_fx <  $request->{"topay_fx_$array_options[$ref]->{invoice_id}"}) {
+         # We need to store all the overpayments so we can use it on the screen
+         $unhandled_overpayment = $unhandled_overpayment + $request->{"topay_fx_$array_options[$ref]->{invoice_id}"} - $due_fx ;
+         $request->{"topay_fx_$array_options[$ref]->{invoice_id}"} = $due_fx;
+     }   
    push @invoice_data, {       invoice => { number => $array_options[$ref]->{invnumber},
                                             id     =>  $array_options[$ref]->{invoice_id},
                                             href   => 'ar.pl?id='."$array_options[$ref]->{invoice_id}"
                                            },  
                                invoice_date      => "$array_options[$ref]->{invoice_date}",
                                amount            => "$array_options[$ref]->{amount}",
-                               due               => "$array_options[$ref]->{due}" - "$array_options[$ref]->{discount}",
+                               due               => $request->{"optional_discount_$array_options[$ref]->{invoice_id}"}? "$array_options[$ref]->{due}" - "$array_options[$ref]->{discount}": "$array_options[$ref]->{due}",
                                paid              => "$array_options[$ref]->{amount}" - "$array_options[$ref]->{due}",
-                               discount          => "$array_options[$ref]->{discount}",
+                               discount          => $request->{"optional_discount_$array_options[$ref]->{invoice_id}"} ? "$array_options[$ref]->{discount}" : 0 ,
+                               optional_discount =>  $request->{"optional_discount_$array_options[$ref]->{invoice_id}"},
                                exchange_rate     => "$exchangerate",
                                due_fx            =>  $due_fx, # This was set at the begining of the for statement
                                topay             => "$array_options[$ref]->{due}" - "$array_options[$ref]->{discount}",
@@ -738,7 +760,10 @@
         push  @format_options, {value => 2, text => "PDF" }, {value => 3, text => "POSTSCRIPT" };
 }    
 # LETS BUILD THE SELECTION FOR THE UI
+# Notice that the first data inside this selection is the firs_load, this
+# will help payment2.html to know wether it is beeing called for the first time
 my $select = {
+  first_load => $request->{first_load},
   stylesheet => $request->{_user}->{stylesheet},
   header  =>  { text => $request->{type} eq 'receipt' ? $locale->text('Receipt') : $locale->text('Payment') },
   type    =>  { name  => 'type',
@@ -774,7 +799,7 @@
   vendorcustomer => { name => 'vendor-customer',
                       value => $request->{'vendor-customer'}
                      },
-    
+  unhandled_overpayment => { name => 'unhandledoverpayment', value => $unhandled_overpayment   }  ,
   vc => { name => $Payment->{company_name}, # We will assume that the first Billing Information as default
           address =>  [ {text => $vc_options[0]->{'line_one'}},
                         {text =>  $vc_options[0]->{'line_two'}},
@@ -808,6 +833,7 @@
 }
 
 
+
 =pod
 
 =item post_payment
@@ -824,7 +850,7 @@
 my $locale       = $request->{_locale};
 my $Payment = LedgerSMB::DBObject::Payment->new({'base' => $request});
 # LETS GET THE CUSTOMER/VENDOR INFORMATION	
-($Payment->{entity_id}, $Payment->{company_name}) = split /--/ , $request->{'vendor-customer'};
+($Payment->{entity_credit_id}, $Payment->{company_name}) = split /--/ , $request->{'vendor-customer'};
 # LETS GET THE DEPARTMENT INFO
 # WE HAVE TO SET $dbPayment->{department_id} in order to process
 if ($request->{department}) {
@@ -849,10 +875,11 @@
 # Variable definition
 #
 # We use the prefix op to refer to the overpayment variables.
-my $overpayment; # This variable might be fuzzy, we are using it to handle invalid data
-                 # i.e. a user set an overpayment qty inside an invoice.
+my $unhandled_overpayment = 0; # This variable might be fuzzy, we are using it to handle invalid data
+                           # i.e. a user set an overpayment qty inside an invoice.
 my @array_options; 
 my @amount;
+my @discount;
 my @cash_account_id;
 my @source;
 my @transaction_id;
@@ -865,33 +892,53 @@
 # We need the invoices in order to process the income data, this is done this way
 # since the data we have isn't indexed in any way.
 #
-
+# Ok, we want to use the disccount information in order to do some accounting movements,
+# we will process it with the same logic for a regular payment, and see where does this leave us.
..hidden.. = $Payment->get_entity_credit_account();# We need to know the disccount account
+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}"}) {
+         # 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
+     my  $temporary_discount = 0;
+     if (($request->{"optional_discount_$array_options[$ref]->{invoice_id}"})&&("$array_options[$ref]->{due}"/"$request->{exrate}" <=  $request->{"topay_fx_$array_options[$ref]->{invoice_id}"} +  $array_options[$ref]->{discount})) {
+         $temporary_discount = $array_options[$ref]->{discount};
+     }   
          #
          # The prefix cash is to set the movements of the cash accounts, 
          # same names are used for ap/ar accounts w/o the cash prefix.
          #
-         # Maybe i should move this to another sub, so i can call it from payment2 as well :). D.M.
-     if ($array_options[$ref]->{amount} <  $request->{"topay_$array_options[$ref]->{invoice_id}"} ) {
-         # THERE IS AN OVERPAYMENT!, we should store it and see if we can use it on the UI 
-         $overpayment = $overpayment + $request->{"topay_$array_options[$ref]->{invoice_id}"} - $array_options[$ref]->{amount};
-         $request->{"topay_$array_options[$ref]->{invoice_id}"} = $request->{"topay_$array_options[$ref]->{invoice_id}"};
+     if ( "$array_options[$ref]->{due}"/"$request->{exrate}" <  $request->{"topay_fx_$array_options[$ref]->{invoice_id}"} + $temporary_discount ) {
+         # We need to store all the overpayments so we can use it on a new payment2 screen
+         $unhandled_overpayment = $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};
+             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->{"source1_$array_options[$ref]->{invoice_id}"}.' '.$request->{"source2_$array_options[$ref]->{invoice_id}"}; # We'll use this for both source and ap/ar accounts
          push @transaction_id, $array_options[$ref]->{invoice_id};        
  }
 }
+# Check if there is an unhandled overpayment and run payment2 as needed
+
+if ($unhandled_overpayment) {
+&payment2($request);
+return 0;
+}
 #
 # Now we need the overpayment information.
 #
 # We will use the prefix op to indicate it is an overpayment information.
 #
 # note: I love the for's C-like syntax.
-
 for (my $i=1 ; $i <= $request->{overpayment_qty}; $i++) {
    if (!$request->{"overpayment_checkbox_$i"}) { # Is overpayment marked as deleted ?  
      if ( $request->{"overpayment_topay_$i"} ) { # Is this overpayment an used field?
@@ -909,7 +956,6 @@
      } 
    }  
 }
-
 # Finally we store all the data inside the LedgerSMB::DBObject::Payment object. 
     $Payment->{cash_account_id}    =  $Payment->_db_array_scalars(@cash_account_id);
     $Payment->{amount}             =  $Payment->_db_array_scalars(@amount);
@@ -935,5 +981,6 @@
                 
 }
 
+
 eval { do "scripts/custom/payment.pl"};
 1;

Modified: trunk/sql/modules/Payment.sql
===================================================================
--- trunk/sql/modules/Payment.sql	2008-07-09 14:47:33 UTC (rev 2199)
+++ trunk/sql/modules/Payment.sql	2008-07-09 17:52:06 UTC (rev 2200)
@@ -1,3 +1,12 @@
+
+CREATE TYPE payment_vc_info AS (
+	id int,
+	name text,
+	entity_class int,
+	discount int
+);
+
+
 CREATE OR REPLACE FUNCTION payment_get_entity_accounts
 (in_account_class int,
  in_vc_name text,
@@ -2,8 +11,10 @@
  in_vc_idn  int)
- returns SETOF entity AS
+ returns SETOF payment_vc_info AS
  $$
- DECLARE out_entity entity%ROWTYPE;
+ DECLARE out_entity payment_vc_info;
+ 
+
  BEGIN
  	FOR out_entity IN
- 		SELECT ec.id, cp.legal_name as name, e.entity_class, e.created
+ 		SELECT ec.id, cp.legal_name as name, e.entity_class, ec.discount_account_id
  		FROM entity e
@@ -110,6 +121,7 @@
 		         SELECT id, invnumber, transdate, amount, entity_id,
 		               2 AS invoice_class, paid, curr,
 		               entity_credit_account, department_id
+
 		         FROM ar
 		         ) a 
 		JOIN (SELECT trans_id, chart_id, sum(CASE WHEN in_account_class = 1 THEN amount
@@ -137,7 +149,8 @@
 		        AND (a.amount <= in_amountto
 		             OR in_amountto IS NULL)
 		        AND (a.department_id = in_department_id
-		             OR in_department_id IS NULL)     
+		             OR in_department_id IS NULL)
+		        AND due <> 0          
 		        GROUP BY a.invnumber, a.transdate, a.amount, discount, ac.due, a.id, c.discount_terms
 	LOOP
 		RETURN NEXT payment_inv;
@@ -554,7 +567,7 @@
 	        INSERT INTO acc_trans (chart_id, amount,
 		                       trans_id, transdate, approved, source)
 		VALUES (in_cash_account_id[out_count], 
-		        CASE WHEN in_account_class = 2 THEN in_amount[out_count]  
+		        CASE WHEN in_account_class = 1 THEN in_amount[out_count]  
 		        ELSE in_amount[out_count]* - 1
 		        END,
 		        in_transaction_id[out_count], in_datepaid, coalesce(in_approved, true), 
@@ -576,7 +589,7 @@
          INSERT INTO acc_trans (chart_id, amount,
                                 trans_id, transdate, approved, source)
 		VALUES (var_account_id, 
-		        CASE WHEN in_account_class = 2 THEN in_amount[out_count] * -1 
+		        CASE WHEN in_account_class = 1 THEN in_amount[out_count] * -1 
 		        ELSE in_amount[out_count]
 		        END,
 		        in_transaction_id[out_count], in_datepaid,  coalesce(in_approved, true), 
@@ -740,7 +753,6 @@
         class text
 );
 
-
 --
 --  payment_get_vc_info has the same arch as company__list_locations, except for the filtering capabilities 
 --  This should be unified on the API when we get things working - David Mora
@@ -748,7 +760,7 @@
 CREATE OR REPLACE FUNCTION payment_get_vc_info(in_entity_credit_id int, in_location_class_id int)
 RETURNS SETOF payment_location_result AS
 $$
-DECLARE out_row RECORD;
+DECLARE out_row payment_location_result;
 	BEGIN
 		FOR out_row IN
                 SELECT l.id, l.line_one, l.line_two, l.line_three, l.city,


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.