/*+*********************************************************************************** * 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 = '
'+ ''+ ''+ ''+ ''+ ''; if(!jQuery.isEmptyObject(taxObj)){ for(var taxName in taxObj){ var taxInfo = taxObj[taxName] taxDiv += ''+ ''+ ' '+ ''+ ''; loopIterator++; } }else{ taxDiv += ''+ ''+ ''; } taxDiv += '
Set Tax for :'+ '
'+ ' %'+ '
'+taxInfo.label+'
'+ ''+ '
'+app.vtranslate("JS_LBL_NO_TAXES")+'
'; 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(); } });