/*+***********************************************************************************
* 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'
},{
//Container which stores the line item elements
lineItemContentsContainer : false,
//Container which stores line item result details
lineItemResultContainer : false,
//contains edit view form element
editViewForm : false,
//a variable which will be used to hold the sequence of the row
rowSequenceHolder : false,
//holds the element which has basic hidden row which we can clone to add rows
basicRow : false,
//will be having class which is used to identify the rows
rowClass : 'lineItemRow',
prevSelectedCurrencyConversionRate : false,
//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'
}
},
//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'
}
},
//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'
},
/**
* 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 to set line item container
* @params : element - jQuery object which represents line item container
* @return : current instance ;
*/
setLineItemContainer : function(element) {
this.lineItemContentsContainer = element;
return this;
},
/**
* Function to get the line item result container
* @result : jQuery object which represent line item result container
*/
getLineItemResultContainer : function(){
if(this.lineItemResultContainer == false) {
this.setLinteItemResultContainer(jQuery('#lineItemResult'));
}
return this.lineItemResultContainer;
},
/**
* Function to set line item result container
* @param : element - jQuery object which represents line item result container
* @result : current instance
*/
setLinteItemResultContainer : function(element) {
this.lineItemResultContainer = element;
return this;
},
/**
* Function which will give the closest line item row element
* @return : jQuery object
*/
getClosestLineItemRow : function(element){
return element.closest('tr.'+this.rowClass);
},
getShippingAndHandlingControlElement : function(){
return jQuery('#shipping_handling_charge');
},
getAdjustmentTypeElement : function() {
return jQuery('input:radio[name="adjustmentType"]');
},
getAdjustmentTextElement : function(){
return jQuery('#adjustment');
},
getTaxTypeSelectElement : function(){
return jQuery('#taxtype');
},
isIndividualTaxMode : function() {
var taxTypeElement = this.getTaxTypeSelectElement();
var selectedOption = taxTypeElement.find('option:selected');
if(selectedOption.val() == Inventory_Edit_Js.individualTaxType){
return true;
}
return false;
},
isGroupTaxMode : function() {
var taxTypeElement = this.getTaxTypeSelectElement();
var selectedOption = taxTypeElement.find('option:selected');
if(selectedOption.val() == Inventory_Edit_Js.groupTaxType){
return true;
}
return false;
},
/**
* Function which gives edit view form
* @return : jQuery object which represents the form element
*/
getForm : function() {
if(this.editViewForm == false){
this.editViewForm = jQuery('#EditView');
}
return this.editViewForm;
},
/**
* Function which gives quantity value
* @params : lineItemRow - row which represents the line item
* @return : string
*/
getQuantityValue : function(lineItemRow){
return parseFloat(jQuery('.qty', lineItemRow).val());
},
/**
* Function which will give me list price value
* @params : lineItemRow - row which represents the line item
* @return : string
*/
getListPriceValue : function(lineItemRow) {
return parseFloat(jQuery('.listPrice',lineItemRow).val());
},
setListPriceValue : function(lineItemRow, listPriceValue) {
var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val());
var listPrice = parseFloat(listPriceValue).toFixed(numberOfDecimal);
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) {
jQuery('.productTotal', lineItemRow).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) {
return parseFloat(this.getLineItemTotalElement(lineItemRow).text());
},
/**
* Function which will get the line item total element
* @params : lineItemRow - row which represents the line item
* @return : jQuery element
*/
getLineItemTotalElement : function(lineItemRow) {
return jQuery('.productTotal', lineItemRow);
},
/**
* 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) {
return parseFloat(jQuery('.discountTotal',lineItemRow).text());
},
/**
* 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){
jQuery('.totalAfterDiscount',lineItemRow).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) {
return parseFloat(jQuery('.totalAfterDiscount',lineItemRow).text());
},
/**
* 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){
return parseFloat(jQuery('.productTaxTotal', lineItemRow).text());
},
/**
* 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){
jQuery('.netPrice',lineItemRow).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 parseFloat(jQuery('.netPrice',lineItemRow).text());
},
setNetTotal : function(netTotalValue){
jQuery('#netTotal').text(netTotalValue);
return this;
},
getNetTotal : function() {
return parseFloat(jQuery('#netTotal').text());
},
/**
* Function to set the final discount total
*/
setFinalDiscountTotal : function(finalDiscountValue){
jQuery('#discountTotal_final').text(finalDiscountValue);
return this;
},
getFinalDiscountTotal : function() {
return parseFloat(jQuery('#discountTotal_final').text());
},
setGroupTaxTotal : function(groupTaxTotalValue) {
jQuery('#tax_final').text(groupTaxTotalValue);
},
getGroupTaxTotal : function() {
return parseFloat(jQuery('#tax_final').text());
},
getShippingAndHandling : function() {
return parseFloat(this.getShippingAndHandlingControlElement().val());
},
setShippingAndHandlingTaxTotal : function() {
var shippingTotal = jQuery('.shippingTaxTotal');
var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val());
var shippingFinalTaxTotal = 0;
jQuery.each(shippingTotal,function(index,domElement){
var totalVal = parseFloat(jQuery(domElement).val());
shippingFinalTaxTotal += totalVal;
});
shippingFinalTaxTotal = shippingFinalTaxTotal.toFixed(numberOfDecimal);
jQuery('#shipping_handling_tax').text(shippingFinalTaxTotal);
return this;
},
getShippingAndHandlingTaxTotal : function() {
return parseFloat(jQuery('#shipping_handling_tax').text());
},
getAdjustmentValue : function() {
return parseFloat(this.getAdjustmentTextElement().val());
},
isAdjustMentAddType : function() {
var adjustmentSelectElement = this.getAdjustmentTypeElement();
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.getAdjustmentTypeElement();
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) {
jQuery('#grandTotal').text(grandTotalValue);
return this;
},
getGrandTotal : function() {
return parseFloat(jQuery('#grandTotal').text());
},
loadRowSequenceNumber: function() {
if(this.rowSequenceHolder == false) {
this.rowSequenceHolder = jQuery('.' + this.rowClass, this.getLineItemContentsContainer()).length;
}
return this;
},
getNextLineItemRowNumber : function() {
if(this.rowSequenceHolder == false){
this.loadRowSequenceNumber();
}
return ++this.rowSequenceHolder;
},
/**
* Function which will return the basic row which can be used to add new rows
* @return jQuery object which you can use to
*/
getBasicRow : function() {
if(this.basicRow == false){
var lineItemTable = this.getLineItemContentsContainer();
this.basicRow = jQuery('.lineItemCloneCopy',lineItemTable)
}
var newRow = this.basicRow.clone(true,true);
var individualTax = this.isIndividualTaxMode();
if(individualTax){
newRow.find('.individualTaxContainer').removeClass('hide');
}
return newRow.removeClass('hide lineItemCloneCopy');
},
registerAddingNewProductsAndServices: function(){
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
jQuery('#addProduct').on('click',function(){
var newRow = thisInstance.getBasicRow().addClass(thisInstance.rowClass);
jQuery('.lineItemPopup[data-module-name="Services"]',newRow).remove();
var sequenceNumber = thisInstance.getNextLineItemRowNumber();
newRow = newRow.appendTo(lineItemTable);
thisInstance.checkLineItemRow();
newRow.find('input.rowNumber').val(sequenceNumber);
thisInstance.updateLineItemsElementWithSequenceNumber(newRow,sequenceNumber);
newRow.find('input.productName').addClass('autoComplete');
thisInstance.registerLineItemAutoComplete(newRow);
});
jQuery('#addService').on('click',function(){
var newRow = thisInstance.getBasicRow().addClass(thisInstance.rowClass);
jQuery('.lineItemPopup[data-module-name="Products"]',newRow).remove();
var sequenceNumber = thisInstance.getNextLineItemRowNumber();
newRow = newRow.appendTo(lineItemTable);
thisInstance.checkLineItemRow();
newRow.find('input.rowNumber').val(sequenceNumber);
thisInstance.updateLineItemsElementWithSequenceNumber(newRow,sequenceNumber);
newRow.find('input.productName').addClass('autoComplete');
thisInstance.registerLineItemAutoComplete(newRow);
});
},
getTaxDiv: function(taxObj,parentRow){
var rowNumber = jQuery('input.rowNumber',parentRow).val();
var loopIterator = 1;
var taxDiv = '
'+
'
';
return jQuery(taxDiv);
},
loadSubProducts : function(lineItemRow) {
var recordId = jQuery('input.selectedModuleId',lineItemRow).val();
var subProrductParams = {
'module' : "Products",
'action' : "SubProducts",
'record' : recordId
}
var progressInstace = jQuery.progressIndicator();
AppConnector.request(subProrductParams).then(
function(data){
var responseData = data.result;
var subProductsContainer = jQuery('.subProductsContainer',lineItemRow);
var subProductIdHolder = jQuery('.subProductIds',lineItemRow);
var subProductHtml = '';
for(var id in responseData) {
subProductHtml += '-'+responseData[id]+'
';
}
subProductIdHolder.val(Object.keys(responseData).join(':'));
subProductsContainer.html(subProductHtml);
progressInstace.hide();
},
function(error,err){
//TODO : handle the error case
}
);
},
mapResultsToFields: function(referenceModule,element,responseData){
var parentRow = jQuery(element).closest('tr.'+this.rowClass);
var lineItemNameElment = jQuery('input.productName',parentRow);
for(var id in responseData){
var recordId = id;
var recordData = responseData[id];
var selectedName = recordData.name;
var unitPrice = recordData.listprice;
var listPriceValues = recordData.listpricevalues;
var taxes = recordData.taxes;
if(referenceModule == 'Products') {
parentRow.data('quantity-in-stock',recordData.quantityInStock);
}
var description = recordData.description;
jQuery('input.selectedModuleId',parentRow).val(recordId);
jQuery('input.lineItemType',parentRow).val(referenceModule);
lineItemNameElment.val(selectedName);
lineItemNameElment.attr('disabled', 'disabled');
jQuery('input.listPrice',parentRow).val(unitPrice);
var currencyId = jQuery("#currency_id").val();
var listPriceValuesJson = JSON.stringify(listPriceValues);
if(typeof listPriceValues[currencyId]!= 'undefined') {
this.setListPriceValue(parentRow, listPriceValues[currencyId]);
this.lineItemRowCalculations(parentRow);
}
jQuery('input.listPrice',parentRow).attr('list-info',listPriceValuesJson);
jQuery('textarea.lineItemCommentBox',parentRow).val(description);
var taxUI = this.getTaxDiv(taxes,parentRow);
jQuery('.taxDivContainer',parentRow).html(taxUI);
if(this.isIndividualTaxMode()) {
parentRow.find('.productTaxTotal').removeClass('hide')
}else{
parentRow.find('.productTaxTotal').addClass('hide')
}
}
if(referenceModule == 'Products'){
this.loadSubProducts(parentRow);
}
jQuery('.qty',parentRow).trigger('focusout');
},
showPopup : function(params) {
var aDeferred = jQuery.Deferred();
var popupInstance = Vtiger_Popup_Js.getInstance();
popupInstance.show(params, function(data){
aDeferred.resolve(data);
});
return aDeferred.promise();
},
/*
* Function which is reposible to handle the line item popups
* @params : popupImageElement - popup image element
*/
lineItemPopupEventHandler : function(popupImageElement) {
var aDeferred = jQuery.Deferred();
var thisInstance = this;
var referenceModule = popupImageElement.data('moduleName');
var moduleName = app.getModuleName();
//thisInstance.getModulePopUp(e,referenceModule);
var params = {};
params.view = popupImageElement.data('popup');
params.module = moduleName;
params.multi_select = true;
params.currency_id = jQuery('#currency_id option:selected').val();
this.showPopup(params).then(function(data){
var responseData = JSON.parse(data);
var len = Object.keys(responseData).length;
if(len >1 ){
for(var i=0;i= 1 && (referenceModule == 'Products' || referenceModule == 'Services')){
if(referenceModule == 'Products') {
var row = jQuery('#addProduct').trigger('click');
} else if(referenceModule == 'Services') {
var row1 = jQuery('#addService').trigger('click');
}
//TODO : CLEAN : we might synchronus invocation since following elements needs to executed once new row is created
var newRow = jQuery('#lineItemTab > tbody > tr:last');
var targetElem = jQuery('.lineItemPopup',newRow);
thisInstance.mapResultsToFields(referenceModule,targetElem,responseData[i]);
aDeferred.resolve();
}
}
}else{
thisInstance.mapResultsToFields(referenceModule,popupImageElement,responseData);
aDeferred.resolve();
}
})
return aDeferred.promise();
},
/**
* Function which will be used to handle price book popup
* @params : popupImageElement - popup image element
*/
pricebooksPopupHandler : function(popupImageElement){
var thisInstance = this;
var lineItemRow = popupImageElement.closest('tr.'+ this.rowClass);
var lineItemProductOrServiceElement = lineItemRow.find('input.productName').closest('td');
var params = {};
params.module = 'PriceBooks';
params.src_module = jQuery('img.lineItemPopup',lineItemProductOrServiceElement).data('moduleName');
params.src_field = jQuery('img.lineItemPopup',lineItemProductOrServiceElement).data('fieldName');
params.src_record = jQuery('input.selectedModuleId',lineItemProductOrServiceElement).val();
params.get_url = 'getProductListPriceURL';
params.currency_id = jQuery('#currency_id option:selected').val();
this.showPopup(params).then(function(data){
var responseData = JSON.parse(data);
for(var id in responseData){
thisInstance.setListPriceValue(lineItemRow,responseData[id]);
}
thisInstance.quantityChangeActions(lineItemRow);
});
},
/**
* 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);
},
/**
* 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;
}
if(discountType == Inventory_Edit_Js.percentageDiscountType){
rowPercentageField.removeClass('hide').focus();
//since it is percentage
var productTotal = this.getLineItemTotal(lineItemRow);
discountValue = (productTotal * discountValue)/100;
}else if(discountType == Inventory_Edit_Js.directAmountDiscountType){
rowAmountField.removeClass('hide').focus();
}
this.setDiscountTotal(lineItemRow,discountValue)
.calculateTotalAfterDiscount(lineItemRow);
},
/**
* Function which will calculate line item total after discount
* @params : lineItemRow - element which will represent lineItemRow
*/
calculateTotalAfterDiscount: function(lineItemRow) {
var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val());
var productTotal = this.getLineItemTotal(lineItemRow);
var discountTotal = this.getDiscountTotal(lineItemRow);
var totalAfterDiscount = productTotal - discountTotal;
totalAfterDiscount = totalAfterDiscount.toFixed(numberOfDecimal);
this.setTotalAfterDiscount(lineItemRow,totalAfterDiscount);
},
/**
* Function which will calculate tax for the line item total after discount
*/
calculateTaxForLineItem : function(lineItemRow) {
var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val());
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.00";
}
if(isNaN(individualTaxPercentage)){
var individualTaxTotal = "0.00";
} else {
var individualTaxPercentage = parseFloat(individualTaxPercentage);
var individualTaxTotal = Math.abs(individualTaxPercentage * totalAfterDiscount)/100;
individualTaxTotal = individualTaxTotal.toFixed(numberOfDecimal);
}
jQuery('.taxTotal',individualTaxRow).val(individualTaxTotal);
taxTotal += parseFloat(individualTaxTotal);
});
taxTotal = parseFloat(taxTotal.toFixed(numberOfDecimal));
this.setLineItemTaxTotal(lineItemRow, taxTotal);
},
/**
* Function which will calculate net price for the line item
*/
calculateLineItemNetPrice : function(lineItemRow) {
var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val());
var totalAfterDiscount = this.getTotalAfterDiscount(lineItemRow);
var netPrice = parseFloat(totalAfterDiscount);
if(this.isIndividualTaxMode()) {
var productTaxTotal = this.getLineItemTaxTotal(lineItemRow);
netPrice += parseFloat(productTaxTotal)
}
netPrice = netPrice.toFixed(numberOfDecimal);
this.setLineItemNetPrice(lineItemRow,netPrice);
},
/**
* Function which will caliculate the total net price for all the line items
*/
calculateNetTotal : function() {
var thisInstance = this
var lineItemTable = this.getLineItemContentsContainer();
var netTotalValue = 0;
lineItemTable.find('tr.'+this.rowClass).each(function(index,domElement){
var lineItemRow = jQuery(domElement);
netTotalValue += thisInstance.getLineItemNetPrice(lineItemRow);
});
this.setNetTotal(netTotalValue);
},
calculateFinalDiscount : function() {
var thisInstance = this;
var discountContainer = jQuery('#finalDiscountUI');
var element = discountContainer.find('input.finalDiscounts').filter(':checked');
var discountType = element.data('discountType');
var discountRow = element.closest('tr');
var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val());
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;
}
if(discountType == Inventory_Edit_Js.percentageDiscountType){
rowPercentageField.removeClass('hide').focus();
//since it is percentage
var productTotal = this.getNetTotal();
discountValue = (productTotal * discountValue)/100;
}else if(discountType == Inventory_Edit_Js.directAmountDiscountType){
if(thisInstance.prevSelectedCurrencyConversionRate){
var conversionRate = jQuery('#conversion_rate').val();
conversionRate = conversionRate / thisInstance.prevSelectedCurrencyConversionRate;
discountValue = discountValue * conversionRate;
discountRow.find('.discountVal').val(discountValue);
}
rowAmountField.removeClass('hide').focus();
}
discountValue = parseFloat(discountValue).toFixed(numberOfDecimal);
this.setFinalDiscountTotal(discountValue);
this.calculatePreTaxTotal();
},
calculateGroupTax : function() {
var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val());
var netTotal = this.getNetTotal();
var finalDiscountValue = this.getFinalDiscountTotal();
var amount = netTotal - finalDiscountValue;
amount = parseFloat(amount).toFixed(numberOfDecimal);
var groupTaxContainer = jQuery('#group_tax_div');
var groupTaxTotal = 0;
groupTaxContainer.find('.groupTaxPercentage').each(function(index,domElement){
var groupTaxPercentageElement = jQuery(domElement);
var groupTaxRow = groupTaxPercentageElement.closest('tr');
if(isNaN(groupTaxPercentageElement.val())){
var groupTaxValue = "0.00";
} else {
var groupTaxValue = Math.abs(amount * groupTaxPercentageElement.val())/100;
}
groupTaxValue = parseFloat(groupTaxValue).toFixed(numberOfDecimal);
groupTaxRow.find('.groupTaxTotal').val(groupTaxValue);
groupTaxTotal += parseFloat(groupTaxValue);
});
this.setGroupTaxTotal(groupTaxTotal);
},
calculateShippingAndHandlingTaxCharges : function() {
var shippingHandlingCharge = this.getShippingAndHandling();
var shippingTaxDiv = jQuery('#shipping_handling_div');
var shippingTaxPercentage = shippingTaxDiv.find('.shippingTaxPercentage');
jQuery.each(shippingTaxPercentage,function(index,domElement){
var currentTaxPer = jQuery(domElement);
var currentParentRow = currentTaxPer.closest('tr');
var currentTaxPerValue = currentTaxPer.val();
var currentTaxTotal = "0.00";
if(currentTaxPerValue == ""){
currentTaxPerValue = "0.00";
}
if(isNaN(currentTaxPerValue)){
var currentTaxTotal = "0.00";
} else {
currentTaxPerValue = parseFloat(currentTaxPerValue);
var currentTaxTotal = Math.abs(currentTaxPerValue * shippingHandlingCharge)/100;
}
jQuery('.shippingTaxTotal',currentParentRow).val(currentTaxTotal);
});
},
calculateGrandTotal : function(){
var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val());
var netTotal = this.getNetTotal();
var discountTotal = this.getFinalDiscountTotal();
var shippingHandlingCharge = this.getShippingAndHandling();
var shippingHandlingTax = this.getShippingAndHandlingTaxTotal();
var adjustment = this.getAdjustmentValue();
var grandTotal = parseFloat(netTotal) - parseFloat(discountTotal) + parseFloat(shippingHandlingCharge) + parseFloat(shippingHandlingTax);
if(this.isGroupTaxMode()){
grandTotal += this.getGroupTaxTotal();
}
if(this.isAdjustMentAddType()) {
grandTotal += parseFloat(adjustment);
}else if(this.isAdjustMentDeductType()) {
grandTotal -= parseFloat(adjustment);
}
grandTotal = grandTotal.toFixed(numberOfDecimal);
this.setGrandTotal(grandTotal);
},
registerFinalDiscountShowEvent : function(){
var thisInstance = this;
jQuery('#finalDiscount').on('click',function(e){
var finalDiscountUI = jQuery('#finalDiscountUI');
thisInstance.hideLineItemPopup();
finalDiscountUI.removeClass('hide');
});
},
registerFinalDiscountChangeEvent : function() {
var lineItemResultTab = this.getLineItemResultContainer();
var thisInstance = this;
lineItemResultTab.on('change','.finalDiscounts',function(e){
thisInstance.finalDiscountChangeActions();
});
},
registerFinalDiscountValueChangeEvent : function(){
var thisInstance = this;
jQuery('.finalDiscountSave').on('click',function(e){
thisInstance.finalDiscountChangeActions();
});
},
registerLineItemActionSaveEvent : function(){
var editForm = this.getForm();
editForm.on('click','button[name="lineItemActionSave"]',function(){
var match = true;
var formError = jQuery('#EditView').data('jqv').InvalidFields;
var closestDiv = jQuery('button[name="lineItemActionSave"]').closest('.validCheck').find('input[data-validation-engine]').not('.hide');
jQuery(closestDiv).each(function(key,value){
if(jQuery.inArray(value,formError) != -1){
match = false;
}
});
if(!match){
editForm.removeData('submit');
return false;
} else {
jQuery('.closeDiv').trigger('click');
}
});
},
registerGroupTaxShowEvent : function() {
var thisInstance = this;
jQuery('#finalTax').on('click',function(e){
var groupTaxContainer = jQuery('#group_tax_row');
thisInstance.hideLineItemPopup();
groupTaxContainer.find('.finalTaxUI').removeClass('hide');
});
},
registerGroupTaxChangeEvent : function() {
var thisInstance = this;
var groupTaxContainer = jQuery('#group_tax_row');
groupTaxContainer.on('focusout','.groupTaxPercentage',function(e){
thisInstance.calculateGroupTax();
thisInstance.calculateGrandTotal();
});
},
registerShippingAndHandlingChargesChange : function(){
var thisInstance = this;
this.getShippingAndHandlingControlElement().on('focusout', function(e){
var value = jQuery(e.currentTarget).val();
if(value == ""){
jQuery(e.currentTarget).val("0.00");
}
thisInstance.shippingAndHandlingChargesChangeActions();
});
jQuery('.shippingTaxPercentage').on('change',function(){
thisInstance.shippingAndHandlingChargesChangeActions();
})
jQuery('.finalTaxSave').on('click',function(){
thisInstance.setShippingAndHandlingTaxTotal();
})
},
registerShippingAndHandlingTaxShowEvent : function(){
var thisInstance = this;
jQuery('#shippingHandlingTax').on('click',function(e){
var finalShippingHandlingDiv = jQuery('#shipping_handling_div');
thisInstance.hideLineItemPopup();
finalShippingHandlingDiv.removeClass('hide');
});
},
registerAdjustmentTypeChange : function() {
var thisInstance = this;
this.getAdjustmentTypeElement().on('change', function(e){
thisInstance.calculateGrandTotal();
});
},
registerAdjustmentValueChange : function() {
var thisInstance = this;
this.getAdjustmentTextElement().on('focusout',function(e){
var value = jQuery(e.currentTarget).val();
if(value == ""){
jQuery(e.currentTarget).val("0.00");
}
thisInstance.calculateGrandTotal();
});
},
registerLineItemsPopUpCancelClickEvent : function(){
var editForm = this.getForm();
editForm.on('click','.cancelLink',function(){
jQuery('.closeDiv').trigger('click')
})
},
lineItemResultActions: function(){
var thisInstance = this;
var lineItemResultTab = this.getLineItemResultContainer();
this.registerFinalDiscountShowEvent();
this.registerFinalDiscountValueChangeEvent();
this.registerFinalDiscountChangeEvent();
this.registerLineItemActionSaveEvent();
this.registerLineItemsPopUpCancelClickEvent();
this.registerGroupTaxShowEvent();
this.registerGroupTaxChangeEvent();
this.registerShippingAndHandlingChargesChange();
this.registerShippingAndHandlingTaxShowEvent();
this.registerAdjustmentTypeChange();
this.registerAdjustmentValueChange();
lineItemResultTab.on('click','.closeDiv',function(e){
jQuery(e.target).closest('div').addClass('hide');
});
},
lineItemRowCalculations : function(lineItemRow) {
this.calculateLineItemTotal(lineItemRow);
this.calculateDiscountForLineItem(lineItemRow);
this.calculateTaxForLineItem(lineItemRow);
this.calculateLineItemNetPrice(lineItemRow);
},
lineItemToTalResultCalculations : function(){
this.calculateNetTotal();
this.calculateFinalDiscount();
if(this.isGroupTaxMode()){
this.calculateGroupTax();
}
//this.calculateShippingAndHandlingTaxCharges();
this.calculateGrandTotal();
},
/**
* 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) {
this.lineItemRowCalculations(lineItemRow);
this.lineItemToTalResultCalculations();
},
lineItemDiscountChangeActions : function(lineItemRow){
this.calculateDiscountForLineItem(lineItemRow);
this.calculateTaxForLineItem(lineItemRow);
this.calculateLineItemNetPrice(lineItemRow);
this.lineItemToTalResultCalculations();
},
/**
* 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.calculateShippingAndHandlingTaxCharges();
this.calculateGrandTotal();
},
lineItemDeleteActions : function() {
this.lineItemToTalResultCalculations();
},
shippingAndHandlingChargesChangeActions : function(){
this.calculateShippingAndHandlingTaxCharges();
this.setShippingAndHandlingTaxTotal();
this.calculatePreTaxTotal();
this.calculateGrandTotal();
},
finalDiscountChangeActions : function() {
this.calculateFinalDiscount();
if(this.isGroupTaxMode()){
this.calculateGroupTax();
}
this.calculateGrandTotal();
},
/**
* Function which will register change event for discounts radio buttons
*/
registerDisountChangeEvent : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('change','.discounts',function(e){
var lineItemRow = jQuery(e.currentTarget).closest('tr.'+thisInstance.rowClass);
thisInstance.lineItemDiscountChangeActions(lineItemRow);
});
},
/**
* Function which will register event for focusout of discount input fields like percentage and amount
*/
registerDisountValueChange : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('click','.discountSave', function(e){
var element = jQuery(e.currentTarget);
//if the element is not hidden then we need to handle the focus out
if(!app.isHidden(element)){
var lineItemRow = jQuery(e.currentTarget).closest('tr.'+thisInstance.rowClass);
thisInstance.lineItemDiscountChangeActions(lineItemRow);
}
});
},
hideLineItemPopup : function(){
var editForm = this.getForm();
var popUpElementContainer = jQuery('.popupTable',editForm).closest('div');
if(popUpElementContainer.length > 0){
popUpElementContainer.addClass('hide');
}
},
registerLineItemDiscountShowEvent : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('click','.individualDiscount',function(e){
var element = jQuery(e.currentTarget);
var response = thisInstance.isProductSelected(element);
if(response == true){
return;
}
var parentElem = jQuery(e.currentTarget).closest('td');
thisInstance.hideLineItemPopup();
parentElem.find('div.discountUI').removeClass('hide');
});
},
/**
* Function which will regiser events for product and service popup
*/
registerProductAndServicePopup : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('click','img.lineItemPopup', function(e){
var element = jQuery(e.currentTarget);
thisInstance.lineItemPopupEventHandler(element).then(function(data){
var parent = element.closest('tr');
var deletedItemInfo = parent.find('.deletedItem');
if(deletedItemInfo.length > 0){
deletedItemInfo.remove();
}
})
});
},
/**
* Function which will regisrer price book popup
*/
registerPriceBookPopUp : function () {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('click','.priceBookPopup',function(e){
var element = jQuery(e.currentTarget);
var response = thisInstance.isProductSelected(element);
if(response == true){
return;
}
thisInstance.pricebooksPopupHandler(element);
});
},
/*
* Function which will register event for quantity change (focusout event)
*/
registerQuantityChangeEventHandler : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('focusout','.qty',function(e){
var element = jQuery(e.currentTarget);
var lineItemRow = element.closest('tr.'+thisInstance.rowClass);
var quantityInStock = lineItemRow.data('quantityInStock');
if(typeof quantityInStock != 'undefined') {
if(parseFloat(element.val()) > parseFloat(quantityInStock)) {
lineItemRow.find('.stockAlert').removeClass('hide').find('.maxQuantity').text(quantityInStock);
}else{
lineItemRow.find('.stockAlert').addClass('hide');
}
}
thisInstance.quantityChangeActions(lineItemRow);
});
},
/**
* Function which will register event for list price event change
*/
registerListPriceChangeEvent : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('focusout', 'input.listPrice',function(e){
var element = jQuery(e.currentTarget);
var lineItemRow = thisInstance.getClosestLineItemRow(element);
thisInstance.quantityChangeActions(lineItemRow);
});
},
registerTaxPercentageChange : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('focusout','.taxPercentage',function(e){
var element = jQuery(e.currentTarget);
var lineItemRow = thisInstance.getClosestLineItemRow(element);
thisInstance.calculateTaxForLineItem(lineItemRow);
});
lineItemTable.on('click','.taxSave',function(e){
var element = jQuery(e.currentTarget);
var lineItemRow = thisInstance.getClosestLineItemRow(element);
thisInstance.taxPercentageChangeActions(lineItemRow);
});
},
isProductSelected : function(element){
var parentRow = element.closest('tr');
var productField = parentRow.find('.productName');
var response = productField.validationEngine('validate');
return response;
},
registerLineItemTaxShowEvent : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('click','.individualTax',function(e){
var element = jQuery(e.currentTarget);
var response = thisInstance.isProductSelected(element);
if(response == true){
return;
}
var parentElem = jQuery(e.currentTarget).closest('td');
thisInstance.hideLineItemPopup()
parentElem.find('.taxUI').removeClass('hide');
});
},
registerDeleteLineItemEvent : function(){
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('click','.deleteRow',function(e){
var element = jQuery(e.currentTarget);
//removing the row
element.closest('tr.'+ thisInstance.rowClass).remove();
thisInstance.checkLineItemRow();
thisInstance.lineItemDeleteActions();
});
},
registerTaxTypeChange : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
this.getTaxTypeSelectElement().on('change', function(e){
if(thisInstance.isIndividualTaxMode()) {
jQuery('#group_tax_row').addClass('hide');
lineItemTable.find('tr.'+thisInstance.rowClass).each(function(index,domElement){
var lineItemRow = jQuery(domElement);
lineItemRow.find('.individualTaxContainer,.productTaxTotal').removeClass('hide');
thisInstance.lineItemRowCalculations(lineItemRow);
});
}else{
jQuery('#group_tax_row').removeClass('hide');
lineItemTable.find('tr.'+thisInstance.rowClass).each(function(index,domElement){
var lineItemRow = jQuery(domElement);
lineItemRow.find('.individualTaxContainer,.productTaxTotal').addClass('hide');
thisInstance.calculateLineItemNetPrice(lineItemRow);
});
}
thisInstance.lineItemToTalResultCalculations();
});
},
registerCurrencyChangeEvent : function() {
var thisInstance = this;
jQuery('#currency_id').change(function(e){
var element = jQuery(e.currentTarget);
var currencyId = element.val();
var conversionRateElem = jQuery('#conversion_rate');
var prevSelectedCurrencyConversionRate = conversionRateElem.val();
thisInstance.prevSelectedCurrencyConversionRate = prevSelectedCurrencyConversionRate;
var optionsSelected = element.find('option:selected');
var conversionRate = optionsSelected.data('conversionRate');
conversionRateElem.val(conversionRate);
conversionRate = parseFloat(conversionRate)/ parseFloat(prevSelectedCurrencyConversionRate);
thisInstance.LineItemDirectDiscountCal(conversionRate);
var lineItemTable = thisInstance.getLineItemContentsContainer();
lineItemTable.find('tr.'+thisInstance.rowClass).each(function(index,domElement){
var lineItemRow = jQuery(domElement);
var listPriceElement = jQuery(lineItemRow).find('[name^=listPrice]');
var listPriceValues = JSON.parse(listPriceElement.attr('list-info'));
if(typeof listPriceValues[currencyId]!= 'undefined') {
thisInstance.setListPriceValue(lineItemRow, listPriceValues[currencyId]);
thisInstance.lineItemRowCalculations(lineItemRow);
} else {
var listPriceVal = thisInstance.getListPriceValue(lineItemRow);
var convertedListPrice = listPriceVal * conversionRate;
thisInstance.setListPriceValue(lineItemRow, convertedListPrice);
thisInstance.lineItemRowCalculations(lineItemRow);
}
});
thisInstance.AdjustmentShippingResultCalculation(conversionRate);
thisInstance.lineItemToTalResultCalculations();
jQuery('#prev_selected_currency_id').val(optionsSelected.val())
});
},
AdjustmentShippingResultCalculation: function(conversionRate){
//Adjustment
var thisInstance = this;
var adjustmentElement = thisInstance.getAdjustmentTextElement();
var newAdjustment = jQuery(adjustmentElement).val() * conversionRate;
jQuery(adjustmentElement).val(newAdjustment);
//Shipping & handling
var shippingHandlingElement = thisInstance.getShippingAndHandlingControlElement();
var resultVal = jQuery(shippingHandlingElement).val() * conversionRate;
jQuery(shippingHandlingElement).val(resultVal);
jQuery(shippingHandlingElement).trigger('focusout');
},
LineItemDirectDiscountCal: function(conversionRate){
//LineItems Discount Calculations for direct Price reduction
var thisInstance = this;
var lineItemRows = jQuery('.lineItemRow');
jQuery(lineItemRows).each(function(index) {
var lineItemRow = jQuery(lineItemRows[index]);
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);
thisInstance.setDiscountTotal(lineItemRow,newdiscountValue);
}
});
},
lineItemActions: function() {
var lineItemTable = this.getLineItemContentsContainer();
this.registerDisountChangeEvent();
this.registerDisountValueChange();
this.registerLineItemDiscountShowEvent();
this.registerLineItemAutoComplete();
this.registerClearLineItemSelection();
this.registerProductAndServicePopup();
this.registerPriceBookPopUp();
this.registerQuantityChangeEventHandler();
this.registerListPriceChangeEvent();
this.registerTaxPercentageChange();
this.registerLineItemTaxShowEvent();
this.registerDeleteLineItemEvent();
this.registerTaxTypeChange();
this.registerCurrencyChangeEvent();
lineItemTable.on('click','.closeDiv',function(e){
jQuery(e.currentTarget).closest('div').addClass('hide');
});
lineItemTable.on('click','.clearComment',function(e){
var elem = jQuery(e.currentTarget);
var parentElem = elem.closest('div');
var comment = jQuery('.lineItemCommentBox',parentElem).val('');
});
},
/***
* Function which will update the line item row elements with the sequence number
* @params : lineItemRow - tr line item row for which the sequence need to be updated
* currentSequenceNUmber - existing sequence number that the elments is having
* expectedSequenceNumber - sequence number to which it has to update
*
* @return : row element after changes
*/
updateLineItemsElementWithSequenceNumber : 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',
'comment','qty','listPrice','discount_type','discount_percentage',
'discount_amount','lineItemType','searchIcon','netPrice','subprod_names',
'productTotal','discountTotal','totalAfterDiscount','taxTotal');
var nameFields = new Array('discount');
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);
}
for(var nameIndex in nameFields) {
var elementName = nameFields[nameIndex];
var actualElementName = elementName + currentSequenceNumber;
var expectedElementName = elementName + expectedSequenceNumber;
lineItemRow.find('[name="'+actualElementName+'"]').attr('name',expectedElementName);
}
return lineItemRow.attr('id',expectedRowId);
},
updateLineItemElementByOrder : function () {
var lineItemContentsContainer = this.getLineItemContentsContainer();
var thisInstance = this;
jQuery('tr.'+this.rowClass ,lineItemContentsContainer).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');
thisInstance.updateLineItemsElementWithSequenceNumber(lineItemRow, expectedRowIndex, actualIdComponents[1]);
}
});
},
saveProductCount : function () {
jQuery('#totalProductCount').val(jQuery('tr.'+this.rowClass, this.getLineItemContentsContainer()).length);
},
saveSubTotalValue : function() {
jQuery('#subtotal').val(this.getNetTotal());
},
saveTotalValue : function() {
jQuery('#total').val(this.getGrandTotal());
},
makeLineItemsSortable : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.sortable({
'containment' : lineItemTable,
'items' : 'tr.'+this.rowClass,
'revert' : true,
'tolerance':'pointer',
'helper' : function(e,ui){
//while dragging helper elements td element will take width as contents width
//so we are explicity saying that it has to be same width so that element will not
//look like distrubed
ui.children().each(function(index,element){
element = jQuery(element);
element.width(element.width());
})
return ui;
}
}).mousedown(function(event){
//TODO : work around for issue of mouse down even hijack in sortable plugin
thisInstance.getClosestLineItemRow(jQuery(event.target)).find('input:focus').trigger('focusout');
});
},
registerSubmitEvent : function () {
var thisInstance = this;
var editViewForm = this.getForm();
this._super();
editViewForm.submit(function(e){
var deletedItemInfo = jQuery('.deletedItem',editViewForm);
if(deletedItemInfo.length > 0){
e.preventDefault();
var msg = app.vtranslate('JS_PLEASE_REMOVE_LINE_ITEM_THAT_IS_DELETED');
var params = {
text : msg,
type: 'error'
}
Vtiger_Helper_Js.showPnotify(params);
editViewForm.removeData('submit');
return false;
}
thisInstance.updateLineItemElementByOrder();
var lineItemTable = thisInstance.getLineItemContentsContainer();
jQuery('.discountSave',lineItemTable).trigger('click');
thisInstance.lineItemToTalResultCalculations();
thisInstance.saveProductCount();
thisInstance.saveSubTotalValue();
thisInstance.saveTotalValue();
thisInstance.savePreTaxTotalValue();
})
},
/**
* Function which will register event for Reference Fields Selection
*/
registerReferenceSelectionEvent : function(container) {
var thisInstance = this;
jQuery('input[name="contact_id"]', container).on(Vtiger_Edit_Js.referenceSelectionEvent, function(e, data){
thisInstance.referenceSelectionEventHandler(data, container);
});
},
/**
* Reference Fields Selection Event Handler
*/
referenceSelectionEventHandler : function(data,container){
var thisInstance = this;
var message = app.vtranslate('OVERWRITE_EXISTING_MSG1')+app.vtranslate('SINGLE_'+data['source_module'])+' ('+data['selectedName']+') '+app.vtranslate('OVERWRITE_EXISTING_MSG2');
Vtiger_Helper_Js.showConfirmationBox({'message' : message}).then(
function(e) {
thisInstance.copyAddressDetails(data, container);
},
function(error, err){
});
},
/**
* Function which will copy the address details
*/
copyAddressDetails : function(data,container,addressMap) {
var thisInstance = this;
var sourceModule = data['source_module'];
var noAddress = true;
var errorMsg;
thisInstance.getRecordDetails(data).then(
function(data){
var response = data['result'];
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';
}
Vtiger_Helper_Js.showPnotify(app.vtranslate(errorMsg));
} else{
thisInstance.mapAddressDetails(addressMap, result, container);
}
} else{
thisInstance.mapAddressDetails(thisInstance.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) {
container.find('[name="'+key+'"]').val(result[addressDetails[key]]);
container.find('[name="'+key+'"]').trigger('change');
}
},
registerLineItemAutoComplete : function(container) {
var thisInstance = this;
if(typeof container == 'undefined') {
container = thisInstance.getLineItemContentsContainer();
}
container.find('input.autoComplete').autocomplete({
'minLength' : '3',
'source' : function(request, response){
//element will be array of dom elements
//here this refers to auto complete instance
var inputElement = jQuery(this.element[0]);
var tdElement = inputElement.closest('td');
var searchValue = request.term;
var params = {};
var searchModule = tdElement.find('.lineItemPopup').data('moduleName');
params.search_module = searchModule
params.search_value = searchValue;
thisInstance.searchModuleNames(params).then(function(data){
var reponseDataList = new Array();
var serverDataFormat = data.result
if(serverDataFormat.length <= 0) {
serverDataFormat = new Array({
'label' : app.vtranslate('JS_NO_RESULTS_FOUND'),
'type' : 'no results'
});
}
for(var id in serverDataFormat){
var responseData = serverDataFormat[id];
reponseDataList.push(responseData);
}
response(reponseDataList);
});
},
'select' : function(event, ui ){
var selectedItemData = ui.item;
//To stop selection if no results is selected
if(typeof selectedItemData.type != 'undefined' && selectedItemData.type=="no results"){
return false;
}
var element = jQuery(this);
element.attr('disabled','disabled');
var tdElement = element.closest('td');
var selectedModule = tdElement.find('.lineItemPopup').data('moduleName');
var popupElement = tdElement.find('.lineItemPopup');
var dataUrl = "index.php?module=Inventory&action=GetTaxes&record="+selectedItemData.id+"¤cy_id="+jQuery('#currency_id option:selected').val();
AppConnector.request(dataUrl).then(
function(data){
for(var id in data){
if(typeof data[id] == "object"){
var recordData = data[id];
thisInstance.mapResultsToFields(selectedModule, popupElement, recordData);
}
}
},
function(error,err){
}
);
},
'change' : function(event, ui) {
var element = jQuery(this);
//if you dont have disabled attribute means the user didnt select the item
if(element.attr('disabled')== undefined) {
element.closest('td').find('.clearLineItem').trigger('click');
}
}
});
},
registerClearLineItemSelection : function() {
var thisInstance = this;
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.on('click','.clearLineItem',function(e){
var elem = jQuery(e.currentTarget);
var parentElem = elem.closest('td');
thisInstance.clearLineItemDetails(parentElem);
parentElem.find('input.productName').removeAttr('disabled').val('');
e.preventDefault();
});
},
clearLineItemDetails : function(parentElem) {
var thisInstance = this;
var lineItemRow = parentElem.closest('tr.'+thisInstance.rowClass);
jQuery('input.selectedModuleId',lineItemRow).val('');
jQuery('input.listPrice',lineItemRow).val('0');
jQuery('.lineItemCommentBox', lineItemRow).val('');
thisInstance.quantityChangeActions(lineItemRow);
},
checkLineItemRow : function(){
var lineItemTable = this.getLineItemContentsContainer();
var noRow = lineItemTable.find('.lineItemRow').length;
if(noRow >1){
this.showLineItemsDeleteIcon();
}else{
this.hideLineItemsDeleteIcon();
}
},
showLineItemsDeleteIcon : function(){
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.find('.deleteRow').show();
},
hideLineItemsDeleteIcon : function(){
var lineItemTable = this.getLineItemContentsContainer();
lineItemTable.find('.deleteRow').hide();
},
/**
* 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;
},
/**
* Function to copy address between fields
* @param strings which accepts value as either odd or even
*/
copyAddress : function(swapMode){
var thisInstance = 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 = thisInstance.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 register event for copying addresses
*/
registerEventForCopyAddress : function(){
var thisInstance = this;
var formElement = this.getForm();
jQuery('[name="copyAddressFromRight"],[name="copyAddressFromLeft"]').change(function(){
var element = jQuery(this);
var elementClass = element.attr('class');
var targetCopyAddress = element.data('copyAddress');
var objectToMapAddress;
if(elementClass == "accountAddress"){
var recordRelativeAccountId = jQuery('[name="account_id"]').val();
if(recordRelativeAccountId == "" || recordRelativeAccountId == "0"){
Vtiger_Helper_Js.showPnotify(app.vtranslate('JS_PLEASE_SELECT_AN_ACCOUNT_TO_COPY_ADDRESS'));
} else {
var recordRelativeAccountName = jQuery('#account_id_display').val();
var data = {
'record' : recordRelativeAccountId,
'selectedName' : recordRelativeAccountName,
'source_module': "Accounts"
}
if(targetCopyAddress == "billing"){
objectToMapAddress = thisInstance.addressFieldsMappingBetweenModules['AccountsBillMap'];
} else if(targetCopyAddress == "shipping"){
objectToMapAddress = thisInstance.addressFieldsMappingBetweenModules['AccountsShipMap'];
}
thisInstance.copyAddressDetails(data,element.closest('table'),objectToMapAddress);
element.attr('checked','checked');
}
}else if(elementClass == "contactAddress"){
var recordRelativeContactId = jQuery('[name="contact_id"]').val();
if(recordRelativeContactId == "" || recordRelativeContactId == "0"){
Vtiger_Helper_Js.showPnotify(app.vtranslate('JS_PLEASE_SELECT_AN_CONTACT_TO_COPY_ADDRESS'));
} else {
var recordRelativeContactName = jQuery('#contact_id_display').val();
var data = {
'record' : recordRelativeContactId,
'selectedName' : recordRelativeContactName,
source_module: "Contacts"
}
if(targetCopyAddress == "billing"){
objectToMapAddress = thisInstance.addressFieldsMappingBetweenModules['ContactsBillMap'];
} else if(targetCopyAddress == "shipping"){
objectToMapAddress = thisInstance.addressFieldsMappingBetweenModules['ContactsShipMap'];
}
thisInstance.copyAddressDetails(data,element.closest('table'),objectToMapAddress);
element.attr('checked','checked');
}
} else if(elementClass == "shippingAddress"){
var target = element.data('target');
if(target == "shipping"){
var swapMode = "true";
}
thisInstance.copyAddress(swapMode);
} else if(elementClass == "billingAddress"){
var target = element.data('target');
if(target == "billing"){
var swapMode = "false";
}
thisInstance.copyAddress(swapMode);
}
})
jQuery('[name="copyAddress"]').on('click',function(e){
var element = jQuery(e.currentTarget);
var swapMode;
var target = element.data('target');
if(target == "billing"){
swapMode = "false";
}else if(target == "shipping"){
swapMode = "true";
}
thisInstance.copyAddress(swapMode);
})
},
/**
* Function to toggle shipping and billing address according to layout
*/
registerForTogglingBillingandShippingAddress : function(){
var billingAddressPosition = jQuery('[name="bill_street"]').closest('td').index();
var copyAddress1Block = jQuery('[name="copyAddress1"]');
var copyAddress2Block = jQuery('[name="copyAddress2"]');
var copyHeader1 = jQuery('[name="copyHeader1"]');
var copyHeader2 = jQuery('[name="copyHeader2"]');
var copyAddress1toggleAddressLeftContainer = copyAddress1Block.find('[name="togglingAddressContainerLeft"]');
var copyAddress1toggleAddressRightContainer = copyAddress1Block.find('[name="togglingAddressContainerRight"]');
var copyAddress2toggleAddressLeftContainer = copyAddress2Block.find('[name="togglingAddressContainerLeft"]')
var copyAddress2toggleAddressRightContainer = copyAddress2Block.find('[name="togglingAddressContainerRight"]');
var headerText1 = copyHeader1.html();
var headerText2 = copyHeader2.html();
if(billingAddressPosition == 3){
if(copyAddress1toggleAddressLeftContainer.hasClass('hide')){
copyAddress1toggleAddressLeftContainer.removeClass('hide');
}
copyAddress1toggleAddressRightContainer.addClass('hide');
if(copyAddress2toggleAddressRightContainer.hasClass('hide')){
copyAddress2toggleAddressRightContainer.removeClass('hide');
}
copyAddress2toggleAddressLeftContainer.addClass('hide');
copyHeader1.html(headerText2);
copyHeader2.html(headerText1);
copyAddress1Block.find('[data-copy-address]').each(function(){
jQuery(this).data('copyAddress','shipping');
})
copyAddress2Block.find('[data-copy-address]').each(function(){
jQuery(this).data('copyAddress','billing');
})
}
},
/**
* Function to check for relation operation
* if relation exist calculation should happen by default
*/
registerForRealtionOperation : function(){
var form = this.getForm();
var relationExist = form.find('[name="relationOperation"]').val();
if(relationExist){
jQuery('.qty').trigger('focusout');
}
},
//Related to preTaxTotal Field
/**
* Function to set the pre tax total
*/
setPreTaxTotal : function(preTaxTotalValue){
jQuery('#preTaxTotal').text(preTaxTotalValue);
return this;
},
/**
* Function to get the pre tax total
*/
getPreTaxTotal : function() {
return parseFloat(jQuery('#preTaxTotal').text());
},
/**
* Function to calculate the preTaxTotal value
*/
calculatePreTaxTotal : function() {
var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val());
var netTotal = this.getNetTotal();
var shippingHandlingCharge = this.getShippingAndHandling();
var finalDiscountValue = this.getFinalDiscountTotal();
var preTaxTotal = netTotal+shippingHandlingCharge-finalDiscountValue;
var preTaxTotalValue = parseFloat(preTaxTotal).toFixed(numberOfDecimal);
this.setPreTaxTotal(preTaxTotalValue);
},
/**
* Function to save the pre tax total value
*/
savePreTaxTotalValue : function() {
jQuery('#pre_tax_total').val(this.getPreTaxTotal());
},
/**
* Function which will register all the events
*/
registerBasicEvents : function(container) {
this._super(container);
this.registerReferenceSelectionEvent(container);
},
registerEvents: function(){
this._super();
this.registerAddingNewProductsAndServices();
this.lineItemActions();
this.lineItemResultActions();
//TODO : this might be costier operation. This we added to calculate tax for each line item
this.makeLineItemsSortable();
this.checkLineItemRow();
this.registerForRealtionOperation();
}
});