/*+***********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
*************************************************************************************/
Vtiger_Edit_Js("Inventory_Edit_Js", {
zeroDiscountType : 'zero' ,
percentageDiscountType : 'percentage',
directAmountDiscountType : 'amount',
individualTaxType : 'individual',
groupTaxType : 'group',
lineItemPopOverTemplate : '
\n\
\n\
\n\
\n\
'
}, {
//Will have the mapping of address fields based on the modules
addressFieldsMapping : {
'Contacts' : {
'bill_street' : 'mailingstreet',
'ship_street' : 'otherstreet',
'bill_pobox' : 'mailingpobox',
'ship_pobox' : 'otherpobox',
'bill_city' : 'mailingcity',
'ship_city' : 'othercity',
'bill_state' : 'mailingstate',
'ship_state' : 'otherstate',
'bill_code' : 'mailingzip',
'ship_code' : 'otherzip',
'bill_country' : 'mailingcountry',
'ship_country' : 'othercountry'
} ,
'Accounts' : {
'bill_street' : 'bill_street',
'ship_street' : 'ship_street',
'bill_pobox' : 'bill_pobox',
'ship_pobox' : 'ship_pobox',
'bill_city' : 'bill_city',
'ship_city' : 'ship_city',
'bill_state' : 'bill_state',
'ship_state' : 'ship_state',
'bill_code' : 'bill_code',
'ship_code' : 'ship_code',
'bill_country' : 'bill_country',
'ship_country' : 'ship_country'
},
'Vendors' : {
'bill_street' : 'street',
'ship_street' : 'street',
'bill_pobox' : 'pobox',
'ship_pobox' : 'pobox',
'bill_city' : 'city',
'ship_city' : 'city',
'bill_state' : 'state',
'ship_state' : 'state',
'bill_code' : 'postalcode',
'ship_code' : 'postalcode',
'bill_country' : 'country',
'ship_country' : 'country'
},
'Leads' : {
'bill_street' : 'lane',
'ship_street' : 'lane',
'bill_pobox' : 'pobox',
'ship_pobox' : 'pobox',
'bill_city' : 'city',
'ship_city' : 'city',
'bill_state' : 'state',
'ship_state' : 'state',
'bill_code' : 'code',
'ship_code' : 'code',
'bill_country' : 'country',
'ship_country' : 'country'
}
},
//Address field mapping between modules specific for billing and shipping
addressFieldsMappingBetweenModules:{
'AccountsBillMap' : {
'bill_street' : 'bill_street',
'bill_pobox' : 'bill_pobox',
'bill_city' : 'bill_city',
'bill_state' : 'bill_state',
'bill_code' : 'bill_code',
'bill_country' : 'bill_country'
},
'AccountsShipMap' : {
'ship_street' : 'ship_street',
'ship_pobox' : 'ship_pobox',
'ship_city' : 'ship_city',
'ship_state' : 'ship_state',
'ship_code' : 'ship_code',
'ship_country' : 'ship_country'
},
'ContactsBillMap' : {
'bill_street' : 'mailingstreet',
'bill_pobox' : 'mailingpobox',
'bill_city' : 'mailingcity',
'bill_state' : 'mailingstate',
'bill_code' : 'mailingzip',
'bill_country' : 'mailingcountry'
},
'ContactsShipMap' : {
'ship_street' : 'otherstreet',
'ship_pobox' : 'otherpobox',
'ship_city' : 'othercity',
'ship_state' : 'otherstate',
'ship_code' : 'otherzip',
'ship_country' : 'othercountry'
},
'LeadsBillMap' : {
'bill_street' : 'lane',
'bill_pobox' : 'pobox',
'bill_city' : 'city',
'bill_state' : 'state',
'bill_code' : 'code',
'bill_country' : 'country'
},
'LeadsShipMap' : {
'ship_street' : 'lane',
'ship_pobox' : 'pobox',
'ship_city' : 'city',
'ship_state' : 'state',
'ship_code' : 'code',
'ship_country' : 'country'
}
},
//Address field mapping within module
addressFieldsMappingInModule : {
'bill_street':'ship_street',
'bill_pobox':'ship_pobox',
'bill_city' :'ship_city',
'bill_state':'ship_state',
'bill_code' :'ship_code',
'bill_country':'ship_country'
},
dummyLineItemRow : false,
lineItemsHolder : false,
numOfLineItems : false,
customLineItemFields : false,
customFieldsDefaultValues : false,
numOfCurrencyDecimals : false,
taxTypeElement : false,
regionElement : false,
currencyElement : false,
finalDiscountUIEle : false,
conversionRateEle : false,
overAllDiscountEle : false,
preTaxTotalEle : false,
//final calculation elements
netTotalEle : false,
finalDiscountTotalEle : false,
finalTaxEle : false,
finalDiscountEle : false,
chargesTotalEle : false,
chargesContainer : false,
chargeTaxesContainer : false,
chargesTotalDisplay : false,
chargeTaxesTotal : false,
deductTaxesTotal : false,
adjustmentEle : false,
adjustmentTypeEles : false,
grandTotal : false,
groupTaxContainer : false,
dedutTaxesContainer : false,
lineItemDetectingClass : 'lineItemRow',
init : function() {
this._super();
this.initializeVariables();
},
initializeVariables : function() {
this.dummyLineItemRow = jQuery('#row0');
this.lineItemsHolder = jQuery('#lineItemTab');
this.numOfLineItems = this.lineItemsHolder.find('.'+ this.lineItemDetectingClass).length;
if(typeof jQuery('#customFields').val() == 'undefined') {
this.customLineItemFields = [];
}else {
this.customLineItemFields = JSON.parse(jQuery('#customFields').val());
}
if(typeof jQuery('#customFieldsDefaultValues').val() == 'undefined') {
this.customFieldsDefaultValues = [];
}else {
this.customFieldsDefaultValues = JSON.parse(jQuery('#customFieldsDefaultValues').val());
}
this.numOfCurrencyDecimals = parseInt(jQuery('.numberOfCurrencyDecimal').val());
this.taxTypeElement = jQuery('#taxtype');
this.regionElement = jQuery('#region_id');
this.currencyElement = jQuery('#currency_id');
this.netTotalEle = jQuery('#netTotal');
this.finalDiscountTotalEle = jQuery('#discountTotal_final');
this.finalTaxEle = jQuery('#tax_final');
this.finalDiscountUIEle = jQuery('#finalDiscountUI');
this.finalDiscountEle = jQuery('#finalDiscount');
this.conversionRateEle = jQuery('#conversion_rate');
this.overAllDiscountEle = jQuery('#overallDiscount');
this.chargesTotalEle = jQuery('#chargesTotal');
this.preTaxTotalEle = jQuery('#preTaxTotal');
this.chargesContainer = jQuery('#chargesBlock')
this.chargesTotalDisplay = jQuery('#chargesTotalDisplay');
this.chargeTaxesContainer = jQuery('#chargeTaxesBlock');
this.chargeTaxesTotal = jQuery('#chargeTaxTotalHidden');
this.deductTaxesTotal = jQuery('#deductTaxesTotalAmount');
this.adjustmentEle = jQuery('#adjustment');
this.adjustmentTypeEles = jQuery('input[name="adjustmentType"]');
this.grandTotal = jQuery('#grandTotal');
this.groupTaxContainer = jQuery('#group_tax_div');
this.dedutTaxesContainer = jQuery('#deductTaxesBlock');
},
/**
* Function that is used to get the line item container
* @return : jQuery object
*/
getLineItemContentsContainer : function() {
if(this.lineItemContentsContainer == false) {
this.setLineItemContainer(jQuery('#lineItemTab'));
}
return this.lineItemContentsContainer;
},
/**
* Function which will copy the address details
*/
copyAddressDetails : function(data,container,addressMap) {
var self = this;
var sourceModule = data['source_module'];
var noAddress = true;
var errorMsg;
this.getRecordDetails(data).then(
function(data){
var response = data;
if(typeof addressMap != "undefined"){
var result = response['data'];
for(var key in addressMap) {
if(result[addressMap[key]] != ""){
noAddress = false;
break;
}
}
if(noAddress){
if(sourceModule == "Accounts"){
errorMsg = 'JS_SELECTED_ACCOUNT_DOES_NOT_HAVE_AN_ADDRESS';
} else if(sourceModule == "Contacts"){
errorMsg = 'JS_SELECTED_CONTACT_DOES_NOT_HAVE_AN_ADDRESS';
} else if(sourceModule == "Leads") {
errorMsg = 'JS_SELECTED_LEAD_DOES_NOT_HAVE_AN_ADDRESS';
}
app.helper.showErrorNotification({'message':app.vtranslate(errorMsg)});
} else{
self.mapAddressDetails(addressMap, result, container);
}
} else{
self.mapAddressDetails(self.addressFieldsMapping[sourceModule], response['data'], container);
if(sourceModule == "Accounts"){
container.find('.accountAddress').attr('checked','checked');
}else if(sourceModule == "Contacts"){
container.find('.contactAddress').attr('checked','checked');
}
}
},
function(error, err){
});
},
/**
* Function which will copy the address details of the selected record
*/
mapAddressDetails : function(addressDetails, result, container) {
for(var key in addressDetails) {
if(key == 'bill_state')
container.find('[name="'+key+'"]').val(result['cf_992']);
else if (key == 'bill_city')
container.find('[name="'+key+'"]').val(result['cf_994']);
else
container.find('[name="'+key+'"]').val(result[addressDetails[key]]);
container.find('[name="'+key+'"]').trigger('change');
}
},
/**
* Function to copy address between fields
* @param strings which accepts value as either odd or even
*/
copyAddress : function(swapMode){
var self = this;
var formElement = this.getForm();
var addressMapping = this.addressFieldsMappingInModule;
if(swapMode == "false"){
for(var key in addressMapping) {
var fromElement = formElement.find('[name="'+key+'"]');
var toElement = formElement.find('[name="'+addressMapping[key]+'"]');
toElement.val(fromElement.val());
}
} else if(swapMode){
var swappedArray = self.swapObject(addressMapping);
for(var key in swappedArray) {
var fromElement = formElement.find('[name="'+key+'"]');
var toElement = formElement.find('[name="'+swappedArray[key]+'"]');
toElement.val(fromElement.val());
}
toElement.val(fromElement.val());
}
},
/**
* Function to swap array
* @param Array that need to be swapped
*/
swapObject : function(objectToSwap){
var swappedArray = {};
var newKey,newValue;
for(var key in objectToSwap){
newKey = objectToSwap[key];
newValue = key;
swappedArray[newKey] = newValue;
}
return swappedArray;
},
getLineItemNextRowNumber : function() {
return ++this.numOfLineItems;
},
formatListPrice : function(lineItemRow, listPriceValue) {
var listPrice = parseFloat(listPriceValue).toFixed(this.numOfCurrencyDecimals);
lineItemRow.find('.listPrice').val(listPrice);
return this;
},
getLineItemRowNumber : function(itemRow) {
return parseInt(itemRow.attr('data-row-num'));
},
/**
* Function which gives quantity value
* @params : lineItemRow - row which represents the line item
* @return : string
*/
getQuantityValue : function(lineItemRow){
return parseFloat(lineItemRow.find('.qty').val());
},
/**
* Function which will get the value of cost price
* @params : lineItemRow - row which represents the line item
* @return : string
*/
getPurchaseCostValue : function(lineItemRow){
var rowNum = this.getLineItemRowNumber(lineItemRow);
return parseFloat(jQuery('#purchaseCost'+rowNum).val());
},
/**
* Function which will set the cost price
* @params : lineItemRow - row which represents the line item
* @params : cost price
* @return : current instance;
*/
setPurchaseCostValue : function(lineItemRow, purchaseCost) {
if(isNaN(purchaseCost)){
purchaseCost=0;
}
var rowNum = this.getLineItemRowNumber(lineItemRow);
jQuery('#purchaseCost'+rowNum).val(purchaseCost);
var quantity = this.getQuantityValue(lineItemRow);
var updatedPurchaseCost = parseFloat(quantity) * parseFloat(purchaseCost);
lineItemRow.find('[name="purchaseCost'+rowNum+'"]').val(updatedPurchaseCost);
lineItemRow.find('.purchaseCost').text(updatedPurchaseCost);
return this;
},
/**
* Function which will set the image
* @params : lineItemRow - row which represents the line item
* @params : image source
* @return : current instance;
*/
setImageTag : function(lineItemRow, imgSrc) {
var imgTag = '';
lineItemRow.find('.lineItemImage').html(imgTag);
return this;
},
/**
* Function which will give me list price value
* @params : lineItemRow - row which represents the line item
* @return : string
*/
getListPriceValue : function(lineItemRow) {
return parseFloat(lineItemRow.find('.listPrice').val());
},
setListPriceValue : function(lineItemRow, listPriceValue) {
var listPrice = parseFloat(listPriceValue).toFixed(this.numOfCurrencyDecimals);
lineItemRow.find('.listPrice').val(listPrice);
return this;
},
/**
* Function which will set the line item total value excluding tax and discount
* @params : lineItemRow - row which represents the line item
* lineItemTotalValue - value which has line item total (qty*listprice)
* @return : current instance;
*/
setLineItemTotal : function(lineItemRow, lineItemTotalValue) {
lineItemRow.find('.productTotal').text(lineItemTotalValue);
return this;
},
/**
* Function which will get the value of line item total (qty*listprice)
* @params : lineItemRow - row which represents the line item
* @return : string
*/
getLineItemTotal : function(lineItemRow) {
var lineItemTotal = this.getLineItemTotalElement(lineItemRow).text();
if(lineItemTotal)
return parseFloat(lineItemTotal);
return 0;
},
/**
* Function which will get the line item total element
* @params : lineItemRow - row which represents the line item
* @return : jQuery element
*/
getLineItemTotalElement : function(lineItemRow) {
return lineItemRow.find('.productTotal');
},
/**
* Function which will set the discount total value for line item
* @params : lineItemRow - row which represents the line item
* discountValue - discount value
* @return : current instance;
*/
setDiscountTotal : function(lineItemRow, discountValue) {
jQuery('.discountTotal',lineItemRow).text(discountValue);
return this;
},
/**
* Function which will get the value of total discount
* @params : lineItemRow - row which represents the line item
* @return : string
*/
getDiscountTotal : function(lineItemRow) {
var element = jQuery('.discountTotal',lineItemRow);
if(element.length > 0) {
return parseFloat(element.text());
}
return 0;
},
/**
* Function which will set the total after discount value
* @params : lineItemRow - row which represents the line item
* totalAfterDiscountValue - total after discount value
* @return : current instance;
*/
setTotalAfterDiscount : function(lineItemRow, totalAfterDiscountValue){
lineItemRow.find('.totalAfterDiscount').text(totalAfterDiscountValue);
return this;
},
/**
* Function which will get the value of total after discount
* @params : lineItemRow - row which represents the line item
* @return : string
*/
getTotalAfterDiscount : function(lineItemRow) {
var element = lineItemRow.find('.totalAfterDiscount');
if(element.length > 0) {
return parseFloat(element.text());
}
return this.getLineItemTotal(lineItemRow);
},
/**
* Function which will set the tax total
* @params : lineItemRow - row which represents the line item
* taxTotal - tax total
* @return : current instance;
*/
setLineItemTaxTotal : function(lineItemRow, taxTotal) {
jQuery('.productTaxTotal', lineItemRow).text(taxTotal);
return this;
},
/**
* Function which will get the value of total tax
* @params : lineItemRow - row which represents the line item
* @return : string
*/
getLineItemTaxTotal : function(lineItemRow){
var lineItemTax = jQuery('.productTaxTotal', lineItemRow).text();
if(lineItemTax)
return parseFloat(lineItemTax);
return 0;
},
/**
* Function which will set the line item net price
* @params : lineItemRow - row which represents the line item
* lineItemNetPriceValue - line item net price value
* @return : current instance;
*/
setLineItemNetPrice : function(lineItemRow, lineItemNetPriceValue){
lineItemRow.find('.netPrice').text(lineItemNetPriceValue);
return this;
},
/**
* Function which will get the value of net price
* @params : lineItemRow - row which represents the line item
* @return : string
*/
getLineItemNetPrice : function(lineItemRow) {
return this.formatLineItemNetPrice(lineItemRow.find('.netPrice'));
},
formatLineItemNetPrice : function(netPriceEle) {
var lineItemNetPrice = netPriceEle.text();
if(lineItemNetPrice)
return parseFloat(lineItemNetPrice);
return 0;
},
setNetTotal : function(netTotalValue){
this.netTotalEle.text(netTotalValue);
return this;
},
getNetTotal : function() {
var netTotal = this.netTotalEle.text();
if(netTotal)
return parseFloat(netTotal);
return 0;
},
/**
* Function to set the final discount total
*/
setFinalDiscountTotal : function(finalDiscountValue){
this.finalDiscountTotalEle.text(finalDiscountValue);
return this;
},
getFinalDiscountTotal : function() {
var discountTotal = this.finalDiscountTotalEle.text();
if(discountTotal)
return parseFloat(discountTotal);
return 0;
},
setGroupTaxTotal : function(groupTaxTotalValue) {
this.finalTaxEle.text(groupTaxTotalValue);
},
getGroupTaxTotal : function() {
var groupTax = this.finalTaxEle.text();
if(groupTax)
return parseFloat(groupTax);
return 0
},
getChargesTotal : function() {
var chargesElement = this.chargesTotalEle;
if (chargesElement.length <= 0) {
return 0;
}
return parseFloat(chargesElement.val());
},
getChargeTaxesTotal : function() {
var taxElement = this.chargeTaxesTotal;
if (taxElement.length <= 0) {
return 0;
}
return parseFloat(taxElement.val());
},
getDeductTaxesTotal : function() {
var taxElement = this.deductTaxesTotal;
if (taxElement.length <= 0) {
return 0;
}
return parseFloat(taxElement.text());
},
/**
* Function to set the pre tax total
*/
setPreTaxTotal : function(preTaxTotalValue){
this.preTaxTotalEle.text(preTaxTotalValue);
return this;
},
/**
* Function to get the pre tax total
*/
getPreTaxTotal : function() {
if(this.preTaxTotalEle.length > 0){
return parseFloat(this.preTaxTotalEle.text())
}
},
/**
* Function which will set the margin
* @params : lineItemRow - row which represents the line item
* @params : margin
* @return : current instance;
*/
setMarginValue : function(lineItemRow, margin) {
var rowNum = this.getLineItemRowNumber(lineItemRow);
lineItemRow.find('[name="margin'+ rowNum +'"]').val(margin);
lineItemRow.find('.margin').text(margin);
return this;
},
getAdjustmentValue : function() {
return parseFloat(this.adjustmentEle.val());
},
isAdjustMentAddType : function() {
var adjustmentSelectElement = this.adjustmentTypeEles;
var selectionOption;
adjustmentSelectElement.each(function(){
if(jQuery(this).is(':checked')){
selectionOption = jQuery(this);
}
})
if(typeof selectionOption != "undefined"){
if(selectionOption.val() == '+'){
return true;
}
}
return false;
},
isAdjustMentDeductType : function() {
var adjustmentSelectElement = this.adjustmentTypeEles;
var selectionOption;
adjustmentSelectElement.each(function(){
if(jQuery(this).is(':checked')){
selectionOption = jQuery(this);
}
})
if(typeof selectionOption != "undefined"){
if(selectionOption.val() == '-'){
return true;
}
}
return false;
},
setGrandTotal : function(grandTotalValue) {
this.grandTotal.text(grandTotalValue);
return this;
},
getGrandTotal : function() {
var grandTotal = this.grandTotal.text();
if(grandTotal)
return parseFloat(grandTotal);
return 0;
},
isIndividualTaxMode : function() {
return (this.taxTypeElement.val() == Inventory_Edit_Js.individualTaxType) ? true : false;
},
isGroupTaxMode : function() {
return (this.taxTypeElement.val() == Inventory_Edit_Js.groupTaxType) ? true : false;
},
/**
* Function which will give the closest line item row element
* @return : jQuery object
*/
getClosestLineItemRow : function(element){
return element.closest('tr.'+this.lineItemDetectingClass);
},
isProductSelected : function(element){
var parentRow = element.closest('tr');
var productField = parentRow.find('.productName');
var response = productField.valid();
return response;
},
checkLineItemRow : function(){
var numRows = this.lineItemsHolder.find('.'+this.lineItemDetectingClass).length;
if(numRows > 1) {
this.showLineItemsDeleteIcon();
}else{
this.hideLineItemsDeleteIcon();
}
},
showLineItemsDeleteIcon : function(){
this.lineItemsHolder.find('.deleteRow').show();
},
hideLineItemsDeleteIcon : function(){
this.lineItemsHolder.find('.deleteRow').hide();
},
clearLineItemDetails : function(parentElem) {
var lineItemRow = this.getClosestLineItemRow(parentElem);
jQuery('[id*="purchaseCost"]', lineItemRow).val('0');
jQuery('.lineItemImage', lineItemRow).html('');
jQuery('input.selectedModuleId',lineItemRow).val('');
jQuery('input.listPrice',lineItemRow).val('0');
jQuery('.lineItemCommentBox', lineItemRow).val('');
jQuery('.subProductIds', lineItemRow).val('');
jQuery('.subProductsContainer', lineItemRow).html('');
this.quantityChangeActions(lineItemRow);
},
saveProductCount : function () {
jQuery('#totalProductCount').val(this.lineItemsHolder.find('tr.'+this.lineItemDetectingClass).length);
},
saveSubTotalValue : function() {
jQuery('#subtotal').val(this.getNetTotal());
},
saveTotalValue : function() {
jQuery('#total').val(this.getGrandTotal());
},
/**
* Function to save the pre tax total value
*/
savePreTaxTotalValue : function() {
jQuery('#pre_tax_total').val(this.getPreTaxTotal());
},
updateRowNumberForRow : function(lineItemRow, expectedSequenceNumber, currentSequenceNumber){
if(typeof currentSequenceNumber == 'undefined') {
//by default there will zero current sequence number
currentSequenceNumber = 0;
}
var idFields = new Array('productName','subproduct_ids','hdnProductId','purchaseCost','margin',
'comment','qty','listPrice','discount_div','discount_type','discount_percentage',
'discount_amount','lineItemType','searchIcon','netPrice','subprod_names',
'productTotal','discountTotal','totalAfterDiscount','taxTotal');
var classFields = new Array('taxPercentage');
//To handle variable tax ids
for(var classIndex in classFields) {
var className = classFields[classIndex];
jQuery('.'+className,lineItemRow).each(function(index, domElement){
var idString = domElement.id
//remove last character which will be the row number
idFields.push(idString.slice(0,(idString.length-1)));
});
}
var expectedRowId = 'row'+expectedSequenceNumber;
for(var idIndex in idFields ) {
var elementId = idFields[idIndex];
var actualElementId = elementId + currentSequenceNumber;
var expectedElementId = elementId + expectedSequenceNumber;
lineItemRow.find('#'+actualElementId).attr('id',expectedElementId)
.filter('[name="'+actualElementId+'"]').attr('name',expectedElementId);
}
var nameFields = new Array('discount', 'purchaseCost', 'margin');
for (var nameIndex in nameFields) {
var elementName = nameFields[nameIndex];
var actualElementName = elementName+currentSequenceNumber;
var expectedElementName = elementName+expectedSequenceNumber;
lineItemRow.find('[name="'+actualElementName+'"]').attr('name', expectedElementName);
}
lineItemRow.attr('id', expectedRowId).attr('data-row-num', expectedSequenceNumber);
lineItemRow.find('input.rowNumber').val(expectedSequenceNumber);
return lineItemRow;
},
updateLineItemElementByOrder : function () {
var self = this;
var checkedDiscountElements = {};
var lineItems = this.lineItemsHolder.find('tr.'+this.lineItemDetectingClass);
lineItems.each(function(index,domElement){
var lineItemRow = jQuery(domElement);
var actualRowId = lineItemRow.attr('id');
var discountContianer = lineItemRow.find('div.discountUI');
var element = discountContianer.find('input.discounts').filter(':checked');
checkedDiscountElements[actualRowId] = element.data('discountType');
});
lineItems.each(function(index,domElement){
var lineItemRow = jQuery(domElement);
var expectedRowIndex = (index+1);
var expectedRowId = 'row'+expectedRowIndex;
var actualRowId = lineItemRow.attr('id');
if(expectedRowId != actualRowId) {
var actualIdComponents = actualRowId.split('row');
self.updateRowNumberForRow(lineItemRow, expectedRowIndex, actualIdComponents[1]);
var discountContianer = lineItemRow.find('div.discountUI');
discountContianer.find('input.discounts').each(function(index1, discountElement) {
var discountElement = jQuery(discountElement);
var discountType = discountElement.data('discountType');
if (discountType == checkedDiscountElements[actualRowId]) {
discountElement.attr('checked', true);
}
});
}
});
},
/**
* Function which will initialize line items custom fields with default values if exists
*/
initializeLineItemRowCustomFields : function(lineItemRow, rowNum) {
var lineItemType = lineItemRow.find('input.lineItemType').val();
for(var cfName in this.customLineItemFields) {
var elementName = cfName + rowNum;
var element = lineItemRow.find('[name="'+elementName+'"]');
var cfDataType = this.customLineItemFields[cfName];
if (cfDataType == 'picklist' || cfDataType == 'multipicklist') {
(cfDataType == 'multipicklist') && (element = lineItemRow.find('[name="'+elementName+'[]"]'));
var picklistValues = element.data('productPicklistValues');
(lineItemType == 'Services') && (picklistValues = element.data('servicePicklistValues'));
var options = '';
(cfDataType == 'picklist') && (options = '');
for(var picklistName in picklistValues) {
var pickListValue = picklistValues[picklistName];
options += '';
}
element.html(options);
element.addClass('select2');
}
var defaultValueInfo = this.customFieldsDefaultValues[cfName];
if (defaultValueInfo) {
var defaultValue = defaultValueInfo;
if (typeof defaultValueInfo == 'object') {
defaultValue = defaultValueInfo['productFieldDefaultValue'];
(lineItemType == 'Services') && (defaultValue = defaultValueInfo['serviceFieldDefaultValue'])
}
if (cfDataType === 'multipicklist') {
if (defaultValue.length > 0) {
defaultValue = defaultValue.split(" |##| ");
var setDefaultValue = function(picklistElement, values){
for(var index in values) {
var picklistVal = values[index];
picklistElement.find('option[value="'+picklistVal+'"]').prop('selected',true);
}
}(element, defaultValue)
}
} else {
element.val(defaultValue);
}
} else {
defaultValue = '';
element.val(defaultValue);
}
}
return lineItemRow;
},
getLineItemSetype : function(row) {
return row.find('.lineItemType').val();
},
getNewLineItem : function(params) {
var currentTarget = params.currentTarget;
var itemType = currentTarget.data('moduleName');
var newRow = this.dummyLineItemRow.clone(true).removeClass('hide').addClass(this.lineItemDetectingClass).removeClass('lineItemCloneCopy');
var individualTax = this.isIndividualTaxMode();
if(individualTax){
newRow.find('.individualTaxContainer').removeClass('hide');
}
newRow.find('.lineItemPopup').filter(':not([data-module-name="'+ itemType +'"])').remove();
newRow.find('.lineItemType').val(itemType);
var newRowNum = this.getLineItemNextRowNumber();
this.updateRowNumberForRow(newRow, newRowNum);
this.initializeLineItemRowCustomFields(newRow, newRowNum);
return newRow
},
/**
* Function which will calculate line item total excluding discount and tax
* @params : lineItemRow - element which will represent lineItemRow
*/
calculateLineItemTotal : function (lineItemRow) {
var quantity = this.getQuantityValue(lineItemRow);
var listPrice = this.getListPriceValue(lineItemRow);
var lineItemTotal = parseFloat(quantity) * parseFloat(listPrice);
this.setLineItemTotal(lineItemRow,lineItemTotal.toFixed(this.numOfCurrencyDecimals));
},
/**
* Function which will calculate discount for the line item
* @params : lineItemRow - element which will represent lineItemRow
*/
calculateDiscountForLineItem : function(lineItemRow) {
var discountContianer = lineItemRow.find('div.discountUI');
var element = discountContianer.find('input.discounts').filter(':checked');
var discountType = element.data('discountType');
var discountRow = element.closest('tr');
jQuery('input.discount_type',discountContianer).val(discountType);
var rowPercentageField = jQuery('input.discount_percentage',discountContianer);
var rowAmountField = jQuery('input.discount_amount',discountContianer);
//intially making percentage and amount discount fields as hidden
rowPercentageField.addClass('hide');
rowAmountField.addClass('hide');
var discountValue = discountRow.find('.discountVal').val();
if(discountValue == ""){
discountValue = 0;
}
if(isNaN(discountValue) || discountValue < 0){
discountValue = 0;
}
var productTotal = this.getLineItemTotal(lineItemRow);
var lineItemDiscount = '('+discountValue+')';
if(discountType == Inventory_Edit_Js.percentageDiscountType) {
lineItemDiscount = '('+discountValue+'%)';
rowPercentageField.removeClass('hide').focus();
//since it is percentage
discountValue = (productTotal * discountValue)/100;
} else if(discountType == Inventory_Edit_Js.directAmountDiscountType) {
rowAmountField.removeClass('hide').focus();
}
jQuery('.itemDiscount', lineItemRow).text(lineItemDiscount);
jQuery('.productTotalVal', lineItemRow).text(productTotal.toFixed(this.numOfCurrencyDecimals));
this.setDiscountTotal(lineItemRow, parseFloat(discountValue).toFixed(this.numOfCurrencyDecimals))
.calculateTotalAfterDiscount(lineItemRow);
},
/**
* Function which will calculate line item total after discount
* @params : lineItemRow - element which will represent lineItemRow
*/
calculateTotalAfterDiscount: function(lineItemRow) {
var productTotal = this.getLineItemTotal(lineItemRow);
var discountTotal = this.getDiscountTotal(lineItemRow);
var totalAfterDiscount = productTotal - discountTotal;
totalAfterDiscount = totalAfterDiscount.toFixed(this.numOfCurrencyDecimals);
this.setTotalAfterDiscount(lineItemRow,totalAfterDiscount);
var purchaseCost = parseFloat(lineItemRow.find('.purchaseCost').text());
var margin = totalAfterDiscount - purchaseCost;
margin = parseFloat(margin.toFixed(2));
this.setMarginValue(lineItemRow, margin);
},
/**
* Function which will calculate tax for the line item total after discount
*/
calculateTaxForLineItem : function(lineItemRow) {
var self = this;
var totalAfterDiscount = this.getTotalAfterDiscount(lineItemRow);
var taxPercentages = jQuery('.taxPercentage',lineItemRow);
//intially make the tax as zero
var taxTotal = 0;
jQuery.each(taxPercentages,function(index,domElement){
var taxPercentage = jQuery(domElement);
var individualTaxRow = taxPercentage.closest('tr');
var individualTaxPercentage = taxPercentage.val();
if(individualTaxPercentage == ""){
individualTaxPercentage = "0";
}
if(isNaN(individualTaxPercentage)){
var individualTaxTotal = "0";
} else {
var individualTaxPercentage = parseFloat(individualTaxPercentage);
var individualTaxTotal = Math.abs(individualTaxPercentage * totalAfterDiscount)/100;
individualTaxTotal = individualTaxTotal.toFixed(self.numOfCurrencyDecimals);
}
individualTaxRow.find('.taxTotal').val(individualTaxTotal);
});
//Calculation compound taxes
var taxTotal = 0;
jQuery.each(taxPercentages, function(index, domElement){
var taxElement = jQuery(domElement);
var taxRow = taxElement.closest('tr');
var total = jQuery('.taxTotal', taxRow).val();
var compoundOn = taxElement.data('compoundOn');
if (compoundOn) {
var amount = parseFloat(totalAfterDiscount);
jQuery.each(compoundOn, function(index, id) {
if(!isNaN(jQuery('.taxTotal'+id, lineItemRow).val())) {
amount = parseFloat(amount) + parseFloat(jQuery('.taxTotal'+id, lineItemRow).val());
}
});
if(isNaN(taxElement.val())) {
var total = 0;
} else {
var total = Math.abs(amount * taxElement.val())/100;
}
taxRow.find('.taxTotal').val(total);
}
taxTotal += parseFloat(total);
});
taxTotal = parseFloat(taxTotal).toFixed(self.numOfCurrencyDecimals);
this.setLineItemTaxTotal(lineItemRow, taxTotal);
},
/**
* Function which will calculate net price for the line item
*/
calculateLineItemNetPrice : function(lineItemRow) {
var totalAfterDiscount = this.getTotalAfterDiscount(lineItemRow);
var netPrice = parseFloat(totalAfterDiscount);
if(this.isIndividualTaxMode()) {
var productTaxTotal = this.getLineItemTaxTotal(lineItemRow);
netPrice += parseFloat(productTaxTotal)
}
netPrice = netPrice.toFixed(this.numOfCurrencyDecimals);
this.setLineItemNetPrice(lineItemRow,netPrice);
},
/**
* Function which will caliculate the total net price for all the line items
*/
calculateNetTotal : function() {
var self = this
var netTotalValue = 0;
this.lineItemsHolder.find('tr.'+this.lineItemDetectingClass+' .netPrice').each(function(index,domElement){
var lineItemNetPriceEle = jQuery(domElement);
netTotalValue += self.formatLineItemNetPrice(lineItemNetPriceEle);
});
this.setNetTotal(netTotalValue.toFixed(this.numOfCurrencyDecimals));
this.finalDiscountUIEle.find('.subTotalVal').text(netTotalValue);
},
calculateFinalDiscount : function() {
var discountContainer = this.finalDiscountUIEle;
var element = discountContainer.find('input.finalDiscounts').filter(':checked');
var discountType = element.data('discountType');
var discountRow = element.closest('tr');
var numberOfDecimal = this.numOfCurrencyDecimals;
jQuery('#discount_type_final').val(discountType);
var rowPercentageField = discountContainer.find('input.discount_percentage_final');
var rowAmountField = discountContainer.find('input.discount_amount_final');
//intially making percentage and amount discount fields as hidden
rowPercentageField.addClass('hide');
rowAmountField.addClass('hide');
var discountValue = discountRow.find('.discountVal').val();
if(discountValue == ""){
discountValue = 0;
}
if(isNaN(discountValue) || discountValue < 0){
discountValue = 0;
}
var overallDiscount = '('+discountValue+')';
if(discountType == Inventory_Edit_Js.percentageDiscountType){
overallDiscount = '('+discountValue+'%)';
rowPercentageField.removeClass('hide').focus();
//since it is percentage
var productTotal = this.getNetTotal();
discountValue = (productTotal * discountValue)/100;
}else if(discountType == Inventory_Edit_Js.directAmountDiscountType){
if(this.prevSelectedCurrencyConversionRate){
var conversionRate = this.conversionRateEle.val();
conversionRate = conversionRate / this.prevSelectedCurrencyConversionRate;
discountValue = discountValue * conversionRate;
discountRow.find('.discountVal').val(discountValue);
}
rowAmountField.removeClass('hide').focus();
}
discountValue = parseFloat(discountValue).toFixed(numberOfDecimal);
this.overAllDiscountEle.text(overallDiscount);
this.setFinalDiscountTotal(discountValue);
this.calculatePreTaxTotal();
},
/**
* Function to calculate the preTaxTotal value
*/
calculatePreTaxTotal : function() {
var numberOfDecimal = this.numOfCurrencyDecimals;
if (this.isGroupTaxMode()) {
var netTotal = this.getNetTotal();
} else {
var thisInstance = this;
var netTotal = 0;
var elementsList = this.lineItemsHolder.find('.'+ this.lineItemDetectingClass);
jQuery.each(elementsList, function(index, element) {
var lineItemRow = jQuery(element);
netTotal = netTotal + thisInstance.getTotalAfterDiscount(lineItemRow);
});
}
var chargesTotal = this.getChargesTotal();
var finalDiscountValue = this.getFinalDiscountTotal();
var preTaxTotal = netTotal + chargesTotal - finalDiscountValue;
var preTaxTotalValue = parseFloat(preTaxTotal).toFixed(numberOfDecimal);
this.setPreTaxTotal(preTaxTotalValue);
},
calculateCharges : function() {
var chargesBlockContainer = this.chargesContainer;
var numberOfDecimal = this.numOfCurrencyDecimals;
var netTotal = this.getNetTotal();
var finalDiscountValue = this.getFinalDiscountTotal();
var amount = parseFloat(netTotal-finalDiscountValue).toFixed(numberOfDecimal);
chargesBlockContainer.find('.chargePercent').each(function(index, domElement){
var element = jQuery(domElement);
if(isNaN(element.val())) {
var value = 0;
} else {
var value = Math.abs(amount * element.val())/100;
}
element.closest('tr').find('.chargeValue').val(parseFloat(value).toFixed(numberOfDecimal));
});
var chargesTotal = 0;
chargesBlockContainer.find('.chargeValue').each(function(index, domElement){
var chargeElementValue = jQuery(domElement).val();
if(!chargeElementValue){
jQuery(domElement).val(0);
chargeElementValue=0;
}
chargesTotal = parseFloat(chargesTotal) + parseFloat(chargeElementValue);
});
this.chargesTotalEle.val(parseFloat(chargesTotal));
this.chargesTotalDisplay.text(parseFloat(chargesTotal).toFixed(numberOfDecimal));
jQuery('#SHChargeVal').text(chargesTotal.toFixed(numberOfDecimal));
this.calculateChargeTaxes();
// this.calculatePreTaxTotal();
// this.calculateGrandTotal();
},
calculateChargeTaxes : function() {
var self = this;
var chargesBlockContainer = this.chargeTaxesContainer;
chargesBlockContainer.find('.chargeTaxPercentage').each(function(index, domElement){
var element = jQuery(domElement);
var chargeId = element.data('chargeId');
var chargeAmount = self.chargesContainer.find('[name="charges['+chargeId+'][value]"]').val();
if(isNaN(element.val())) {
var value = 0;
} else {
var value = Math.abs(chargeAmount * element.val())/100;
}
element.closest('tr').find('.chargeTaxValue').val(parseFloat(value).toFixed(self.numOfCurrencyDecimals));
});
chargesBlockContainer.find('.chargeTaxPercentage').each(function(index, domElement){
var element = jQuery(domElement);
var compoundOn = element.data('compoundOn');
if (compoundOn) {
var chargeId = element.data('chargeId');
var chargeAmount = parseFloat(self.chargesContainer.find('[name="charges['+chargeId+'][value]"]').val()).toFixed(self.numOfCurrencyDecimals);
jQuery.each(compoundOn, function(index, id) {
var chargeTaxEle = chargesBlockContainer.find('.chargeTax'+chargeId+id);
if(!isNaN(chargeTaxEle.val())) {
chargeAmount = parseFloat(chargeAmount) + parseFloat(chargeTaxEle.val());
}
});
if(isNaN(element.val())) {
var value = 0;
} else {
var value = Math.abs(chargeAmount * element.val())/100;
}
element.closest('tr').find('.chargeTaxValue').val(parseFloat(value).toFixed(self.numOfCurrencyDecimals));
}
});
var chargesTotal = 0;
chargesBlockContainer.find('.chargeTaxValue').each(function(index, domElement){
var chargeElementValue = jQuery(domElement).val();
chargesTotal = parseFloat(chargesTotal) + parseFloat(chargeElementValue);
});
jQuery('#chargeTaxTotal').text(parseFloat(chargesTotal).toFixed(this.numOfCurrencyDecimals));
this.chargeTaxesTotal.val(parseFloat(chargesTotal).toFixed(this.numOfCurrencyDecimals));
this.calculatePreTaxTotal();
this.calculateGrandTotal();
},
calculateGrandTotal : function(){
var netTotal = this.getNetTotal();
var discountTotal = this.getFinalDiscountTotal();
var shippingHandlingCharge = this.getChargesTotal();
var shippingHandlingTax = this.getChargeTaxesTotal();
var deductedTaxesAmount = this.getDeductTaxesTotal();
var adjustment = this.getAdjustmentValue();
var grandTotal = parseFloat(netTotal) - parseFloat(discountTotal) + parseFloat(shippingHandlingCharge) + parseFloat(shippingHandlingTax) - parseFloat(deductedTaxesAmount);
if(this.isGroupTaxMode()){
grandTotal += this.getGroupTaxTotal();
}
if(this.isAdjustMentAddType()) {
grandTotal += parseFloat(adjustment);
}else if(this.isAdjustMentDeductType()) {
grandTotal -= parseFloat(adjustment);
}
grandTotal = grandTotal.toFixed(this.numOfCurrencyDecimals);
this.setGrandTotal(grandTotal);
},
calculateGroupTax : function() {
var self = this;
var netTotal = this.getNetTotal();
var finalDiscountValue = this.getFinalDiscountTotal();
var amount = netTotal - finalDiscountValue;
amount = parseFloat(amount).toFixed(this.numOfCurrencyDecimals);
var groupTaxTotal = 0;
this.groupTaxContainer.find('.groupTaxPercentage').each(function(index, domElement) {
var groupTaxPercentageElement = jQuery(domElement);
var groupTaxRow = groupTaxPercentageElement.closest('tr');
if(isNaN(groupTaxPercentageElement.val())){
var groupTaxValue = "0";
} else {
var groupTaxValue = Math.abs(amount * groupTaxPercentageElement.val())/100;
}
groupTaxValue = parseFloat(groupTaxValue).toFixed(self.numOfCurrencyDecimals);
groupTaxRow.find('.groupTaxTotal').val(groupTaxValue);
});
//Calculating compound taxes
groupTaxTotal = 0;
this.groupTaxContainer.find('.groupTaxPercentage').each(function(index, domElement) {
var groupTaxPercentageElement = jQuery(domElement);
var compoundOn = groupTaxPercentageElement.data('compoundOn');
var groupTaxRow = groupTaxPercentageElement.closest('tr');
if (compoundOn) {
var totalAmount = amount;
jQuery.each(compoundOn, function(index, value) {
var groupTaxAmountValue = self.groupTaxContainer.find('[name="tax'+value+'_group_amount"]').val();
if(!isNaN(groupTaxAmountValue)) {
totalAmount = parseFloat(totalAmount) + parseFloat(groupTaxAmountValue);
}
});
if (isNaN(groupTaxPercentageElement.val())) {
var groupTaxValue = 0;
} else {
var groupTaxValue = Math.abs(totalAmount * groupTaxPercentageElement.val()) / 100;
}
groupTaxValue = parseFloat(groupTaxValue).toFixed(self.numOfCurrencyDecimals);
groupTaxRow.find('.groupTaxTotal').val(groupTaxValue);
} else {
var groupTaxValue = groupTaxRow.find('.groupTaxTotal').val();
}
if(isNaN(groupTaxValue)) {
groupTaxValue = 0;
}
groupTaxTotal += parseFloat(groupTaxValue);
});
this.setGroupTaxTotal(groupTaxTotal.toFixed(this.numOfCurrencyDecimals));
},
calculateDeductTaxes : function() {
var self = this;
var netTotal = this.getNetTotal();
var finalDiscountValue = this.getFinalDiscountTotal();
var amount = parseFloat(netTotal-finalDiscountValue).toFixed(this.numOfCurrencyDecimals);
var deductTaxesTotalAmount = 0;
this.dedutTaxesContainer.find('.deductTaxPercentage').each(function(index, domElement){
var value = 0;
var element = jQuery(domElement);
if(!isNaN(element.val())) {
value = Math.abs(amount * element.val())/100;
}
value = parseFloat(value).toFixed(self.numOfCurrencyDecimals);
element.closest('tr').find('.deductTaxValue').val(value);
deductTaxesTotalAmount = parseFloat(deductTaxesTotalAmount) + parseFloat(value);
});
this.deductTaxesTotal.text(parseFloat(deductTaxesTotalAmount).toFixed(this.numOfCurrencyDecimals));
this.calculateGrandTotal();
},
lineItemDirectDiscountCal: function(conversionRate){
//LineItems Discount Calculations for direct Price reduction
var self = this;
self.lineItemsHolder.find('tr.'+self.lineItemDetectingClass).each(function(index, domElement) {
var lineItemRow = jQuery(domElement);
var discountContianer = lineItemRow.find('div.discountUI');
var element = discountContianer.find('input.discounts').filter(':checked');
var discountRow = element.closest('tr');
var discountType = element.data('discountType');
var discountValue = discountRow.find('.discountVal').val();
if((discountType == Inventory_Edit_Js.directAmountDiscountType) ){
var newdiscountValue = conversionRate * discountValue;
discountRow.find('.discountVal').val(newdiscountValue);
jQuery(element).closest('tr').find('.discountVal').val(newdiscountValue);
self.setDiscountTotal(lineItemRow,newdiscountValue.toFixed(self.numberOfCurrencyDecimals));
}
});
},
AdjustmentShippingResultCalculation: function(conversionRate){
//Adjustment
var self = this;
var adjustmentElement = this.adjustmentEle;
var newAdjustment = jQuery(adjustmentElement).val() * conversionRate;
jQuery(adjustmentElement).val(newAdjustment);
//Shipping & handling
var chargesBlockContainer = self.chargesContainer;
chargesBlockContainer.find('.chargeValue').each(function(index, domElement){
var chargeElement = jQuery(domElement);
jQuery(chargeElement).val(parseFloat(jQuery(domElement).val()) * conversionRate);
});
this.calculateCharges();
},
lineItemRowCalculations : function(lineItemRow) {
this.calculateLineItemTotal(lineItemRow);
this.calculateDiscountForLineItem(lineItemRow);
this.calculateTaxForLineItem(lineItemRow);
this.calculateLineItemNetPrice(lineItemRow);
},
lineItemToTalResultCalculations : function(){
this.calculateNetTotal();
this.calculateFinalDiscount();
this.calculateCharges();
if(this.isGroupTaxMode()){
this.calculateGroupTax();
}
this.calculateDeductTaxes();
this.calculateGrandTotal();
},
/**
* Function which will handle the actions that need to be performed once the tax percentage is change for a line item
* @params : lineItemRow - element which will represent lineItemRow
*/
taxPercentageChangeActions : function(lineItemRow){
this.calculateLineItemNetPrice(lineItemRow);
this.calculateNetTotal();
this.calculateFinalDiscount();
if(this.isGroupTaxMode()){
this.calculateGroupTax();
}
this.lineItemToTalResultCalculations();
this.calculateGrandTotal();
},
lineItemDiscountChangeActions : function(lineItemRow){
this.calculateDiscountForLineItem(lineItemRow);
this.calculateTaxForLineItem(lineItemRow);
this.calculateLineItemNetPrice(lineItemRow);
this.lineItemToTalResultCalculations();
},
finalDiscountChangeActions : function() {
this.calculateChargeTaxes();
this.calculateFinalDiscount();
if(this.isGroupTaxMode()){
this.calculateGroupTax();
}
this.calculateCharges();
this.calculateDeductTaxes();
this.calculateGrandTotal();
},
lineItemDeleteActions : function() {
this.lineItemToTalResultCalculations();
},
loadSubProducts : function(lineItemRow) {
var recordId = jQuery('input.selectedModuleId',lineItemRow).val();
var subProrductParams = {
'module' : "Products",
'action' : "SubProducts",
'record' : recordId
}
app.request.get({'data':subProrductParams}).then(
function(error, data){
if(!data){
return;
}
var result = data;
var isBundleViewable = result.isBundleViewable;
var responseData = result.values;
var subProductsContainer = jQuery('.subProductsContainer',lineItemRow);
var subProductIdHolder = jQuery('.subProductIds',lineItemRow);
var subProductIdsList = '';
var subProductHtml = '';
for(var id in responseData) {
if (isBundleViewable == 1) {
subProductHtml += ' - '+responseData[id]['productName'] + ' (' +responseData[id]['quantity']+')';
if (responseData[id]['stockMessage']) {
subProductHtml += ' - '+responseData[id]['stockMessage']+'';
}
subProductHtml += ' ';
}
subProductIdsList += id+':'+responseData[id]['quantity']+',';
}
subProductIdHolder.val(subProductIdsList);
subProductsContainer.html(subProductHtml);
}
);
},
/**
* Function which will handle the actions that need to be preformed once the qty is changed like below
* - calculate line item total -> discount and tax -> net price of line item -> grand total
* @params : lineItemRow - element which will represent lineItemRow
*/
quantityChangeActions : function(lineItemRow) {
var purchaseCost = this.getPurchaseCostValue(lineItemRow);
this.setPurchaseCostValue(lineItemRow, purchaseCost);
this.lineItemRowCalculations(lineItemRow);
this.lineItemToTalResultCalculations();
},
getTaxDiv: function(taxObj,parentRow){
var rowNumber = jQuery('input.rowNumber',parentRow).val();
var loopIterator = 1;
var taxDiv =
'
'+
'
Set Tax for :
';
if(!jQuery.isEmptyObject(taxObj)){
taxDiv +=
'
'+
'
';
for(var taxName in taxObj){
var taxInfo = taxObj[taxName];
taxDiv +=
'