SuiteScript Tests - RESTlet
This page contains QuickMart RESTlet test cases.
Test Case #19: RESTlet - Receive E-commerce Orders (Integration)
Objective: Receive orders from Shopify via webhook.
Script Configuration
/**
* @NApiVersion 2.1
* @NScriptType Restlet
*
* QuickMart - Receive E-commerce Orders
* Integration Pattern: RECEIVE
*/
define(['N/record', 'N/search', 'N/log'], function(record, search, log) {
function doPost(requestBody) {
log.audit('Order Received', JSON.stringify(requestBody));
try {
// Validate required fields
if (!requestBody.customer_email || !requestBody.line_items) {
return { success: false, error: 'Missing required fields' };
}
// Find or create customer
var customerId = findOrCreateCustomer(requestBody);
// Create Sales Order
var salesOrder = record.create({
type: record.Type.SALES_ORDER,
isDynamic: true
});
salesOrder.setValue('entity', customerId);
salesOrder.setValue('orderstatus', 'A'); // Pending Approval
salesOrder.setValue('memo', 'Shopify Order: ' + requestBody.order_id);
salesOrder.setValue('custbody_priority_order', requestBody.priority || false);
// Set custom form for online orders
salesOrder.setValue('customform', getOnlineOrderForm());
// Add line items
requestBody.line_items.forEach(function(item) {
var nsItemId = findItemBySku(item.sku);
if (nsItemId) {
salesOrder.selectNewLine('item');
salesOrder.setCurrentSublistValue('item', 'item', nsItemId);
salesOrder.setCurrentSublistValue('item', 'quantity', item.quantity);
salesOrder.setCurrentSublistValue('item', 'rate', item.price);
salesOrder.commitLine('item');
}
});
var orderId = salesOrder.save();
log.audit('Order Created', 'SO ID: ' + orderId);
return {
success: true,
netsuite_order_id: orderId,
message: 'Order created successfully'
};
} catch (e) {
log.error('Order Creation Failed', e.message);
return {
success: false,
error: e.message
};
}
}
function findOrCreateCustomer(orderData) {
// Search by email
var results = search.create({
type: search.Type.CUSTOMER,
filters: [['email', 'is', orderData.customer_email]],
columns: ['internalid']
}).run().getRange({ start: 0, end: 1 });
if (results.length > 0) {
return results[0].id;
}
// Create new customer
var customer = record.create({ type: record.Type.CUSTOMER });
customer.setValue('companyname', orderData.customer_name);
customer.setValue('email', orderData.customer_email);
return customer.save();
}
function findItemBySku(sku) {
var results = search.create({
type: search.Type.INVENTORY_ITEM,
filters: [['itemid', 'is', sku]],
columns: ['internalid']
}).run().getRange({ start: 0, end: 1 });
return results.length > 0 ? results[0].id : null;
}
function getOnlineOrderForm() {
// Return internal ID of "Sales Order - Online" form
return 123; // Replace with actual form ID
}
return {
post: doPost
};
});
Sample Request
POST /app/site/hosting/restlet.nl?script=XXX&deploy=1
{
"order_id": "SHOP-12345",
"customer_email": "john@example.com",
"customer_name": "John Doe",
"priority": true,
"line_items": [
{ "sku": "PAPER-A4", "quantity": 10, "price": 12.00 },
{ "sku": "INK-HP", "quantity": 2, "price": 35.00 }
]
}
Test Case #20: RESTlet - Receive POS Payments
Objective: Receive payment data from POS system.
/**
* @NApiVersion 2.1
* @NScriptType Restlet
*
* QuickMart - Receive POS Payments
* Integration Pattern: RECEIVE
*/
define(['N/record', 'N/search', 'N/log'], function(record, search, log) {
function doPost(requestBody) {
try {
var invoiceId = findInvoice(requestBody.invoice_number);
if (!invoiceId) {
return { success: false, error: 'Invoice not found' };
}
var payment = record.transform({
fromType: record.Type.INVOICE,
fromId: invoiceId,
toType: record.Type.CUSTOMER_PAYMENT
});
payment.setValue('payment', requestBody.amount);
payment.setValue('paymentmethod', requestBody.payment_method);
payment.setValue('memo', 'POS Payment: ' + requestBody.reference);
var paymentId = payment.save();
return { success: true, payment_id: paymentId };
} catch (e) {
return { success: false, error: e.message };
}
}
function findInvoice(invoiceNumber) {
var results = search.create({
type: search.Type.INVOICE,
filters: [['tranid', 'is', invoiceNumber]],
columns: ['internalid']
}).run().getRange({ start: 0, end: 1 });
return results.length > 0 ? results[0].id : null;
}
return { post: doPost };
});
Test Case #21: RESTlet - Expose Stock Availability (Integration)
Objective: Allow external systems to query stock levels.
/**
* @NApiVersion 2.1
* @NScriptType Restlet
*
* QuickMart - Stock Availability Query
* Integration Pattern: EXPOSE
*/
define(['N/search', 'N/log'], function(search, log) {
function doGet(requestParams) {
var itemId = requestParams.itemId;
var sku = requestParams.sku;
var location = requestParams.location;
if (!itemId && !sku) {
return { error: 'itemId or sku required' };
}
var filters = [];
if (itemId) {
filters.push(['internalid', 'is', itemId]);
} else {
filters.push(['itemid', 'is', sku]);
}
var results = search.create({
type: search.Type.INVENTORY_ITEM,
filters: filters,
columns: [
'itemid',
'displayname',
'quantityavailable',
'quantityonhand',
'quantityonorder'
]
}).run().getRange({ start: 0, end: 1 });
if (results.length === 0) {
return { error: 'Item not found' };
}
var item = results[0];
return {
item_id: item.id,
sku: item.getValue('itemid'),
name: item.getValue('displayname'),
available: parseFloat(item.getValue('quantityavailable')) || 0,
on_hand: parseFloat(item.getValue('quantityonhand')) || 0,
on_order: parseFloat(item.getValue('quantityonorder')) || 0
};
}
return { get: doGet };
});
Sample Request/Response
GET /app/site/hosting/restlet.nl?script=XXX&deploy=1&sku=PAPER-A4
Response:
{
"item_id": "12345",
"sku": "PAPER-A4",
"name": "A4 Printer Paper",
"available": 150,
"on_hand": 200,
"on_order": 50
}
Test Case #22: RESTlet - Customer Loyalty Lookup
Objective: Allow POS to lookup customer loyalty data.
/**
* @NApiVersion 2.1
* @NScriptType Restlet
*
* QuickMart - Customer Loyalty Lookup
* Integration Pattern: EXPOSE
*/
define(['N/search', 'N/log'], function(search, log) {
const TIER_NAMES = { 1: 'Bronze', 2: 'Silver', 3: 'Gold', 4: 'Platinum' };
const TIER_DISCOUNTS = { 1: 0, 2: 5, 3: 10, 4: 15 };
function doGet(requestParams) {
var email = requestParams.email;
var phone = requestParams.phone;
if (!email && !phone) {
return { error: 'email or phone required' };
}
// Find customer
var custFilters = [];
if (email) custFilters.push(['email', 'is', email]);
if (phone) custFilters.push(['phone', 'is', phone]);
var custResults = search.create({
type: search.Type.CUSTOMER,
filters: custFilters,
columns: ['entityid', 'email', 'phone']
}).run().getRange({ start: 0, end: 1 });
if (custResults.length === 0) {
return { found: false, message: 'Customer not found' };
}
var customerId = custResults[0].id;
// Find loyalty record
var loyaltyResults = search.create({
type: 'customrecord_cust_loyalty',
filters: [['custrecord_cl_customer', 'is', customerId]],
columns: [
'custrecord_cl_tier',
'custrecord_cl_points',
'custrecord_cl_totalspent'
]
}).run().getRange({ start: 0, end: 1 });
if (loyaltyResults.length === 0) {
return {
found: true,
customer_id: customerId,
customer_name: custResults[0].getValue('entityid'),
loyalty: null,
message: 'No loyalty record'
};
}
var tier = parseInt(loyaltyResults[0].getValue('custrecord_cl_tier')) || 1;
return {
found: true,
customer_id: customerId,
customer_name: custResults[0].getValue('entityid'),
loyalty: {
tier: tier,
tier_name: TIER_NAMES[tier],
points: parseInt(loyaltyResults[0].getValue('custrecord_cl_points')) || 0,
total_spent: parseFloat(loyaltyResults[0].getValue('custrecord_cl_totalspent')) || 0,
discount_percent: TIER_DISCOUNTS[tier]
}
};
}
return { get: doGet };
});