This topic contains 8 replies, has 0 voices, and was last updated by michoel 7 years, 5 months ago.

  • Author
    Posts
  • #5874 Score: 0

    jharden
    • Contributions: 0
    • Level 1

    Hello NetSuite Community!

    I’m trying to write a SuiteScript that determines if a SalesOrder can be billed or not. I’d love a quick set of eyes on the script to see if I’ve forgotten about any details. Thanks in advance!

    Code:
    function canSalesOrderBeBilled(salesOrderId) {
    var salesOrderStatus = nlapiLookupField(‘salesorder’, salesOrderId, ‘statusRef’);

    if(salesOrderStatus == ‘pendingBilling’ || salesOrderStatus == ‘pendingBillingPartFulfilled’ || salesOrderStatus == ‘pendingApproval’) {
    return true;
    }

    if(salesOrderStatus == ‘billed’ || salesOrderStatus == ‘closed’ || salesOrderStatus == ‘cancelled’) {
    return false;
    }

    var filters = [
    new nlobjSearchFilter(‘createdfrom’, null, ‘anyof’, salesOrderId)
    ];

    var invoiceResults = nlapiSearchRecord(
    ‘invoice’,
    null,
    filters,
    null
    );

    var salesOrderResults = nlapiSearchRecord(
    ‘cashsale’,
    null,
    filters,
    null
    );

    if(invoiceResults || salesOrderResults) {
    return false;
    }

    return true;
    }
    This is a cached copy. Click here to see the original post.

  • #5875 Score: 0

    david.smith
    • Contributions: 0
    • Level 1

    What type of script is it and what record (if any) are you attaching it to?

  • #5876 Score: 0

    jharden
    • Contributions: 0
    • Level 1

    This would be for a User Event script. The issue I’m running into is it’s possible for some accounts to be configured to bill before shipping, so pendingFulfillment status does not give me a guarantee that the SalesOrder was not billed.

  • #5877 Score: 0

    david.smith
    • Contributions: 0
    • Level 1

    Use the orderstatus field. Here are the codes. (A-H)

    Status in UI
    Status Code

    Order:Pending Approval
    SalesOrd:A

    Order:Pending Fulfillment
    SalesOrd:B

    Order:Cancelled
    SalesOrd:C

    Order:Partially Fulfilled
    SalesOrd

    Order:Pending Billing/Partially Fulfilled
    SalesOrd:E

    Order:Pending Billing
    SalesOrd:F

    Order:Billed
    SalesOrd:G

    Order:Closed
    SalesOrd:H

  • #5878 Score: 0

    michoel
    • Contributions: 0
    • Level 1

    Originally posted by jharden

    View Post

    The issue I’m running into is it’s possible for some accounts to be configured to bill before shipping, so pendingFulfillment status does not give me a guarantee that the SalesOrder was not billed.

    You won’t catch cases where the Sales Order was only partially billed before fulfillment (you are just checking for the presence of at least one invoice, but that might not cover the the entire order).

    I would suggest looking at the line items, and checking for at least one item that is not closed, and ‘quantitybilled’ is less than ‘quantity’.

    Also, this could be combined into a single search:

    Code:
    var filters = [
    new nlobjSearchFilter(‘createdfrom’, null, ‘anyof’, salesOrderId)
    ];

    var invoiceResults = nlapiSearchRecord(
    ‘invoice’,
    null,
    filters,
    null
    );

    var salesOrderResults = nlapiSearchRecord(
    ‘cashsale’,
    null,
    filters,
    null
    );
    Like this:

    Code:
    var filters = [
    new nlobjSearchFilter(‘createdfrom’, null, ‘anyof’, salesOrderId),
    new nlobjSearchFilter(‘type’, null, ‘anyof’, [‘CustInvc’, ‘CashSale’]),
    ];

    var invoiceResults = nlapiSearchRecord(‘transaction’, null, filters);

  • #5879 Score: 0

    michoel
    • Contributions: 0
    • Level 1

    Originally posted by david.smith

    View Post

    Use the orderstatus field. Here are the codes. (A-H)

    david.smith I am curious why you would prefer that? The statusref field is more readable, and it’s documented in the Records Browser?


    david.smith replied on 03/22/2017, 08:12 AM: For the same reason I use internalid values instead of text.

  • #5880 Score: 0

    markjasonflores
    • Contributions: 0
    • Level 1

    Jharden, what record/trigger will you deploy this script into? If this is deployed on the SO itself, you can ditch the nlapiLookupField() and just use a normal nlapiGetFieldValue(). Also, like Michoel pointed out, its better if you combine the two searches at the bottom into one.

    Originally posted by michoel

    View Post

    Code:
    var filters = [
    new nlobjSearchFilter(‘createdfrom’, null, ‘anyof’, salesOrderId),
    new nlobjSearchFilter(‘type’, null, ‘anyof’, [‘CustInvc’, ‘CashSale’]),
    ];

    var invoiceResults = nlapiSearchRecord(‘transaction’, null, filters);

  • #5881 Score: 0

    jharden
    • Contributions: 0
    • Level 1

    Wow! Many thanks for the helpful replies.

    Combining the searches is definitely a great improvement. I ran across another method that seems like it would be bit cleaner. There’s an “amountunbilled” field on the SalesOrder that should work.

    This code snippet seems to be working fairly well. Any reason why this approach wouldn’t work?

    Code:
    function isEmpty(obj) {
    return obj === undefined || obj === null || obj === “”;
    }

    function isZero(obj) {
    return parseFloat(obj) == 0.0
    }

    var amountUnbilled = nlapiLookupField(‘salesorder’, 1212, ‘amountunbilled’);

    if(isEmpty(amountUnbilled) || isZero(amountUnbilled)) {
    // then there is nothing to bill!
    }


    david.smith replied on 03/27/2017, 08:27 AM: Your function isEmpty is unnecessary. JavaScript uses Falsy values. The only thing you would be missing is if the value was a zero string.

    https://developer.mozilla.org/en-US/docs/Glossary/Falsy

    This will do the same thing.

    if( !parseFloat(amountUnbilled) ){

    // nothing to bill

    }

  • #5882 Score: 0

    michoel
    • Contributions: 0
    • Level 1

    Originally posted by jharden

    View Post

    I ran across another method that seems like it would be bit cleaner. There’s an “amountunbilled” field on the SalesOrder that should work. This code snippet seems to be working fairly well. Any reason why this approach wouldn’t work?

    I forgot about that search field, that’s probably the best way.

You must be logged in to reply to this topic.