Search code examples
netsuitesuitescriptsuitescript2.0

SuiteScript 2.0: Error thrown when applying partial customer payment against an invoice


Any help on this would be greatly appreciated.

I am using a map/reduce script to create a new customer payment record (from an invoice record) which is a partial payment of the invoice. This action needs to occur in the MAP stage.

Example: Amount due on the invoice is (say) £26.66, and I want to apply a £2.00 payment against this.

The following snippet appears to work when applying the FULL payment of the invoice:

        var customerpayment = record.transform({
            fromType : rectype, 
            fromId: recid, 
            toType: 'customerpayment',
            isDynamic: true
        })

            if (amount > 0){

            var linecount = customerpayment.getLineCount({ sublistId: 'apply' }); 

            for (var i = 1; i < linecount; i++) {
                
            var refnum = customerpayment.getCurrentSublistValue({sublistId: 'apply', fieldId: 'refnum', line: i });
                
                if (refnum == tranid) { 
                    log.audit ('refnum == tranid. Line no: ' + i, refnum + ' | ' + tranid); 
                    
                    //isDynamic = TRUE
                    customerpayment.selectLine({sublistId: 'apply', line: i });

                    //Mark "apply' FALSE to clear the apply box (this would clear the "payment" header field as well)
                    customerpayment.setCurrentSublistValue({sublistId: 'apply', fieldId: 'apply', value: false });

                    //Now set the payment header field with the amount you want to apply
                    customerpayment.setValue({fieldId: 'payment', value: amount});      
                   
                    //Now select TRUE on apply. This (should) copy/paste the payment amount automatically as it does via the UI.
                    customerpayment.setCurrentSublistValue({sublistId: 'apply', fieldId: 'apply', value: true });
                     
                    //For sanity sake, just populate the apply 'total' line with the same amount as payment field. In case it did not do it automatically.
                    customerpayment.setCurrentSublistValue({sublistId: 'apply', fieldId: 'total', value: amount });

                    var getTotal = customerpayment.getCurrentSublistValue({sublistId: 'apply', fieldId: 'total', line: i }); 
                    var getAllTotal = customerpayment.getValue({fieldId: 'payment'});                       

                    //Quick check that 'payment' header field and apply total field are the same
                    log.audit ('payment | payment line', getAllTotal + ' | ' + getTotal);   

                    break;
                }
            }
            
            //Now save record
            var payment_id = customerpayment.save({
                enableSourcing : true,
                ignoreMandatoryFields: true
            })

The same code above sadly fires the following error when adjusting amount that is SMALLER than the amount due on the invoice.

enter image description here

I have reached a holt at this point so any assistance would be greatly appreciated. Interestingly, I have managed to create a user event script which successfully does just this. Not sure if its down to the script type that could be preventing this action? Thanks in advance!


Solution

  • when you create the payment record you have to set the payment amount at the body level. And since you are in dynamic mode you have to set it before you start applying.

    customerpayment.setValue({fieldId:'payment', value:amount});
    customerpayment.setValue({fieldId:'autoapply', value:false}); //so only the invoice of interest will receive the payment
    

    then apply to your lines.

    if(refNum == tranid){
       customerpayment.setCurrentSublistValue({sublistId: 'apply', fieldId: 'apply', value: true }); // IIRC this is all you need to do. I think in dynamic mode NS fills in the amount or the amount owing whichever is less. But if not proceed:
    
       var canApply = Math.min(amount, customerpayment.getCurrentSublistValue({sublistid:'apply', fieldId:'amount'}));
    
       customerpayment.setCurrentSublistValue({sublistId: 'apply', fieldId: 'amount', value: canApply});
       break;
    }