duplicateRecord issue in 2.2.7

Hi,
I have a client (yes, just the one :D ), that is still on 2.2.7 (I think I’ll wait for 3.5 to be released/v2 before moving them to 3.x…).
They do sales order processing (mail order/internet sales). Orders sometimes need refunding, so I created a routine to ‘reverse’ the order & line items. The staff member picks the original invoice, chooses a ‘reason’ for the return (that decides what can then happen with the reversed invoice) and then clicks a button that duplicates the order & it’s line items.
This used to work fine, but now is occasionally going wrong and bringing in line items from invoices from years ago, as well as the correct ones!!!
I cannot see why this is happening. I am using a method that I got from the forums years ago, that loads the related line items into a variable, so I thought it might be a memory issue, but one client who had the problem has 2Gb of RAM on their PC (but another only 384Mb).

The first method that is called is

// processReturnsExchange [order_details_returns]
//handle return/exchange
//called from 'Make Return/Exchange' button

globals.pleaseWait();

//check a reason has been chosen
if (return_exchange_reason == null || return_exchange_reason == '')
{
	//branch depending on which reason chosen
	//there are different results depending on what reason is chosen
	//stock_adjust = 1 means stock levels should be adjusted
	//stock_adjust = 0 means stock levels should not be adjusted
	//lock_lines = 1 means line should be locked to not allow changes
	//lock_lines = 0 means line should be unlocked to allow changes
	//allow_lines = 1 means new lines are allowed on new invoice
	//allow_lines = 0 means new lines are not allowed on new invoice
	//duplicateInvoice(); then duplicates and sets values etc.
	
	switch( globals.reasonStatus )
	{
	case 1 : return_exchange_reason   = 'Returned/Exchanged';
			globals.original_order_id = ordersid ;
			globals.stock_adjust      = 1 ;
			globals.lock_lines        = 1 ;
			globals.allow_new_lines   = 0 ;
			duplicateInvoice();
			break ;
			
	case 2 : return_exchange_reason   = 'Returned/Exchanged';
			globals.original_order_id = ordersid ;
			globals.stock_adjust      = 1 ;
			globals.lock_lines        = 1 ;
			globals.allow_new_lines   = 1 ;
			duplicateInvoice();
			break ;
			
	case 3 : return_exchange_reason   = 'Returned/Exchanged';
			globals.original_order_id = ordersid ;
			globals.stock_adjust      = 1 ;
			globals.lock_lines        = 1 ;
			globals.allow_new_lines   = 1 ;
			duplicateInvoice();
			break ;
			
	case 4 : return_exchange_reason   = 'Returned/Exchanged';
			globals.original_order_id = ordersid ;
			globals.stock_adjust      = 1 ;
			globals.lock_lines        = 0 ;
			globals.allow_new_lines   = 1 ;
			duplicateInvoice();
			break ;
			
	case 5 : return_exchange_reason   = 'Returned/Exchanged';
			globals.original_order_id = ordersid ;
			globals.stock_adjust      = 1 ;
			globals.lock_lines        = 0 ;
			globals.allow_new_lines   = 1 ;
			duplicateInvoice();
			break ;
			
	case 6 : return_exchange_reason   = 'Returned/Exchanged';
			globals.original_order_id = ordersid ;
			globals.stock_adjust      = 1 ;
			globals.lock_lines        = 1 ;
			globals.allow_new_lines   = 1 ;
			duplicateInvoice();
			break ;
			
	case 7 : return_exchange_reason   = 'Returned/Exchanged';
			globals.original_order_id = ordersid ;
			globals.stock_adjust      = 0 ;
			globals.lock_lines        = 0 ;
			globals.allow_new_lines   = 0 ;
			duplicateInvoice();
			break ;
			
	case 8 : return_exchange_reason   = 'Returned/Exchanged';
			globals.original_order_id = ordersid ;
			globals.stock_adjust      = 0 ;
			globals.lock_lines        = 0 ;
			globals.allow_new_lines   = 1 ;
			duplicateInvoice();
			break ;
			
	default : break ;
	}
}
else
//it's already been done...
{
	plugins.dialogs.showWarningDialog( 'WARNING!',  'You cannot Refund/Exchange an Invoice again!',  'OK')
}

globals.ready();

the duplicateInvoice method is

//duplicateInvoice [order_details_returns]
//duplicates an invoice to allow for return
//called from processReturnsExchange

var tab_detail = orders_to_line_items; // save all the  detail records in memory 

var number_detail_rows = tab_detail.getSize(); // number of detail records 

//duplicate record
foundset.duplicateRecord(foundset.getSelectedIndex() ,true,true); //duplicates and selects new master record 

//save it to get PK
controller.saveData();

//assign defaults
original_inv_no     = invoice_no ;
invoice_no          = 'PF' + ordersid ;
original_order_id   = globals.original_order_id ;
original_order_date = orders_to_orders_original.date_order ;

//pick up setting based on reason
allow_new_lines = globals.allow_new_lines ;

//assign defaults
original_authcode = authcode ;

//clear some fields that may have data in from original
authcode   = '' ;
wp_transid = '' ;
converted  = '' ;

//sets paid using for refund
setRefundPaidUsing();

//sets actual reason based on id
return_exchange_reason = application.getValueListItems('returnsExchangesReasons').getValue(globals.reasonStatus, 1);

//loop thru line items, duplicating them to new order
for ( var i = 1 ; i <= number_detail_rows ; i++ ) // loop on previouly saved detail records 
{ 
	tab_detail.duplicateRecord(i,false,true); // duplicate the detail 
	tab_detail.order_id   = ordersid; // assigns the new master primary key to the detail record 
	tab_detail.invoice_no = invoice_no; // assigns the new master invoice no to the detail record 
	tab_detail.quantity   = tab_detail.quantity * -1; // reverse all quantities
	
	//pick up setting based on reason
	tab_detail.adjust_stock = globals.stock_adjust ;
	tab_detail.line_locked  = globals.lock_lines ;
} 

//recalc order totals
databaseManager.recalculate(foundset.getSelectedIndex());

//save
controller.saveData();

//allow it to be edited
controller.readOnly = false ;

Can anyone tell me what I might be doing wrong? Is it a bug in 2.2.7? Will there ever be any more updates to 2.2.7 if so?

Thanks,

Rafi

Servoy Developer
Version R2 2.2.7-build 339
Java version 1.5.0_07-87 (Mac OS X)

[Servoy Admin]
Server Information
Servoy version R2 2.2.7-build 339, repository version 27
Current time: Wed May 02 18:42:25 BST 2007
Uptime: 15 days 30 minutes 32 seconds

User Information
Logged in as: rafi

JDK Information
java.vm.name=Java HotSpot™ Client VM
java.vm.version=1.5.0_10-b03
java.vm.info=mixed mode
java.vm.vendor=Sun Microsystems Inc.

Operating System Information
os.name=Windows 2003
os.version=5.2
os.arch=x86

System Information
runtime.allocatedMemory=118824K
runtime.usedMemory=58520K

Memory/Performance Settings
servoy.maxClientHeap: 196

I don’t really know what goes wrong, but I have a few remarks:

  1. This

var number_detail_rows = tab_detail.getSize()

evaluates to a maximum of 40. If you have more detail records than that, it will fail to duplicate those. You should loop as for (var i = 1; i <= tab_detail.getSize()

  1. I would load both the original and the duplicated record into a variable and do your stuff from there. In my eyes that is safer than relying on the foundset index really staying the same.

Maybe that helps.

Hi Patrick,
thanks for replying.

patrick:
I don’t really know what goes wrong, but I have a few remarks:

  1. This

var number_detail_rows = tab_detail.getSize()

evaluates to a maximum of 40. If you have more detail records than that, it will fail to duplicate those. You should loop as for (var i = 1; i <= tab_detail.getSize()

  1. I would load both the original and the duplicated record into a variable and do your stuff from there. In my eyes that is safer than relying on the foundset index really staying the same.

Maybe that helps.

Regarding point 1. Where does it state that it will only return a maximum of 40? I’m pretty sure I’ve used this before for more than 40 detail records and it has worked correctly. In this problem scenario there were less than 40 details.
Secondly, if I use your loop method, each time I duplicate a detail record won’t the size get bigger and the loop never end? I think I saw someone commenting on this elsewhere. I just want to loop thru the original detail records only.

  1. I will try and put the parent & duplicates into variables and see if that helps. (Not at client again until next week)

Thanks,
Rafi.

Hello Rafig,

getSize() will return a maximum of 200 for a normal foundset and 40 for a related foundset. I don’t know where it says that, but it’s the way it is. If you loop using getSize() and you hit the limit, getSize() will update itself to the next 200 (or 40). So looping like that is no problem.

You are correct that looping as I suggest might give you trouble, but that will be no problem anymore when you use my approach with the record variable.

Thanks :D