Description
Once the user clicks the button, Pop of box
Searchable box for items. On the top of the popup
Free from the text button of request.
After Submit the request sent the email: “ “
Email subject should include the Quote number or Sales order number.
Body of email will have the searched items and/or text-filled on the popup box.
JS files
JS FILE 1
define(
'SCG.QuoteUpdate.QuoteUpdate', [
'SCG.QuoteUpdate.QuoteUpdate.View'
, 'Quote.Details.View'
, 'Profile.Model'
, 'Utils'
, 'Backbone'
, 'underscore'
, 'jQuery'
],
function(
QuoteUpdateView
, QuoteDetailsView
, ProfileModel
, Utils
, Backbone
, _
, jQuery
) {
'use strict';
return {
mountToApp: function mountToApp(application) {
// using the 'Layout' component we add a new child view inside the 'Header' existing view
// (there will be a DOM element with the HTML attribute data-view="Header.Logo")
// more documentation of the Extensibility API in
// https://system.netsuite.com/help/helpcenter/en_US/APIs/SuiteCommerce/Extensibility/Frontend/index.html
/** @type {LayoutComponent} */
var layout = application.getComponent('Layout');
var detailsView;
var self = this
if (layout) {
_.extend(QuoteDetailsView.prototype, {
initialize: _.wrap(QuoteDetailsView.prototype.initialize, function wrapInitialize(fn) {
var quoteInformation;
// Store the reference to the view(this) in the global variable
detailsView = this;
fn.apply(this, _.toArray(arguments).slice(1));
// Add button for enable edit order lines quantity
//if (currentUser.id !== this.model.get('owner')) {
// Add button for enable edit order lines quantity
this.on('beforeCompositeViewRender', function afterViewRender() {
var checkOpenQuote = detailsView.model.get('status')
if (Object.keys(checkOpenQuote).length > 0 && checkOpenQuote.internalid == "Open") {
quoteInformation = detailsView.$('.quote-details-summary-container');
if (quoteInformation.length) {
quoteInformation.after(
'<div data-view="SCG.QuoteUpdate.QuoteUpdate.View"></div>'
);
}
}
});
// }
})
});
_.extend(QuoteDetailsView.prototype.childViews, {
'SCG.QuoteUpdate.QuoteUpdate.View': function QuoteUpdate() {
return new QuoteUpdateView({
application: this.application,
parent: detailsView.model,
container: application,
ProfileModel:ProfileModel
//items: SubArray
});
}
});
}
},
};
});
JS FILE 2
// @module SCG.QuoteUpdate.QuoteUpdate
define('SCG.QuoteUpdate.QuoteUpdate.View', [
'scg_quoteupdate_quoteupdate.tpl',
'SCG.QuoteUpdate.QuoteUpdate.Request.QuickAdd'
, 'Profile.Model'
, 'Utils'
, 'Backbone'
, 'underscore'
, 'jQuery'
],
function(
scg_quoteupdate_quoteupdate_tpl,
SCGQuoteUpdateRequestView
, ProfileModel
, Utils
, Backbone
, _
, jQuery
) {
'use strict';
// @class SCG.QuoteUpdate.QuoteUpdate.View @extends Backbone.View
return Backbone.View.extend({
template: scg_quoteupdate_quoteupdate_tpl,
initialize: function(options) {
/* Uncomment to test backend communication with an example service
(you'll need to deploy and activate the extension first)
*/
this.message = '';
this.options = options
}
,
events: {
'click [data-action="Search-items-toQuote"]': 'SearchItems',
},
bindings: {}
,
childViews: {
}
,
SearchItems: function(options) {
//console.log('optionssearch', options)
var UpdateRequest = new SCGQuoteUpdateRequestView({
application: this.options.application,
container: this.options.container,
Quotedetails: this.options.parent,
ProfileModel: this.options.ProfileModel
});
this.application.getLayout().showInModal(UpdateRequest);
}
//@method getContext @return SCG.QuoteUpdate.QuoteUpdate.View.Context
,
getContext: function getContext() {
//@class SCG.QuoteUpdate.QuoteUpdate.View.Context
this.message = this.message || 'Request additional items'
// console.log('this.options.application', this.options.application)
this.application = this.options.application;
return {
message: this.message,
pageHeader: this.page_header
};
}
});
});
JS FILE 3
// @module SCG.QuoteUpdate.QuoteUpdate
define('SCG.QuoteUpdate.QuoteUpdate.Request.QuickAdd', [
'scg_quoteupdate_quoteupdate_request.tpl'
, 'Utils'
, 'Backbone'
, 'jQuery'
, 'underscore'
, 'QuickAdd.View'
], function(
scg_quoteupdate_quoteupdate_request_tpl
, Utils
, Backbone
, jQuery
, _
, QuickAddView
) {
'use strict';
// @class SCG.QuoteUpdate.QuoteUpdate.View @extends Backbone.View
return Backbone.View.extend({
template: scg_quoteupdate_quoteupdate_request_tpl
,
initialize: function(options) {
/* Uncomment to test backend communication with an example service
(you'll need to deploy and activate the extension first)
*/
this.message = '';
this.counter = 1;
this.itemArray = {};
console.log('this.itemsArray', this.itemsArray)
var itemArrCheck = this.itemsArray;
console.log('this.itemArrCheck', itemArrCheck)
$("#in-modal-noitemmsg").html('<span>No items added</span>');
if ((itemArrCheck == undefined) || (!(itemArrCheck)) || (itemArrCheck ? (Object.keys(itemArrCheck).length = 0 ? true : false) : false)) {
console.log('this.itemsArray', this.itemsArray)
$("#in-modal-noitemmsg").html('<span>No items added</span>');
}
if ((itemArrCheck == undefined) || (!(itemArrCheck)) || (itemArrCheck ? (Object.keys(itemArrCheck).length = 0 ? true : false) : false)) {
console.log('this.itemsArray', this.itemsArray)
$("#in-modal-noitemmsg").html('<span>No items added</span>');
}
},
RemoveItem: function(data) {
console.log('data', data)
var self = this
var myObject = this.itemArray;
var prop = data.currentTarget.id;
delete this.itemArray[prop];
this.setLineIndex();
}
//@method addNewLine
//@param {QuickAdd.View.SelectedLine.Properties} options
//@return {Void}
,
addNewLine: function(options) {
var itemInfoDetail = options.selectedLine.get('item')
this.itemArray[itemInfoDetail.get('internalid')] = options.selectedLine
this.render(true);
this.setLineIndex();
}
//Update the message if there
,
updateMessage: function(data) {
this.message = data.currentTarget.value ? data.currentTarget.value : '';
}
//@method setLineIndex Sets a line in a particular position
//@param {Transaction.Line.Model} selected_line
//@param {Number} new_position
//@param {Transaction.Line.Collection} collection
//@return {Void}
,
setLineIndex: function() {
$('.quoteupdate-module-items-item').empty()
_.each(this.itemArray, function(rowItem) {
var itemInfo = rowItem.get('item')
//console.log('itemInfo', itemInfo)
/* this.counter++;*/
var html = '<tr><td class="modal-width"><div class="transaction-line-views-cell-actionable-expanded-thumbnail"><a href="' + itemInfo.get('keyMapping_url')
html += '" data-touchpoint="home" data-hashtag="%2' + itemInfo.get('itemid') + '"><img src="' + itemInfo.get('itemimages_detail').main.url + '?resizeid=5&resizeh=150&resizew=150"'
html += ' alt=""></a></div>'
html += '</td><td class="modal-width"><div class="transaction-line-views-cell-actionable-expanded-name"> <a href="' + itemInfo.get('keyMapping_url')
html += '" data-touchpoint="home" data-hashtag="%2' + itemInfo.get('itemid') + '" class="transaction-line-views-cell-actionable-expanded-name-link">'
html += itemInfo.get('storedisplayname2') + '</a> </div><div class="transaction-line-views-price"><span class="transaction-line-views-price-lead" itemprop="price" data-rate="'
html += itemInfo.get('onlinecustomerprice_detail').onlinecustomerprice + '">' + itemInfo.get('onlinecustomerprice_detail').onlinecustomerprice_formatted
html += '</span></div><div class="product-line-sku-container"><span class="product-line-sku-label"> SKU: </span><span class="product-line-sku-value" itemprop="sku">' + itemInfo.get('itemid')
html += '</span> </div></td><td class="modal-width"><div class="product-line-qty-item">' + rowItem.get('quantity')
html += '<span/></td><td class="modal-width" style="display: initial; margin-top: 10px;"><input class="quoteupdate-module-items-table-button" type="button" id="' + itemInfo.get('internalid') + '" value="Remove" data-action="remove-item"/></td></tr>'
var newRow = jQuery(html);
//console.log('newRow', newRow)
jQuery('table.quoteupdate-module-items-table').append(newRow);
$('.quoteupdate-module-table-noItemList').empty()
});
$('.quoteupdate-module-message-textarea').val(this.message)
$(".quoteupdate-module-warning-message").hide();
},
events: {
'click [data-action="remove-item"]': 'RemoveItem',
'click [data-action="send-email"]': 'SendEmail',
'change [id="messageEmail"]': 'updateMessage',
//'keyup [id="messageEmail"]': 'updateMessage',
'change [id="in-modal-messageEmail"]': 'updateMessage',
}
//@property {ChildViews} childViews
,
childViews: {
'QuickAddView': function() {
//console.log('QuickAddView', this)
this.quickAddViewComponent = new QuickAddView({
});
//console.log('this.quickAddViewComponent', this.quickAddViewComponent)
this.quickAddViewComponent.on('selectedLine', this.addNewLine, this);
return this.quickAddViewComponent;
}
},
SendEmail: function(option) {
//console.log('option', this)
var itemListArray = []
var quoteData = this.options.Quotedetails;
//console.log("this.profileModel1", this.options.ProfileModel.getInstance());
var custdata = this.options.ProfileModel.getInstance();
var salesrepEmail = "corporate@testgauge.net"
var subsidiary = quoteData.get('subsidiary')
console.log(custdata, subsidiary)
if (subsidiary == "2") {
salesrepEmail = "salesgroup@testgauge.net";
} else if (subsidiary == "1") {
salesrepEmail = "corporate@testgauge.net";
} else if (subsidiary == "4") {
salesrepEmail = "in-franchise@testgauge.net";
} else if (subsidiary == "6") {
salesrepEmail = "tx-franchise@testgauge.net";
} else if (subsidiary == "9") {
salesrepEmail = "co-franchise@testgauge.net";
} else if (subsidiary == "10") {
salesrepEmail = "fl-franchise@testgauge.net";
}
var QuoteObj = {
memo: quoteData.get('memo'),
tranid: quoteData.get('tranid'),
email: custdata.get('email'),
custName: custdata.get('name') || custdata.get('companyname'),
salesrepEmail: salesrepEmail,
message: this.message
}
var ItemList = []
ItemList = _.each(this.itemArray, function(eachitem) {
var itemObj = {}
var itemInfo = eachitem.get('item');
itemObj.imgURL = itemInfo.get('itemimages_detail').main.url;
itemObj.inlinePrize = itemInfo.get('onlinecustomerprice_detail').onlinecustomerprice_formatted
itemObj.sku = itemInfo.get('itemid')
itemObj.qty = eachitem.get('quantity');
itemObj.name = itemInfo.get('storedisplayname2')
itemListArray.push(itemObj);
});
var emailMeaasge = (this.message).trim();
emailMeaasge = (emailMeaasge).split(/\s/).join('');
if (itemListArray.length > 0 || emailMeaasge.length > 0) {
var content = {
Quotedetails: QuoteObj,
items: itemListArray
}
var service_url = Utils.getAbsoluteUrl(getExtensionAssetsPath('services/QuoteUpdate.Service.ss'));
jQuery.get(service_url, { content: JSON.stringify(content) }).then(function(result) {
if (result == true || result == "true") {
console.log(result);
$("#in-modal-message").html('<span style="color:black;">The request send successfully</span>');
alert("The request send successfully.");
$("#modal").modal('hide');
}
});
} else {
$(".quoteupdate-module-warning-message").html('<span width="100%" align="center" style="color:red; display:block;">Please add the message to the Salesrep / Please add atleast one item to the list<br></span>');
$(".quoteupdate-module-warning-message").show();
}
}
//@method getContext @return SCG.QuoteUpdate.QuoteUpdate.View.Context
,
getContext: function getContext() {
//@class SCG.QuoteUpdate.QuoteUpdate.View.Context
this.message = this.message || ''
this.application = this.options.application;
var hasItems = this.itemsArray ? (Object.keys(this.itemsArray).length > 0 ? true : false) : false;
$("#in-modal-noitemmsg").html('<span>No items added</span>');
return {
message: this.message,
pageHeader: this.page_header,
itemsArray: this.itemArray ? this.itemArray : false,
hasItems: this.itemsArray ? true : false
};
}
});
});
TPL Files
scg_quoteupdate_quoteupdate.tpl
<section class="quoteupdate-info-card">
<button class="quoteupdate-Search-items-toQuote" id="Search-items-toQuote" data-action="Search-items-toQuote">
{{message}}
</button>
</section>
scg_quoteupdate_quoteupdate_request.tpl
<section class="quoteupdate-info-card">
<div data-view="QuickAddView"></div>
<div class="quoteupdate-module-message"><textarea id="messageEmail" placeholder="Message to Salesrep" class="quoteupdate-module-message-textarea" spellcheck="true"></textarea></div>
<div class="quoteupdate-module-items">
<h3 class="quoteupdate-module-items-title">
Items to be updated for the Quote
</h3>
<div class="quoteupdate-module-table-itemList">
{{#if itemsArray}}
<table class="quoteupdate-module-items-table">
<thead class="quoteupdate-module-items-header">
<th class="quoteupdate-module-items-header-image modal-width" name="item-image">
{{translate 'Item'}}
</th>
<th class="quoteupdate-module-items-header-totalprice modal-width" name="item-totalprice">
<!-- {{translate 'List Price'}} -->
</th>
<th class="quoteupdate-module-items-header-quantity modal-width" name="item-quantity">
Quantity
</th>
<th class="quoteupdate-module-items-header-actions modal-width" name="item-actions">
<!-- {{translate 'Quantity'}} -->
</th>
</thead>
<tbody class="quoteupdate-module-items-item"></tbody>
</table>
{{else}}
<div class="quoteupdate-module-table-noItemList">{{translate 'No item available to update'}}</div>
{{/if}}
<div id="noitemmsg" class="quoteupdate-module-table-noItemList"><span>No items added</span></div>
</div>
</div>
<div class="modal-footer">
<span id="message" class="quoteupdate-module-warning-message"></span>
<button type="button" class="quoteupdate-module-items-table-button" data-action="send-email">Send Request</button>
<button type="button" class="btn btn-default cancel" data-dismiss="modal">Cancel</button>
</div>
</section>
Suitescript
FIle 1
define(
'SCG.QuoteUpdate.QuoteUpdate.ServiceController'
, [
'ServiceController','SCG.QuoteUpdate.QuoteUpdate','Application', 'SC.Models.Init', 'underscore'
]
, function(
ServiceController,UpdateQuotesendEmail,Application, ModelsInit, _
)
{
'use strict';
return ServiceController.extend({
name: 'SCG.QuoteUpdate.QuoteUpdate.ServiceController'
// The values in this object are the validation needed for the current service.
, options: {
common: {
}
}
, get: function get()
{
var data = this.request.getParameter('content');
// console.log("data",data);
if (data) {
return UpdateQuotesendEmail.get(data);
}
//return 'Hello World I\'m an Extension using a Service!';
}
, post: function post()
{
// not implemented
}
, put: function put()
{
// not implemented
}
, delete: function()
{
// not implemented
}
});
}
);
FILE 2
define(
'SCG.QuoteUpdate.QuoteUpdate.ServiceController'
, [
'ServiceController','SCG.QuoteUpdate.QuoteUpdate','Application', 'SC.Models.Init', 'underscore'
]
, function(
ServiceController,UpdateQuotesendEmail,Application, ModelsInit, _
)
{
'use strict';
return ServiceController.extend({
name: 'SCG.QuoteUpdate.QuoteUpdate.ServiceController'
// The values in this object are the validation needed for the current service.
, options: {
common: {
}
}
, get: function get()
{
var data = this.request.getParameter('content');
// console.log("data",data);
if (data) {
return UpdateQuotesendEmail.get(data);
}
//return 'Hello World I\'m an Extension using a Service!';
}
, post: function post()
{
// not implemented
}
, put: function put()
{
// not implemented
}
, delete: function()
{
// not implemented
}
});
}
);
CSS
/*
Sass Application Entry Point
Link all your sass dependencies in the right order
Example:
@import "other-sass-file.scss";
@import "../../<other module>/Sass/other-sass-file.scss";
*/
.quoteupdate-info-card {
@extend .info-card;
padding: 0px;
border: none;
.cancel {
padding: 12px 20px;
margin: 5px 0 6px 5px;
}
}
.quoteupdate-info-card-content {
@extend .info-card-content;
color: $sc-color-secondary;
font-weight: bold;
}
.quoteupdate-Search-items-toQuote {
background: #2b6ca3;
color: white;
font-weight: 400;
border: 1px solid #2b6ca3;
border-radius: 6px;
text-transform: none;
padding: 5px;
margin-bottom: 8px;
width: -webkit-fill-available;
}
.modal-sm {
width: 50%;
}
* {
box-sizing: border-box;
}
.quoteupdate-module-items-title {
margin-bottom: 15px;
text-align: center;
}
.quoteupdate-module-items-table,
.quoteupdate-module-table-noItemList {
width: 100%;
text-align: center;
font-size: initial;
}
.quoteupdate-module-items-item {
.quoteupdate-module-items-table-button {
background: #2b6ca3;
border-radius: 5px;
color: white;
}
.product-line-qty-item {
margin: 30px 20px;
}
}
.quoteupdate-module-table-itemList,
.quoteupdate-module-table-noItemList {
th,
td {
text-align: center;
font-size: initial;
}
}
.transaction-line-views-cell-actionable-expanded-thumbnail,
.transaction-line-views-cell-actionable-expanded-name,
.product-line-sku-container {
min-width: 100px;
}
.quoteupdate-module-items-table-button {
background: #2b6ca3;
border-radius: 5px;
color: white;
padding: 10px 20px;
&:hover {
background: #0289ff;
}
}
.quoteupdate-module-table-itemList {
max-height: 411px;
overflow-y: auto;
overflow-x: scroll;
margin-bottom: 20px;
.transaction-line-views-cell-actionable-expanded-name-link {
font-size: medium;
}
}
.modal-width {
/*width: 25%*/
@extend .col-md-3;
/*@extend .col-xs-9;
@extend .col-sm-12;*/
}
.quick-add-box {
margin-bottom: 0;
}
.quoteupdate-module-message {
margin-bottom: $sc-margin-lv4;
textarea {
width: 100%;
min-width: 100%;
}
@media(min-width: $screen-sm-min) {
padding: 0 20px;
}
@media(min-width: $screen-lg-min) {
padding: 0 0 0 20px;
/*margin-bottom: 20px;*/
width: 50%;
}
}
Manifest.json
{
"name": "QuoteUpdate",
"fantasyName": "QuoteUpdate",
"vendor": "SCG",
"version": "1.0.0",
"type": "extension",
"target": "SCA,SCS",
"target_version": {
"SCA": "19.2.0",
"SCS": "19.2.0"
},
"description": "Request for adding items for quote",
"skins": [],
"assets": {
"img": {
"files": []
},
"fonts": {
"files": []
},
"services": {
"files": [
"services/QuoteUpdate.Service.ss"
]
}
},
"configuration": {
"files": []
},
"sass": {
"entry_points": {
"myaccount": "Modules/QuoteUpdate/Sass/_quoteupdate-quoteupdate.scss"
},
"files": [
"Modules/QuoteUpdate/Sass/_quoteupdate-quoteupdate.scss"
]
},
"templates": {
"application": {
"myaccount": {
"files": [
"Modules/QuoteUpdate/Templates/scg_quoteupdate_quoteupdate.tpl",
"Modules/QuoteUpdate/Templates/scg_quoteupdate_quoteupdate_request.tpl"
]
}
}
},
"javascript": {
"entry_points": {
"myaccount": "Modules/QuoteUpdate/JavaScript/SCG.QuoteUpdate.QuoteUpdate.js"
},
"application": {
"myaccount": {
"files": [
"Modules/QuoteUpdate/JavaScript/SCG.QuoteUpdate.QuoteUpdate.js",
"Modules/QuoteUpdate/JavaScript/QuoteUpdate.View.js",
"Modules/QuoteUpdate/JavaScript/QuoteUpdate.Request.quickAdd.js"
]
}
}
},
"ssp-libraries": {
"entry_point": "Modules/QuoteUpdate/SuiteScript/QuoteUpdate.ServiceController.js",
"files": [
"Modules/QuoteUpdate/SuiteScript/SCG.QuoteUpdate.QuoteUpdate.js",
"Modules/QuoteUpdate/SuiteScript/QuoteUpdate.ServiceController.js"
]
},
"local_folder": "Workspace\\QuoteUpdate"
}