The extension is created to display the transaction history of sub customers of the user.
- We added a new tab “Sub Customers” in my account menu
- On clicking the link the user will redirect to new page which list the sub customers of the logged user
- On clicking each sub customer, the user will redirect to corresponding transaction history page
javascript
1. JJ.sub_Customer_List.subcustomer
define(
'JJ.sub_Customer_List.subcustomer'
, [
'JJ.sub_Customer_List.subcustomer.View',
'JJ.sub_Customer_List.subcustomer.TransactionHistory.View',
'AjaxRequestsKiller',
'underscore',
'Utils',
'MyAccountMenu',
'ListHeader.View'
]
, function (
subcustomerView,
subcustomerTransactionHistoryView,
AjaxRequestsKiller,
_,
Utils,
MyAccountMenu,
ListHeaderView
) {
'use strict';
return {
mountToApp: function mountToApp(container) {
var layout = container.getComponent('Layout');
var pageType = container.getComponent('PageType');
var myAccountMenu = MyAccountMenu.getInstance();
myAccountMenu.addEntry({
name: Utils.translate('Sub Customers'),
id: 'subcustomers',
index: 6
});
myAccountMenu.addSubEntry({
entryId: 'subcustomers',
id: 'sub-customers',
name: Utils.translate('List of Sub Customers'),
url: 'sub-customers',
index: 1
});
pageType.registerPageType({
name: 'List of Sub Customers',
routes: ['sub-customers'],
view: subcustomerView,
});
pageType.registerPageType({
name: 'TransactionHistory',
routes: ['&userstransactionhistory=*id', '&userstransactionhistory=*id?:options'],
view: subcustomerTransactionHistoryView,
defaultTemplate: {
name: 'jj_orderhistorylist.tpl',
displayName: 'Transaction History Default',
thumbnail: Utils.getThemeAbsoluteUrlOfNonManagedResources(
'img/default-layout-transaction-list.png'
)
}
});
_.extend(ListHeaderView.prototype, {
setSelecteds: _.wrap(ListHeaderView.prototype.setSelecteds, function wrappedInitialize(fn, options) {
fn.apply(this, _.toArray(arguments).slice(1));
var url_options = _.parseUrlOptions(Backbone.history.fragment);
//console.log("url_options",url_options)
this.subcustomerId = this.getSelectedSearch(url_options.subcustomerId);
}),
getSelectedSearch: function (url_value) {
return url_value;
},
updateCollection: function () {
let range = null;
var { collection } = this;
if (this.selectedRange) {
range = {
// @property {String} from
from:
this.selectedRange.from ||
(this.allowEmptyBoundaries ? '' : this.rangeFilterOptions.fromMin),
// @property {String} to
to:
this.selectedRange.to ||
(this.allowEmptyBoundaries ? '' : this.rangeFilterOptions.toMax)
};
}
// @lass Collection.Filter
collection.update &&
collection.update(
{
// @property {value:String} filter
filter: this.selectedFilter,
// @property {RangeFilter} range
range: range,
// @property {value:String} sort
sort: this.selectedSort,
// @property {String} order
order: this.order,
page: this.page,
// @property {Number} killerId
killerId: AjaxRequestsKiller.getKillerId(),
subcustomerId: this.subcustomerId
},
this
);
// @class ListHeader.View
return this;
},
});
}
};
});
2. JJ.sub_Customer_List.subcustomer_home
define(
'JJ.sub_Customer_List.subcustomer_home'
, [
'JJ.sub_Customer_List.subcustomer.View',
'underscore',
'Utils', 'MyAccountMenu'
]
, function (
subcustomerView,
_,
Utils, MyAccountMenu
) {
'use strict';
return {
mountToApp: function mountToApp(container) {
var layout = container.getComponent('Layout');
var pageType = container.getComponent('PageType');
var myAccountMenu = MyAccountMenu.getInstance();
myAccountMenu.addEntry({
name: Utils.translate('Sub Customers'),
id: 'subcustomers',
index: 6
});
myAccountMenu.addSubEntry({
entryId: 'subcustomers',
id: 'sub-customers',
name: Utils.translate('List of Sub Customers'),
url: 'sub-customers',
index: 1
});
pageType.registerPageType({
name: 'List of Sub Customers',
routes: ['sub-customers'],
view: subcustomerView,
});
}
};
});
3. subcustomer.View.js
// @module JJ.sub_Customer_List.subcustomer
define('JJ.sub_Customer_List.subcustomer.View'
, [
'jj_sub_customer_list_subcustomer.tpl'
, 'JJ.sub_Customer_List.subcustomer.Model'
, 'Backbone'
]
, function (
jj_sub_customer_list_subcustomer_tpl
, JJsub_Customer_ListsubcustomerModel
, Backbone
) {
'use strict';
// @class JJ.sub_Customer_List.subcustomer.View @extends Backbone.View
return Backbone.View.extend({
template: jj_sub_customer_list_subcustomer_tpl
, attributes: {
'class': 'subcustomerlist'
}
, initialize: function (options) {
_.extend(this, options);
var self = this;
this.application = options.application;
this.model = new JJsub_Customer_ListsubcustomerModel();
var promise = jQuery.Deferred();
this.model.fetch({ data: { SubList: "List" } }).done(function (result) {
promise.resolve();
this.customerlist = result
self.render()
});
}
, getSelectedMenu: function () {
return 'subcustomerlist';
}
, getBreadcrumbPages: function () {
return {
text: this.title
, href: '/sub-customers'
};
}
, events: {
}
, bindings: {
}
, childViews: {
}
, getContext: function getContext() {
var subcustomers = this.model.get('customerlist') || [];
//console.log("subcustomers", subcustomers);
var uniquesubcustomer = [];
var unique = subcustomers?subcustomers.filter(function (element) {
var isDuplicate = uniquesubcustomer.includes(element.internalid);
if (!isDuplicate) {
uniquesubcustomer.push(element.internalid);
return true;
}
return false;
}):[];
subcustomers = unique
var subcustomerarray = _.reject(subcustomers, function (num) {
return num.internalid == "000"
})
return {
subcustomers: subcustomerarray.length > 0,
subCustomerList: subcustomerarray
};
}
});
});
4. subcustomer.TransactionHistory.View
define(
'JJ.sub_Customer_List.subcustomer.TransactionHistory.View'
, [
'ListHeader.View'
, 'Backbone.CollectionView'
, 'Backbone.CompositeView'
, 'RecordViews.View'
, 'SC.Configuration'
, 'GlobalViews.Pagination.View'
, 'jj_orderhistorylist.tpl'
, 'Handlebars'
, 'Backbone'
, 'underscore'
, 'jQuery', 'Utils'
, 'Profile.Model'
, 'Transaction.Collection'
, 'TransactionHistory.Collection'
, 'TransactionHistory.List.View'
, 'Transaction.List.View'
, 'JJ.sub_customer.TransactionHistory.Collection'
]
, function (
ListHeaderView
, BackboneCollectionView
, BackboneCompositeView
, RecordViewsView
, Configuration
, GlobalViewsPaginationView
, jj_orderhistorylist_tpl
, Handlebars
, Backbone
, _
, jQuery, Utils
, ProfileModel
, TransactionCollection
, TransactionHistoryCollection
, TransactionHistoryListView
, TransactionListView
, JJsub_customerTransactionHistoryCollection
) {
'use strict';
// @class TransactionHistory.List.View view list of transaction history @extend Backbone.View
return TransactionHistoryListView.extend({
template: jj_orderhistorylist_tpl,
title: Utils.translate('Transaction History'),
page_header: Utils.translate('Transaction History'),
attributes: {
id: 'TransactionHistory',
class: 'TransactionHistory'
},
initialize: function (options) {
let page = '1';
if (options.routerArguments && options.routerArguments[0]) {
var params = Utils.parseUrlOptions(options.routerArgument);
if (params.page) {
page = params.page.toString();
}
}
this.options = options;
this.options.page = page;
this.application = options.application;
this.profileModel = ProfileModel.getInstance();
this.subcustomerId = options.routerArguments && options.routerArguments[0];
//console.log('subcustomerId', this.subcustomerId );
this.collection = new JJsub_customerTransactionHistoryCollection()
this.collection.subcustomerId = this.subcustomerId;
//this.collection.set({ subcustomerId: subcustomerId });
//console.log("this.collection", this.collection)
this.listenCollection();
this.collection.on('reset', this.showContent, this);
const today = new Date();
const isoDate = `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`;
this.rangeFilterOptions = {
fromMin: '1800-01-02',
fromMax: isoDate,
toMin: '1800-01-02',
toMax: isoDate
};
this.listHeader = new ListHeaderView({
view: this,
application: this.application,
collection: this.collection,
filters: this.filterOptions,
sorts: this.sortOptions,
rangeFilter: 'date',
rangeFilterLabel: Utils.translate('From'),
hidePagination: true,
allowEmptyBoundaries: true,
subcustomerId:this.subcustomerId
});
},
// @method listenCollection
listenCollection: function () {
this.setLoading(true);
this.collection.on({
request: jQuery.proxy(this, 'setLoading', true),
reset: jQuery.proxy(this, 'setLoading', false)
});
},
// @method setLoading @param {Boolean} bool
setLoading: function (bool) {
this.isLoading = bool;
},
// @method getSelectedMenu @return {String}
getSelectedMenu: function () {
return 'transactionhistory';
},
// @method getBreadcrumbPages
getBreadcrumbPages: function () {
return {
text: this.title,
href: '/transactionhistory'
};
},
// @property {Array} filterOptions Array of default filter options filters always apply on the original collection
filterOptions: [
{
value: 'CustCred,CustPymt,CustDep,DepAppl,CustInvc,CashSale,SalesOrd',
name: Utils.translate('Show all record types'),
selected: true
},
{
value: 'CustCred',
name: Utils.translate('Show Credit Memo'),
permission: 'transactions.tranCustCred.1'
},
{
value: 'CustPymt',
name: Utils.translate('Show Payment'),
permission: 'transactions.tranCustPymt.1'
},
{
value: 'CustDep',
name: Utils.translate('Show Deposit'),
permission: 'transactions.tranCustDep.1'
},
{
value: 'DepAppl',
name: Utils.translate('Show Deposit Application'),
permission: 'transactions.tranDepAppl.1'
},
{
value: 'CustInvc',
name: Utils.translate('Show Invoices'),
permission: 'transactions.tranCustInvc.1'
},
{
value: 'CashSale',
name: Utils.translate('Show Cash Receipts'),
permission: 'transactions.tranCashSale.1'
},
{
value: 'SalesOrd',
name: Utils.translate('Show Sales Order'),
permission: 'transactions.tranSalesOrd.1'
}
],
// @property {Array} sortOptions Array of default sort options sorts only apply on the current collection
// which might be a filtered version of the original
sortOptions: [
{
value: 'trandate,internalid',
name: Utils.translate('by Date'),
selected: true
},
{
value: 'tranid',
name: Utils.translate('by Number')
},
{
value: 'amount',
name: Utils.translate('by Amount')
}
],
getTypeLabel: function (recordtype) {
var type;
switch (recordtype) {
case 'creditmemo':
type = _('Credit Memo').translate();
break;
case 'customerpayment':
type = _('Payment').translate();
break;
case 'customerdeposit':
type = _('Deposit').translate();
break;
case 'depositapplication':
type = _('Deposit Application').translate();
break;
case 'invoice':
type = _('Invoice').translate();
break;
case 'cashsale':
type = _('Cash Receipt').translate();
break;
case "salesorder":
type = _('Sales Order').translate();
break;
}
return type;
}
//@method getTypeUrl @return {String}
, getTypeUrl: function (recordtype, internalid) {
var type = recordtype
, record_root_url = 'transactionhistory/' + type;
if (type === 'invoice') {
record_root_url = 'invoices';
}
else if (type === 'returnauthorization') {
record_root_url = 'returns';
}
else if (type === 'salesorder') {
record_root_url = 'purchases/view/salesorder';
}
return record_root_url + '/' + internalid;
},
childViews: {
'ListHeader.View': function () {
return this.listHeader;
},
'Records.Collection': function () {
var self = this;
var records_collection = new Backbone.Collection(this.collection.map(function (transaction_history) {
//console.log("transaction_history", transaction_history)
// setTimeout(function() {
var model = new Backbone.Model({
touchpoint: 'customercenter',
title: new Handlebars.SafeString(
Utils.translate(
`${self.getTypeLabel(transaction_history.recordtype)} #<span class="tranid">$(0)</span>`,
transaction_history.get('tranid')
)
),
detailsURL: self.getTypeUrl(transaction_history.recordtype, transaction_history.internalid),
id: transaction_history.id,
internalid: transaction_history.id,
columns: [
{
label: Utils.translate('Date:'),
type: 'date',
name: 'date',
value: transaction_history.get('trandate')
},
{
label: Utils.translate('Amount:'),
type: 'currency',
name: 'amount',
value: transaction_history.get('amount_formatted')
},
{
label: Utils.translate('Status:'),
type: 'status',
name: 'status',
value: transaction_history.get('status') ? transaction_history.get('status').name : ""
}
]
});
return model;
//}, 1000);
})
);
//console.log("records_collection", records_collection)
return new BackboneCollectionView({
childView: RecordViewsView,
collection: records_collection,
viewsPerRow: 1
});
},
'GlobalViews.Pagination': function () {
return new GlobalViewsPaginationView(
_.extend(
{
totalPages: Math.ceil(
this.collection.totalRecordsFound / this.collection.recordsPerPage
)
},
Configuration.defaultPaginationSettings
)
);
}
},
// @method getContext @return {TransactionHistory.List.View.Context}
getContext: function () {
// @class TransactionHistory.List.View.Context
return {
// @property {String} pageHeader
pageHeader: this.page_header,
// @property {Boolean} showNoTermMessage
hasTerms: !!this.profileModel.get('paymentterms'),
// @property {Boolean} isThereAnyResult
isThereAnyResult: !!this.collection.length,
// @property {Boolean} isLoading
isLoading: this.isLoading,
// @property {Boolean} showPagination
showPagination: !!(this.collection.totalRecordsFound && this.collection.recordsPerPage),
// @property {Boolean} showCurrentPage
showCurrentPage: this.options.showCurrentPage,
// @property {Boolean} showBackToAccount
showBackToAccount: Configuration.get('siteSettings.sitetype') === 'STANDARD'
};
}
});
});
5. JJ.sub_Customer_List.subcustomer.Model
// Model.js
// -----------------------
// @module Case
define("JJ.sub_Customer_List.subcustomer.Model", ["Backbone", "Utils"], function(
Backbone,
Utils
) {
"use strict";
// @class Case.Fields.Model @extends Backbone.Model
return Backbone.Model.extend({
//@property {String} urlRoot
urlRoot: Utils.getAbsoluteUrl(
getExtensionAssetsPath(
"services/subcustomer.Service.ss"
)
),
parse: function parse(response) {
// console.log("response",response)
var customerlist = response
return {customerlist:customerlist}
},
});
});
6. JJ.sub_customer.TransactionHistory.Collection
define('JJ.sub_customer.TransactionHistory.Collection'
, ['TransactionHistory.Model',
'Transaction.Collection',
'Utils',
'underscore'
]
, function (
TransactionHistoryModel,
TransactionCollection,
Utils,
_
) {
'use strict';
return TransactionCollection.extend({
url: Utils.getAbsoluteUrl(getExtensionAssetsPath("services/subcustomer.Service.ss")),
parse: function parse(response) {
this.totalRecordsFound = response.totalRecordsFound;
this.recordsPerPage = response.recordsPerPage;
this.page = response.page;
return response.records;
},
update: function (options) {
var range = options.range || {};
options.subcustomerId = this.subcustomerId
this.fetch({
data: {
filter: options.filter && options.filter.value,
sort: options.sort.value,
order: options.order,
from: range.from,
to: range.to,
page: options.page,
subcustomerId: options.subcustomerId
},
reset: true,
killerId: options.killerId
});
}
});
});
SuiteScript
1. subcustomer.ServiceController
const { tree } = require("gulp");
define("subcustomer.ServiceController",
["ServiceController",
"JJ.sub_Customer_List.subcustomer",
"Application",
"JJ.sub_Customer.TransactionHistory.Model"],
function (
ServiceController,
JJsub_Customer_Listsubcustomer,
Application,
JJsub_CustomerTransactionHistoryModel
) {
"use strict";
return ServiceController.extend({
name: "subcustomer.ServiceController",
// The values in this object are the validation needed for the current service.
options: {
common: {}
},
get: function get() {
try {
this._validatePermission();
console.error("this@controler", this.request.getAllParameters());
var subcustomerId = this.request.getParameter('subcustomerId');
var type = this.request.getParameter('SubList');
console.error("subcustomerId@controler", subcustomerId);
if (type == "List") {
return JJsub_Customer_Listsubcustomer.get()
}
var id = this.request.getParameter('internalid');
var record_type = this.request.getParameter('recordtype');
if (id && record_type) {
return TransactionModel.get(record_type, id);
}
if (subcustomerId) {
return JJsub_CustomerTransactionHistoryModel.list({
filter: this.request.getParameter('filter'),
order: this.request.getParameter('order'),
sort: this.request.getParameter('sort'),
from: this.request.getParameter('from'),
to: this.request.getParameter('to'),
page: this.request.getParameter('page') || 1,
types: this.request.getParameter('types'),
createdfrom: this.request.getParameter('createdfrom'),
subcustomerId: subcustomerId
});
}
else {
return true;
}
}
catch (e) {
console.error("error@controler", e);
return JSON.stringify({
message: "Hello World I'm an Extension using a Service!"
});
}
},
_validatePermission: function () {
var permissions = Application.getPermissions().transactions;
if (!(permissions.tranFind > 0 &&
(permissions.tranCustInvc > 0 ||
permissions.tranCustCred > 0 ||
permissions.tranCustPymt > 0 ||
permissions.tranCustDep > 0 ||
permissions.tranDepAppl > 0))) {
throw forbiddenError;
}
},
post: function post() {
// return JJsub_Customer_Listsubcustomer.get()
},
put: function put() {
// not implemented
},
delete: function () {
// not implemented
}
});
});
2. JJ.sub_Customer.TransactionHistory.Model
define(
'JJ.sub_Customer.TransactionHistory.Model'
, [
'underscore'
,'Transaction.Model'
]
, function (
_
,TransactionModel
)
{
'use strict';
return TransactionModel.extend({
name: 'DelegatePurchasing.OrderHistory',
setExtraListFilters: _.wrap(TransactionModel.setExtraListFilters, function setExtraListFilters(fn) {
try{
var self = this;
fn.apply(this, _.toArray(arguments).slice(1));
console.error("self",JSON.stringify(self))
console.error("subcustomerIdmodel",self.data.subcustomerId)
if (self.data.subcustomerId){
self.filters.types_operator = 'and';
self.filters.types = ['type', 'anyof', this.data.filter.split(',')];
self.filters.entity = ['entity', 'is', self.data.subcustomerId];
}
}catch (e) {
console.error('error12', e)
}
}),
});
});
3. JJ.sub_Customer_List.subcustomer
// JJ.sub_Customer_List.subcustomer.js
// Load all your starter dependencies in backend for your extension here
// ----------------
define('JJ.sub_Customer_List.subcustomer'
, [
'subcustomer.ServiceController', 'SC.Model',
'SC.Models.Init',
'underscore'
]
, function (
subcustomerServiceController, SCModel,
ModelsInit,
_
) {
'use strict';
console.error('insidemodel')
return SCModel.extend({
get: function get() {
try {
var customerid = nlapiGetContext().getUser();
var productFeatures = [];
var searchFilters = [
["internalid", "anyof", customerid]
];
var searchColumns = [
new nlobjSearchColumn("internalid", "subCustomer", null),
new nlobjSearchColumn("email", "subCustomer", null),
new nlobjSearchColumn("companyname", "subCustomer", null),
//new nlobjSearchColumn("lastname", "subCustomer", null),
new nlobjSearchColumn("role", "subCustomer", null)
]
var subcustomerObj = Application.getAllSearchResults('customer', searchFilters, searchColumns) || {};
console.error('subcustomerObj', subcustomerObj)
var result = JSON.stringify(subcustomerObj);
console.error('result', result)
result = JSON.parse(result);
if (result.length > 0) {
_.each(result, function (eachResult) {
var featuredata = {};
console.error('eachResult', eachResult)
console.error('columnresult', JSON.stringify(eachResult))
var columnresult = JSON.stringify(eachResult)
var internalid = JSON.parse(columnresult).columns.internalid?JSON.parse(columnresult).columns.internalid.internalid:"000"
featuredata.internalid = internalid;
featuredata.email = (JSON.parse(columnresult).columns && JSON.parse(columnresult).columns.email) || '';
featuredata.companyname = (JSON.parse(columnresult).columns && JSON.parse(columnresult).columns.companyname) || '';
//featuredata.lastname = (JSON.parse(columnresult).columns && JSON.parse(columnresult).columns.lastname) || '';
featuredata.role = (JSON.parse(columnresult).columns && JSON.parse(columnresult).columns.role) || '';
productFeatures.push(featuredata);
});
}
console.error('productFeatures', JSON.stringify(productFeatures))
return JSON.stringify(productFeatures);
} catch (e) {
console.error('error@model', e)
}
},
})
});
Templates
1. jj_orderhistorylist
{{#if showBackToAccount}}
<a href="/" class="transaction-history-list-button-back">
<i class="transaction-history-list-button-back-icon"></i>
{{translate 'Back to Account'}}
</a>
{{/if}}
<section class="transaction-history-list">
<header class="transaction-history-list-header">
<h2>{{pageHeader}}</h2>
</header>
<div data-view="ListHeader.View"></div>
<div class="transaction-history-list-results-container">
{{#if isThereAnyResult}}
<table class="transaction-history-list-results-table">
<thead class="transaction-history-list-headers">
<tr>
<th class="transaction-history-list-headers-number">
<span>{{translate 'Order Number'}}</span>
</th>
<th class="transaction-history-list-headers-date">
<span>{{translate 'Date'}}</span>
</th>
<th class="transaction-history-list-headers-amount">
<span>{{translate 'Amount'}}</span>
</th>
<th class="transaction-history-list-headers-status">
<span>{{translate 'Status'}}</span>
</th>
</tr>
</thead>
<tbody data-view="Records.Collection"></tbody>
</table>
{{else}}
{{#if isLoading}}
<p class="transaction-history-list-empty">{{translate 'Loading...'}}</p>
{{else}}
<div class="transaction-history-list-empty-section">
<h5>{{translate 'No transactions were found'}}</h5>
</div>
{{/if}}
{{/if}}
</div>
{{#if showPagination}}
<div class="transaction-history-list-paginator">
<div data-view="GlobalViews.Pagination"></div>
{{#if showCurrentPage}}
<div data-view="GlobalViews.ShowCurrentPage"></div>
{{/if}}
</div>
{{/if}}
</section>
{{!----
Use the following context variables when customizing this template:
pageHeader (String)
hasTerms (Boolean)
isThereAnyResult (Boolean)
isLoading (Boolean)
showPagination (Boolean)
showBackToAccount (Boolean)
----}}
<!--
Available helpers:
{{ getExtensionAssetsPath "img/image.jpg"}} - reference assets in your extension
{{ getExtensionAssetsPathWithDefault context_var "img/image.jpg"}} - use context_var value i.e. configuration variable. If it does not exist, fallback to an asset from the extension assets folder
{{ getThemeAssetsPath context_var "img/image.jpg"}} - reference assets in the active theme
{{ getThemeAssetsPathWithDefault context_var "img/theme-image.jpg"}} - use context_var value i.e. configuration variable. If it does not exist, fallback to an asset from the theme assets folder
-->
2. jj_sub_customer_list_subcustomer
<h2 class="sub-customer-header">List Of Sub Customers</h2>
<!-- <div class="user-logout-block">
<a class="user-logout-button" href="#" data-touchpoint="logout" name="signout">
{{translate 'Sign Out'}}
</a>
</div> -->
{{#if subcustomers}}
<table class="user-list-recordviews-table">
<thead class="user-list-content-table">
<tr class="user-list-content-table-header-row">
<th class="user-list-content-table-header-row-title">
<span>{{translate 'Email'}}</span>
</th>
<th class="user-list-content-table-header-row-name">
<span>{{translate 'Name'}}</span>
</th>
{{!-- <th class="user-list-content-table-header-row-name">
<span>{{translate 'Last Name'}}</span>
</th> --}}
<th class="user-list-content-table-header-row-role">
<span>{{translate 'Role'}}</span>
</th>
<th class="user-list-content-table-header-row-view-orders">
<span>{{translate 'Order History'}}</span>
</th>
</tr>
</thead>
<tbody data-view="Users.List.Items">
{{#each subCustomerList}}
<tr class="recordviews-row" data-item-id="{{id}}" data-navigation-hashtag="{{detailsURL}}" data-action="navigate">
<td class="recordviews" data-name="{{name}}">
{{#if email}}
<span class="recordviews-value">{{email}}</span>
{{/if}}
</td>
<td class="recordviews" data-name="{{name}}">
{{#if companyname}}
<span class="recordviews-label">Name: </span>
<span class="recordviews-value">{{companyname}}</span>
{{/if}}
</td>
{{!-- <td class="recordviews" data-name="{{name}}">
{{#if lastname}}
<span class="recordviews-label">Last Name: </span>
<span class="recordviews-value">{{lastname}}</span>
{{/if}}
</td> --}}
<td class="recordviews" data-name="{{name}}">
{{#if role}}
<span class="recordviews-label">Role: </span>
<span class="recordviews-value">{{role}}</span>
{{/if}}
</td>
<td class="recordviews" data-name="{{name}}">
<a data-action="view-order-list" class="view-order-history" data-id="{{internalid}}" href="&userstransactionhistory={{internalid}}">
<span class="recordviews-value">View Orders</span>
</a>
</td>
<td class="recordviews" data-name="{{name}}">
<a class="user-logout-button" href="#" data-touchpoint="logout" name="signout">
{{translate 'Login'}}
</a>
</td>
</tr>
{{/each}}
</tbody>
</table>
{{else}}
<p class="user-list-empty">{{translate 'No sub customers were found'}}</p>
{{/if}}
<!--
Available helpers:
{{ getExtensionAssetsPath "img/image.jpg"}} - reference assets in your extension
{{ getExtensionAssetsPathWithDefault context_var "img/image.jpg"}} - use context_var value i.e. configuration variable. If it does not exist, fallback to an asset from the extension assets folder
{{ getThemeAssetsPath context_var "img/image.jpg"}} - reference assets in the active theme
{{ getThemeAssetsPathWithDefault context_var "img/theme-image.jpg"}} - use context_var value i.e. configuration variable. If it does not exist, fallback to an asset from the theme assets folder
-->