Netsuite: How to create custom invoices and regular invoices for Sales Order using Netsuite Webservice

Netsuite: How to create custom invoices and regular invoices for Sales Order using Netsuite Webservice

Well, guys I’ve been struggling with how to create invoices using the netsuite webservice whether you are using Php, Ruby, Python or a different language basically what you have to do is to send in you request the following information in this format for custom invoices which means a custom list of item with quantity:


<env:Body>
<platformMsgs:add>
  <platformMsgs:record xsi:type="tranSales:Invoice">
    <tranSales:createdFrom internalId="60237"/>
    <tranSales:tranDate>2015-08-13T19:00:00Z</tranSales:tranDate>
    <tranSales:itemList>
      <tranSales:item>
        <tranSales:item internalId="2866"/>
        <tranSales:orderLine>1</tranSales:orderLine>
        <tranSales:quantity>3.0</tranSales:quantity>
      </tranSales:item>
    </tranSales:itemList>
    <tranSales:customFieldList>
      <platformCore:customField xsi:type="platformCore:StringCustomFieldRef" scriptId="mycustom_field_goes_here">
      <platformCore:value>somevaluehere</platformCore:value>
    </platformCore:customField>
    </tranSales:customFieldList>
  </platformMsgs:record>
</platformMsgs:add>
</env:Body>

Let me explain to you what it means each node:

<tranSales:item internalId="2866"/> 

This is the internal_id from the product you are adding to the invoice if you don’t know which one it is you have a make a search by sku or id or something and them grab the internal

<tranSales:orderLine>1</tranSales:orderLine>:

This is the number of the line in the original sale order(order) you just need to add this reference in order to be able to create the association to the sale order in the node:

<tranSales:createdFrom internalId="60237"/>

If you don’t want to build a custom invoice with a specific items(item_list) you just need to create an invoice with the createdFrom(Sale Order) attribute and the invoice should include all the items included in the sale order, this is the Xml request you should send to Netsuite webservice:

<env:Body>
 <platformMsgs:add>
   <platformMsgs:record xsi:type="tranSales:Invoice">
     <tranSales:createdFrom internalId="60237"/>
     <tranSales:tranDate>2015-08-13T19:00:00Z</tranSales:tranDate>
   </platformMsgs:record>
 </platformMsgs:add>
 </env:Body>

and now some of the code made in Ruby for creating custom invoices(specific items and quantity from an invoice) and regular invoices for one Sale order remember that I’m using this Gem:https://github.com/NetSweet/netsuite

The following code is creating one invoice per fulfillment(sales order can have multiple item fulfillments)

 def create_fulfillment_invoices(order)
   fulfillments = search_sale_order_fulfillments(order.ns_sales_order_id).results

   fulfillments.each do |fulfillment|
     invoice = NetSuite::Records::Invoice.new
     invoice.created_from = NetSuite::Records::RecordRef.new(:internal_id => order.ns_sales_order_id)
     invoice.tran_date = (Time.now + 19.hours).xmlschema

     item_list = NetSuite::Records::InvoiceItemList.new
     item_list.item = build_invoice_item_fulfillment(fulfillment.internal_id, order.ns_sales_order_id)
     invoice.item_list = item_list
     invoice.add
   end
 end

 def search_sale_order_fulfillments(sale_order_id)
   order_fulfillment_conditions = [
     {
       field: 'createdFrom',
       operator: 'anyOf',
       type: 'SearchRecordField',
       value: [ NetSuite::Records::SalesOrder.new(internal_id: sale_order_id) ]
     },
     {
       field: 'type',
       operator: 'anyOf',
       type: 'SearchEnumMultiSelectField',
       value: [ "_itemFulfillment" ]
     }
   ]

   NetSuite::Records::Transaction.search(
     criteria: {
       basic: order_fulfillment_conditions
     }
   )
 end

 def build_invoice_item_fulfillment(fulfillment_internal_id, sale_order_internal_id, is_last_fulfillment)
   fulfillment_details = NetSuite::Records::ItemFulfillment.get(internal_id: fulfillment_internal_id)
   items_included = fulfillment_details.attributes[:item_list].item.map do |item|
     internal_id = item.attributes[:item].internal_id
     line = item.attributes[:order_line]
     quantity = item.attributes[:quantity]
     build_invoice_item_list(internal_id, quantity, line)
   end

   include_shipping_item_last_invoice(items_included, is_last_fulfillment, sale_order_internal_id)
 end

 def build_invoice_item_list(internal_id, quantity, line)
   NetSuite::Records::InvoiceItem.new({
     item: { internal_id: internal_id },
     order_line: line,
     quantity: quantity.to_f
   })
 end

 def include_shipping_item_last_invoice(items_included, is_last_fulfillment, sale_order_internal_id)
   if is_last_fulfillment
     add_shipping_item = append_shipping_item(sale_order_internal_id)
     items_included << add_shipping_item if add_shipping_item
   else
     items_included
   end
 end

 def append_shipping_item(sale_order_internal_id)
   sale_order = NetSuite::Records::SalesOrder.get(internal_id: sale_order_internal_id)

   sale_order_items = sale_order.item_list.items
   shipping_item = sale_order_items.find{ |sale_order_item| sale_order_item.attributes[:item].attributes[:name] == 'Shipping Item'}

   if shipping_item
     build_shipping_item(shipping_item)
   end
 end

 def build_shipping_item(item)
   line = item.attributes[:line]
   internal_id = item.attributes[:item].internal_id
   quantity = item.attributes[:quantity]
   amount = item.attributes[:amount].try(:to_f)

   NetSuite::Records::InvoiceItem.new({
     item: { internal_id: internal_id },
     order_line: line,
     quantity: quantity.to_f,
     amount: amount
   })
 end

If you just want to create a invoice for a sale order that includes the same details, items, subtotal and total this is what you’re looking for:

def create
  invoice = NetSuite::Records::Invoice.new
  # create the reference to the internal_id sale order within Netsuite
  invoice.created_from = NetSuite::Records::RecordRef.new(:internal_id => sale_order_internal_id_from_netsuite)
  invoice.tran_date = (Time.now + 19.hours).xmlschema
  invoice.add
end

Some relevant terms and resources:

Invoice
https://system.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2014_1/schema/record/invoice.html?mode=package
InvoiceItemList
https://system.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2014_1/schema/other/invoiceitemlist.html?mode=package
InvoiceItem
https://system.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2014_1/schema/other/invoiceitem.html?mode=package

Some Ruby classes used in this post:
NetSuite::Records::Invoice.new
NetSuite::Records::InvoiceItemList.new
NetSuite::Records::InvoiceItem.new
NetSuite::Records::ItemFulfillment
NetSuite::Records::SalesOrder.get
NetSuite::Records::InventoryItem

That’s it guys hope you learn stuff in this post, see you later.

No Comments

Post A Comment