Marty Zigman - The NetSuite Expert

Conversations with Marty Zigman

Certified Administrator • ERP • SuiteCloud

Prolecto Labs Accelerator Templates

Use NetSuite SuiteScript to Automate Posting Customer Deposits to Invoices

NetSuite Technical

Tags: , , , ,

This article is relevant if you working to automate the posting of customer deposits to invoices in NetSuite and you need SuiteScript reference information.

Background

NetSuite offers a way to post customer deposits (appropriately as liabilities) received by customers typically for advanced payments before goods are delivered.  I like to think of these similar to retainers commonly used in professional services organizations, such as attorney firms.  Smartly, NetSuite will automatically apply a customer deposit to a freshly generated (unpaid) invoice if it both transaction documents (the customer deposit and the invoice) is connected to a common Sales Order.

However, while the Sales Order connection is convenient, it also can be restrictive.  In my article last week, Applying NetSuite Sales Order Customer Deposits on Independent Invoices, I demonstrated a trick to apply Customer Deposits to Invoices not connected to a Sales Order.

As I have been studying how to increase my firm’s billing operations, which in many respects, may resemble a staffing firm as we heavily use NetSuite Advanced Projects the Timesheet as the basis for accounting for services, I began to see ways that the Sales Order was cumbersome to work with.   While subject to another article, what I had to do is break the connection, in general, to the Sales Order as an organizing transactional concept.

Once you don’t have a Sales Order between your time entries and your invoice work, then NetSuite’s automatic customer deposit application no longer functions.  What I needed was to preserve that automatic function so that unpaid invoices could be immediately paid based on monies (deposits) on account.

Automating Application of Customer Deposits to Open Invoices

Early in my work to automate this function, I thought I would try to apply a customer payment to the invoice.   There is a transform function that will get the payment record in play.  In this case, I would use the “Deposits” sublist to apply payment to the invoice.  While this works in the user interface, it does not behave the same way via SuiteScript.    I could see the deposit lines but I could not get them to actually apply.  I speculate that applying a deposit from the Customer Payment screen actually does another transform behind the scenes.

As I inspected the record structures, I could see there is a record called a Deposit Application which effectively allows a many-to-many (M:M) relationship between Customer Deposits and Invoices.  NetSuite does not provide a user interface (UI) to create one of these deposit application records from scratch.  To create one, you always start from a Customer Deposit record.

Although there is a reference in the SuiteScript Record Browser, I was frustrated as there is no documentation on how to really work with this record.  Per the NetSuite Help documentation, there is no Tranform support Deposit Application record.   Yet, unwilling to concede, I found a clue by inspecting the URL for the Deposit Application and I could see “transform” as one of the parameters (side note: always watch what is happening in the URL as it is a clue to how the system is built).  With some trial-and-error, I was able to figure out what I think is an undocumented feature to get what I needed.

SuiteScript Reference for Working with Customer Deposit Application Records

The following function was being called in an invoice AfterSubmit UserEvent.   I have added comments to help illustrate what is happening.  As of the time of this article, this transform function does not appear to support the respective record types; as such, use with care.

function applyDeposits(invId, cusId){ //invoice id and customer id
	var func = 'applyDeposits ';
	var depositbalance = nlapiLookupField('customer', cusId, 'depositbalance')

	//if there are no monies to apply, avoid doing work
	if (depositbalance > 0){
		//find all the related open deposit records
		var filters = new Array();
		filters[0] = new nlobjSearchFilter('entity', null, 'anyof', cusId);
		//indicates not full applied
		filters[1] = new nlobjSearchFilter('status', null, 'noneof', 'CustDep:C');
		filters[2] = new nlobjSearchFilter('mainline', null, 'is', 'T');
		//don't try to get those deposits hard linked to sales orders
		filters[3] = new nlobjSearchFilter('salesorder', null, 'anyof', '@NONE@'); 

		var columns = new Array();
		columns[0] = new nlobjSearchColumn('internalid').setSort(false);

		//hunt for the records
		var records = nlapiSearchRecord('customerdeposit', null, filters, columns);

		if (!records){
			nlapiLogExecution('DEBUG', func  + 'Found no deposit records; but they were expected.');
			return
		};

		nlapiLogExecution('DEBUG', func + ' starting deposit application work');
		for ( var r = 0; r < records.length; r++ ) {
			//transform below does not appear documented; but works as expected
			var deposit = nlapiTransformRecord('customerdeposit', records[r].getId(), 'depositapplication');

			deposit.setFieldValue('trandate', nlapiDateToString(new Date()));
			deposit.setFieldValue('memo', 'Applied Invoice: ' + new Date());

			//walk the invoice list that we want to apply; find the invoice we are working on
			var a = deposit.getLineItemCount('apply');
			for (var i = 1; i <= a; i++){
				if ( deposit.getLineItemValue('apply', 'internalid', i) == invId ){
					nlapiLogExecution('DEBUG', func  + 'working on invoice line:' + i, deposit.getLineItemValue('apply', 'refnum', i));
					//find the related line and mark it on; appears safe to apply as much as you can; NetSuite appears to
					// handle if there is insufficient funds and it will match the amount of the invoice
					deposit.setLineItemValue('apply', 'amount', i, deposit.getLineItemValue('apply', 'total', i));
					deposit.setLineItemValue('apply', 'apply', i, 'T');
				};
			};
			nlapiSubmitRecord(deposit);
		};
	};
};

Demand More from Your NetSuite Business System

NetSuite was designed to be optimized for business requirements. The platform opens up your space for innovation which can streamline your business operation. If you would like to get more out of NetSuite, let’s have a conversation.

Marty Zigman

Holding all three official certifications, Marty is regarded as the top NetSuite expert and leads a team of senior professionals at Prolecto Resources, Inc. He is a former Deloitte & Touche CPA and has held CTO roles. For over 30 years, Marty has produced leadership in ERP, CRM and eCommerce business systems. Contact Marty to set up a conversation.

More Posts - Website - Twitter - Facebook - LinkedIn - YouTube

About Marty Zigman

Marty Zigman

Holding all three official certifications, Marty is regarded as the top NetSuite expert and leads a team of senior professionals at Prolecto Resources, Inc. He is a former Deloitte & Touche CPA and has held CTO roles. For over 30 years, Marty has produced leadership in ERP, CRM and eCommerce business systems. Contact Marty to set up a conversation.

Biography • Website • X (Twitter) • Facebook • LinkedIn • YouTube

21 thoughts on “Use NetSuite SuiteScript to Automate Posting Customer Deposits to Invoices

  1. HIlde Van Heddegem says:

    How to create the postings BE GAAP for inventory
    Next to asset account and vendor account
    Extra posting 3 é 609 account
    Thanks

  2. Marty Zigman says:

    Hello Hilde,

    I don’t believe I can offer you thinking. I have no background in BE GAAP requirements. However, if you can point me to an explanation of the outcome, I may be able to comment.

    Marty

  3. Gabriel Lawrence says:

    Hi Marty, This looks like pretty close to what I was looking for, but instead of customer deposits I need the script to apply an unapplied payments / credit memos to new invoices. Do you have any experience using something similar with those two records?

    Thanks,

    Gabe

  4. Marty Zigman says:

    Hi Gabriel,

    Yes, we are experts in the customer deposit area but we have done extensive work with unapplied payments and auto applying credit memos. If you can describe the way you want things applied, we can script it.

    Marty

  5. Edgar Moran says:

    Hi Marty,

    To set the JE as approved, can be do it by default on creation or should be when it is updated? So far It seems I can set the credit list as the JE is available only when it has been approved. Thanks

  6. Amy says:

    Hi Marty,
    In the scenario that both the bill and bill payment or invoice and payment are all recorded as Journal Entries, is there a way to mass apply them to each other to close them out?

  7. Marty Zigman says:

    Hi Amy,

    Yes, via script you could produce that application using a Mass Update. So long as you can emulate the process with the UI, you should be able to script it. We have done this for clients where they have many old records that were not properly applied.

    Marty

  8. Rajitha says:

    Hi Marty,

    Can we create the invoice from the billable expense record?

  9. Marty Zigman says:

    You can set a billable expense with the name of a customer / project and then, when creating invoices, the billable expense line will become a candidate to invoice during the next invoice attempt for that customer / project.

  10. Enrique says:

    Hello! I came here because I was looking for automate the creation of a customer deposit when a new sale is entered with some specific custom fields.

    I connected my e-commerce to net suite and we are saving the PayPal data like transaction ID and other stuff in custom fields in a new sales order.

    The thing is, once I create and save this sale order, can we automatically create a customer deposit using in information stored in my fields?

    Thank you Marty

  11. Marty Zigman says:

    Yes, if you are using NetSuite Sales orders, then when you created the Customer Deposit, reference the Sales Order. It is native. This will then link the sales order and subsequent invoices will automatically be paid from the customer deposit.

    In this article use case, we have no sales orders so we need a script to auto-apply to invoices.

    Marty

  12. Enrique says:

    Marty, thank you for your reply.

    Sales orders are created automatically. But I didn’t understand once they are created how do we automatically create a customer deposit if we detect that a specific custom fields of that order is filled out (fields with PayPal information)

    Is that possible? Where do I configure this?

    Thank you so much

  13. Marty Zigman says:

    Hello Enrique,

    Please read this article to help orient you with out of the box options to drive a customer deposit creation from a sales order:
    https://blog.prolecto.com/2016/10/02/using-netsuite-payment-methods-to-drive-customer-deposits/

    Also, in our Customer Deposit Generator, we have a mechanism to automatically create customer deposits based on payment methods when NetSuite’s native approach does not work. The script is relatively simple to implement.

    Marty

  14. David Ross says:

    Marty.

    I am trying to run the script in this article and Netsuite returns SSS_MISSING_REQD_ARGUMENT ‘ID’ error.

    Any idea why?

  15. Marty Zigman says:

    David,

    The code may need to be enhanced to check for null ID situations being passed to the function.

    Marty

  16. David Ross says:

    Thank you for your reply Marty

  17. brus says:

    Hi Marty,
    Hope you are doing good !

    My question is below.

    How many records i can check in deposit record. Can you please help me duo to i have 35k+ records need to check inside the deposit record, is it posible?

  18. Marty Zigman says:

    Hello Brus,

    I am not sure of limitations; but I would not be surprised if that many lines may have problems. I am generally nervous about transactions that have more than 1,000 lines.

    Marty

  19. Avinash says:

    While transforming Invoice into Customer payment using script, rather than posting to Bank account system is posting it to Undeposited funds account. Tried setting ‘undepfunds’ as ‘F’ worked in Sandbox but not in Production. Any comments/suggestions here?

  20. Marty Zigman says:

    Hello Avinash,

    I recommend you let payment methods drive the selection of Undeposited Funds vs. specific accounts. This way you won’t have issues with the logic possibly being off due to internal IDs.

    Marty

Leave a Reply

Your email address will not be published. Required fields are marked *