[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 /*+*********************************************************************************** 2 * The contents of this file are subject to the vtiger CRM Public License Version 1.0 3 * ("License"); You may not use this file except in compliance with the License 4 * The Original Code is: vtiger CRM Open Source 5 * The Initial Developer of the Original Code is vtiger. 6 * Portions created by vtiger are Copyright (C) vtiger. 7 * All Rights Reserved. 8 *************************************************************************************/ 9 10 Vtiger_Edit_Js("Inventory_Edit_Js",{ 11 12 zeroDiscountType : 'zero' , 13 percentageDiscountType : 'percentage', 14 directAmountDiscountType : 'amount', 15 16 individualTaxType : 'individual', 17 groupTaxType : 'group' 18 },{ 19 20 //Container which stores the line item elements 21 lineItemContentsContainer : false, 22 //Container which stores line item result details 23 lineItemResultContainer : false, 24 //contains edit view form element 25 editViewForm : false, 26 27 //a variable which will be used to hold the sequence of the row 28 rowSequenceHolder : false, 29 30 //holds the element which has basic hidden row which we can clone to add rows 31 basicRow : false, 32 33 //will be having class which is used to identify the rows 34 rowClass : 'lineItemRow', 35 36 prevSelectedCurrencyConversionRate : false, 37 38 //Will have the mapping of address fields based on the modules 39 addressFieldsMapping : {'Contacts' : 40 {'bill_street' : 'mailingstreet', 41 'ship_street' : 'otherstreet', 42 'bill_pobox' : 'mailingpobox', 43 'ship_pobox' : 'otherpobox', 44 'bill_city' : 'mailingcity', 45 'ship_city' : 'othercity', 46 'bill_state' : 'mailingstate', 47 'ship_state' : 'otherstate', 48 'bill_code' : 'mailingzip', 49 'ship_code' : 'otherzip', 50 'bill_country' : 'mailingcountry', 51 'ship_country' : 'othercountry' 52 } , 53 54 'Accounts' : 55 { 56 'bill_street' : 'bill_street', 57 'ship_street' : 'ship_street', 58 'bill_pobox' : 'bill_pobox', 59 'ship_pobox' : 'ship_pobox', 60 'bill_city' : 'bill_city', 61 'ship_city' : 'ship_city', 62 'bill_state' : 'bill_state', 63 'ship_state' : 'ship_state', 64 'bill_code' : 'bill_code', 65 'ship_code' : 'ship_code', 66 'bill_country' : 'bill_country', 67 'ship_country' : 'ship_country' 68 }, 69 70 'Vendors' : 71 { 72 'bill_street' : 'street', 73 'ship_street' : 'street', 74 'bill_pobox' : 'pobox', 75 'ship_pobox' : 'pobox', 76 'bill_city' : 'city', 77 'ship_city' : 'city', 78 'bill_state' : 'state', 79 'ship_state' : 'state', 80 'bill_code' : 'postalcode', 81 'ship_code' : 'postalcode', 82 'bill_country' : 'country', 83 'ship_country' : 'country' 84 } 85 }, 86 87 //Address field mapping between modules specific for billing and shipping 88 addressFieldsMappingBetweenModules:{ 89 'AccountsBillMap' : { 90 'bill_street' : 'bill_street', 91 'bill_pobox' : 'bill_pobox', 92 'bill_city' : 'bill_city', 93 'bill_state' : 'bill_state', 94 'bill_code' : 'bill_code', 95 'bill_country' : 'bill_country' 96 }, 97 'AccountsShipMap' : { 98 'ship_street' : 'ship_street', 99 'ship_pobox' : 'ship_pobox', 100 'ship_city' : 'ship_city', 101 'ship_state' : 'ship_state', 102 'ship_code' : 'ship_code', 103 'ship_country' : 'ship_country' 104 }, 105 'ContactsBillMap' : { 106 'bill_street' : 'mailingstreet', 107 'bill_pobox' : 'mailingpobox', 108 'bill_city' : 'mailingcity', 109 'bill_state' : 'mailingstate', 110 'bill_code' : 'mailingzip', 111 'bill_country' : 'mailingcountry' 112 }, 113 'ContactsShipMap' : { 114 'ship_street' : 'otherstreet', 115 'ship_pobox' : 'otherpobox', 116 'ship_city' : 'othercity', 117 'ship_state' : 'otherstate', 118 'ship_code' : 'otherzip', 119 'ship_country' : 'othercountry' 120 } 121 122 }, 123 124 //Address field mapping within module 125 addressFieldsMappingInModule : { 126 'bill_street':'ship_street', 127 'bill_pobox':'ship_pobox', 128 'bill_city' :'ship_city', 129 'bill_state':'ship_state', 130 'bill_code' :'ship_code', 131 'bill_country':'ship_country' 132 }, 133 134 /** 135 * Function that is used to get the line item container 136 * @return : jQuery object 137 */ 138 getLineItemContentsContainer : function() { 139 if(this.lineItemContentsContainer == false) { 140 this.setLineItemContainer(jQuery('#lineItemTab')); 141 } 142 return this.lineItemContentsContainer; 143 }, 144 145 /** 146 * Function to set line item container 147 * @params : element - jQuery object which represents line item container 148 * @return : current instance ; 149 */ 150 setLineItemContainer : function(element) { 151 this.lineItemContentsContainer = element; 152 return this; 153 }, 154 155 /** 156 * Function to get the line item result container 157 * @result : jQuery object which represent line item result container 158 */ 159 getLineItemResultContainer : function(){ 160 if(this.lineItemResultContainer == false) { 161 this.setLinteItemResultContainer(jQuery('#lineItemResult')); 162 } 163 return this.lineItemResultContainer; 164 }, 165 166 /** 167 * Function to set line item result container 168 * @param : element - jQuery object which represents line item result container 169 * @result : current instance 170 */ 171 setLinteItemResultContainer : function(element) { 172 this.lineItemResultContainer = element; 173 return this; 174 }, 175 176 /** 177 * Function which will give the closest line item row element 178 * @return : jQuery object 179 */ 180 getClosestLineItemRow : function(element){ 181 return element.closest('tr.'+this.rowClass); 182 }, 183 184 getShippingAndHandlingControlElement : function(){ 185 return jQuery('#shipping_handling_charge'); 186 }, 187 188 getAdjustmentTypeElement : function() { 189 return jQuery('input:radio[name="adjustmentType"]'); 190 }, 191 192 getAdjustmentTextElement : function(){ 193 return jQuery('#adjustment'); 194 }, 195 196 getTaxTypeSelectElement : function(){ 197 return jQuery('#taxtype'); 198 }, 199 200 isIndividualTaxMode : function() { 201 var taxTypeElement = this.getTaxTypeSelectElement(); 202 var selectedOption = taxTypeElement.find('option:selected'); 203 if(selectedOption.val() == Inventory_Edit_Js.individualTaxType){ 204 return true; 205 } 206 return false; 207 }, 208 209 isGroupTaxMode : function() { 210 var taxTypeElement = this.getTaxTypeSelectElement(); 211 var selectedOption = taxTypeElement.find('option:selected'); 212 if(selectedOption.val() == Inventory_Edit_Js.groupTaxType){ 213 return true; 214 } 215 return false; 216 }, 217 218 /** 219 * Function which gives edit view form 220 * @return : jQuery object which represents the form element 221 */ 222 getForm : function() { 223 if(this.editViewForm == false){ 224 this.editViewForm = jQuery('#EditView'); 225 } 226 return this.editViewForm; 227 }, 228 229 /** 230 * Function which gives quantity value 231 * @params : lineItemRow - row which represents the line item 232 * @return : string 233 */ 234 getQuantityValue : function(lineItemRow){ 235 return parseFloat(jQuery('.qty', lineItemRow).val()); 236 }, 237 238 /** 239 * Function which will give me list price value 240 * @params : lineItemRow - row which represents the line item 241 * @return : string 242 */ 243 getListPriceValue : function(lineItemRow) { 244 return parseFloat(jQuery('.listPrice',lineItemRow).val()); 245 }, 246 247 setListPriceValue : function(lineItemRow, listPriceValue) { 248 var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val()); 249 var listPrice = parseFloat(listPriceValue).toFixed(numberOfDecimal); 250 lineItemRow.find('.listPrice').val(listPrice); 251 return this; 252 }, 253 254 255 /** 256 * Function which will set the line item total value excluding tax and discount 257 * @params : lineItemRow - row which represents the line item 258 * lineItemTotalValue - value which has line item total (qty*listprice) 259 * @return : current instance; 260 */ 261 setLineItemTotal : function(lineItemRow, lineItemTotalValue) { 262 jQuery('.productTotal', lineItemRow).text(lineItemTotalValue); 263 return this; 264 }, 265 266 /** 267 * Function which will get the value of line item total (qty*listprice) 268 * @params : lineItemRow - row which represents the line item 269 * @return : string 270 */ 271 getLineItemTotal : function(lineItemRow) { 272 return parseFloat(this.getLineItemTotalElement(lineItemRow).text()); 273 }, 274 275 /** 276 * Function which will get the line item total element 277 * @params : lineItemRow - row which represents the line item 278 * @return : jQuery element 279 */ 280 getLineItemTotalElement : function(lineItemRow) { 281 return jQuery('.productTotal', lineItemRow); 282 }, 283 284 /** 285 * Function which will set the discount total value for line item 286 * @params : lineItemRow - row which represents the line item 287 * discountValue - discount value 288 * @return : current instance; 289 */ 290 setDiscountTotal : function(lineItemRow, discountValue) { 291 jQuery('.discountTotal',lineItemRow).text(discountValue); 292 return this; 293 }, 294 295 /** 296 * Function which will get the value of total discount 297 * @params : lineItemRow - row which represents the line item 298 * @return : string 299 */ 300 getDiscountTotal : function(lineItemRow) { 301 return parseFloat(jQuery('.discountTotal',lineItemRow).text()); 302 }, 303 304 /** 305 * Function which will set the total after discount value 306 * @params : lineItemRow - row which represents the line item 307 * totalAfterDiscountValue - total after discount value 308 * @return : current instance; 309 */ 310 setTotalAfterDiscount : function(lineItemRow, totalAfterDiscountValue){ 311 jQuery('.totalAfterDiscount',lineItemRow).text(totalAfterDiscountValue); 312 return this; 313 }, 314 315 /** 316 * Function which will get the value of total after discount 317 * @params : lineItemRow - row which represents the line item 318 * @return : string 319 */ 320 getTotalAfterDiscount : function(lineItemRow) { 321 return parseFloat(jQuery('.totalAfterDiscount',lineItemRow).text()); 322 }, 323 324 /** 325 * Function which will set the tax total 326 * @params : lineItemRow - row which represents the line item 327 * taxTotal - tax total 328 * @return : current instance; 329 */ 330 setLineItemTaxTotal : function(lineItemRow, taxTotal) { 331 jQuery('.productTaxTotal', lineItemRow).text(taxTotal); 332 return this; 333 }, 334 335 /** 336 * Function which will get the value of total tax 337 * @params : lineItemRow - row which represents the line item 338 * @return : string 339 */ 340 getLineItemTaxTotal : function(lineItemRow){ 341 return parseFloat(jQuery('.productTaxTotal', lineItemRow).text()); 342 }, 343 344 /** 345 * Function which will set the line item net price 346 * @params : lineItemRow - row which represents the line item 347 * lineItemNetPriceValue - line item net price value 348 * @return : current instance; 349 */ 350 setLineItemNetPrice : function(lineItemRow, lineItemNetPriceValue){ 351 jQuery('.netPrice',lineItemRow).text(lineItemNetPriceValue); 352 return this; 353 }, 354 355 /** 356 * Function which will get the value of net price 357 * @params : lineItemRow - row which represents the line item 358 * @return : string 359 */ 360 getLineItemNetPrice : function(lineItemRow) { 361 return parseFloat(jQuery('.netPrice',lineItemRow).text()); 362 }, 363 364 setNetTotal : function(netTotalValue){ 365 jQuery('#netTotal').text(netTotalValue); 366 return this; 367 }, 368 369 getNetTotal : function() { 370 return parseFloat(jQuery('#netTotal').text()); 371 }, 372 373 /** 374 * Function to set the final discount total 375 */ 376 setFinalDiscountTotal : function(finalDiscountValue){ 377 jQuery('#discountTotal_final').text(finalDiscountValue); 378 return this; 379 }, 380 381 getFinalDiscountTotal : function() { 382 return parseFloat(jQuery('#discountTotal_final').text()); 383 }, 384 385 setGroupTaxTotal : function(groupTaxTotalValue) { 386 jQuery('#tax_final').text(groupTaxTotalValue); 387 }, 388 389 getGroupTaxTotal : function() { 390 return parseFloat(jQuery('#tax_final').text()); 391 }, 392 393 getShippingAndHandling : function() { 394 return parseFloat(this.getShippingAndHandlingControlElement().val()); 395 }, 396 397 setShippingAndHandlingTaxTotal : function() { 398 var shippingTotal = jQuery('.shippingTaxTotal'); 399 var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val()); 400 var shippingFinalTaxTotal = 0; 401 jQuery.each(shippingTotal,function(index,domElement){ 402 var totalVal = parseFloat(jQuery(domElement).val()); 403 shippingFinalTaxTotal += totalVal; 404 }); 405 shippingFinalTaxTotal = shippingFinalTaxTotal.toFixed(numberOfDecimal); 406 jQuery('#shipping_handling_tax').text(shippingFinalTaxTotal); 407 return this; 408 }, 409 410 getShippingAndHandlingTaxTotal : function() { 411 return parseFloat(jQuery('#shipping_handling_tax').text()); 412 }, 413 414 getAdjustmentValue : function() { 415 return parseFloat(this.getAdjustmentTextElement().val()); 416 }, 417 418 isAdjustMentAddType : function() { 419 var adjustmentSelectElement = this.getAdjustmentTypeElement(); 420 var selectionOption; 421 adjustmentSelectElement.each(function(){ 422 if(jQuery(this).is(':checked')){ 423 selectionOption = jQuery(this); 424 } 425 }) 426 if(typeof selectionOption != "undefined"){ 427 if(selectionOption.val() == '+'){ 428 return true; 429 } 430 } 431 return false; 432 }, 433 434 isAdjustMentDeductType : function() { 435 var adjustmentSelectElement = this.getAdjustmentTypeElement(); 436 var selectionOption; 437 adjustmentSelectElement.each(function(){ 438 if(jQuery(this).is(':checked')){ 439 selectionOption = jQuery(this); 440 } 441 }) 442 if(typeof selectionOption != "undefined"){ 443 if(selectionOption.val() == '-'){ 444 return true; 445 } 446 } 447 return false; 448 }, 449 450 setGrandTotal : function(grandTotalValue) { 451 jQuery('#grandTotal').text(grandTotalValue); 452 return this; 453 }, 454 455 getGrandTotal : function() { 456 return parseFloat(jQuery('#grandTotal').text()); 457 }, 458 459 loadRowSequenceNumber: function() { 460 if(this.rowSequenceHolder == false) { 461 this.rowSequenceHolder = jQuery('.' + this.rowClass, this.getLineItemContentsContainer()).length; 462 } 463 return this; 464 }, 465 466 getNextLineItemRowNumber : function() { 467 if(this.rowSequenceHolder == false){ 468 this.loadRowSequenceNumber(); 469 } 470 return ++this.rowSequenceHolder; 471 }, 472 473 /** 474 * Function which will return the basic row which can be used to add new rows 475 * @return jQuery object which you can use to 476 */ 477 getBasicRow : function() { 478 if(this.basicRow == false){ 479 var lineItemTable = this.getLineItemContentsContainer(); 480 this.basicRow = jQuery('.lineItemCloneCopy',lineItemTable) 481 } 482 var newRow = this.basicRow.clone(true,true); 483 var individualTax = this.isIndividualTaxMode(); 484 if(individualTax){ 485 newRow.find('.individualTaxContainer').removeClass('hide'); 486 } 487 return newRow.removeClass('hide lineItemCloneCopy'); 488 }, 489 490 registerAddingNewProductsAndServices: function(){ 491 var thisInstance = this; 492 var lineItemTable = this.getLineItemContentsContainer(); 493 jQuery('#addProduct').on('click',function(){ 494 var newRow = thisInstance.getBasicRow().addClass(thisInstance.rowClass); 495 jQuery('.lineItemPopup[data-module-name="Services"]',newRow).remove(); 496 var sequenceNumber = thisInstance.getNextLineItemRowNumber(); 497 newRow = newRow.appendTo(lineItemTable); 498 thisInstance.checkLineItemRow(); 499 newRow.find('input.rowNumber').val(sequenceNumber); 500 thisInstance.updateLineItemsElementWithSequenceNumber(newRow,sequenceNumber); 501 newRow.find('input.productName').addClass('autoComplete'); 502 thisInstance.registerLineItemAutoComplete(newRow); 503 }); 504 jQuery('#addService').on('click',function(){ 505 var newRow = thisInstance.getBasicRow().addClass(thisInstance.rowClass); 506 jQuery('.lineItemPopup[data-module-name="Products"]',newRow).remove(); 507 var sequenceNumber = thisInstance.getNextLineItemRowNumber(); 508 newRow = newRow.appendTo(lineItemTable); 509 thisInstance.checkLineItemRow(); 510 newRow.find('input.rowNumber').val(sequenceNumber); 511 thisInstance.updateLineItemsElementWithSequenceNumber(newRow,sequenceNumber); 512 newRow.find('input.productName').addClass('autoComplete'); 513 thisInstance.registerLineItemAutoComplete(newRow); 514 }); 515 }, 516 getTaxDiv: function(taxObj,parentRow){ 517 var rowNumber = jQuery('input.rowNumber',parentRow).val(); 518 var loopIterator = 1; 519 var taxDiv = '<div class="taxUI validCheck hide" id="tax_div'+rowNumber+'">'+ 520 '<table width="100%" border="0" cellpadding="5" cellspacing="0" class="table table-nobordered popupTable" id="tax_table'+rowNumber+'">'+ 521 '<tr>'+ 522 '<th id="tax_div_title'+rowNumber+'" align="left" ><b>Set Tax for :</b></th>'+ 523 '<th colspan="2"><button aria-hidden="true" data-dismiss="modal" class="close closeDiv" type="button">x</button>'+ 524 '</th>'+ 525 '</tr>'; 526 if(!jQuery.isEmptyObject(taxObj)){ 527 for(var taxName in taxObj){ 528 var taxInfo = taxObj[taxName] 529 taxDiv += '<tr>'+ 530 '<td>'+ 531 '<input type="text" name="'+taxName+'_percentage'+rowNumber+'" data-validation-engine="validate[funcCall[Vtiger_PositiveNumber_Validator_Js.invokeValidation]]" id="'+taxName+'_percentage'+rowNumber+'" value="'+taxInfo.percentage+'" class="smallInputBox taxPercentage"> %'+ 532 '</td>'+ 533 '<td><div class="textOverflowEllipsis">'+taxInfo.label+'</div></td> '+ 534 '<td>'+ 535 '<input type="text" name="popup_tax_row'+rowNumber+'" class="cursorPointer smallInputBox taxTotal" value="0.0" readonly>'+ 536 '</td>'+ 537 '</tr>'; 538 loopIterator++; 539 } 540 }else{ 541 taxDiv += '<tr>'+ 542 '<td>'+app.vtranslate("JS_LBL_NO_TAXES")+'</td>'+ 543 '</tr>'; 544 } 545 taxDiv += '</table><div class="modal-footer lineItemPopupModalFooter modal-footer-padding">'+ 546 '<div class=" pull-right cancelLinkContainer">'+ 547 '<a class="cancelLink" type="reset" data-dismiss="modal">'+app.vtranslate("JS_LBL_CANCEL")+'</a>'+ 548 '</div>'+ 549 '<button class="btn btn-success taxSave" type="button" name="lineItemActionSave"><strong>'+app.vtranslate("JS_LBL_SAVE")+'</strong></button>'+ 550 '</div></div>'; 551 return jQuery(taxDiv); 552 }, 553 554 loadSubProducts : function(lineItemRow) { 555 var recordId = jQuery('input.selectedModuleId',lineItemRow).val(); 556 var subProrductParams = { 557 'module' : "Products", 558 'action' : "SubProducts", 559 'record' : recordId 560 } 561 var progressInstace = jQuery.progressIndicator(); 562 AppConnector.request(subProrductParams).then( 563 function(data){ 564 565 var responseData = data.result; 566 var subProductsContainer = jQuery('.subProductsContainer',lineItemRow); 567 var subProductIdHolder = jQuery('.subProductIds',lineItemRow); 568 569 var subProductHtml = ''; 570 for(var id in responseData) { 571 subProductHtml += '<em>-'+responseData[id]+'</em><br>'; 572 } 573 subProductIdHolder.val(Object.keys(responseData).join(':')); 574 subProductsContainer.html(subProductHtml); 575 progressInstace.hide(); 576 }, 577 function(error,err){ 578 //TODO : handle the error case 579 } 580 ); 581 }, 582 583 mapResultsToFields: function(referenceModule,element,responseData){ 584 var parentRow = jQuery(element).closest('tr.'+this.rowClass); 585 var lineItemNameElment = jQuery('input.productName',parentRow); 586 587 for(var id in responseData){ 588 var recordId = id; 589 var recordData = responseData[id]; 590 var selectedName = recordData.name; 591 var unitPrice = recordData.listprice; 592 var listPriceValues = recordData.listpricevalues; 593 var taxes = recordData.taxes; 594 if(referenceModule == 'Products') { 595 parentRow.data('quantity-in-stock',recordData.quantityInStock); 596 } 597 var description = recordData.description; 598 jQuery('input.selectedModuleId',parentRow).val(recordId); 599 jQuery('input.lineItemType',parentRow).val(referenceModule); 600 lineItemNameElment.val(selectedName); 601 lineItemNameElment.attr('disabled', 'disabled'); 602 jQuery('input.listPrice',parentRow).val(unitPrice); 603 var currencyId = jQuery("#currency_id").val(); 604 var listPriceValuesJson = JSON.stringify(listPriceValues); 605 if(typeof listPriceValues[currencyId]!= 'undefined') { 606 this.setListPriceValue(parentRow, listPriceValues[currencyId]); 607 this.lineItemRowCalculations(parentRow); 608 } 609 jQuery('input.listPrice',parentRow).attr('list-info',listPriceValuesJson); 610 jQuery('textarea.lineItemCommentBox',parentRow).val(description); 611 var taxUI = this.getTaxDiv(taxes,parentRow); 612 jQuery('.taxDivContainer',parentRow).html(taxUI); 613 if(this.isIndividualTaxMode()) { 614 parentRow.find('.productTaxTotal').removeClass('hide') 615 }else{ 616 parentRow.find('.productTaxTotal').addClass('hide') 617 } 618 } 619 if(referenceModule == 'Products'){ 620 this.loadSubProducts(parentRow); 621 } 622 623 jQuery('.qty',parentRow).trigger('focusout'); 624 }, 625 626 showPopup : function(params) { 627 var aDeferred = jQuery.Deferred(); 628 var popupInstance = Vtiger_Popup_Js.getInstance(); 629 popupInstance.show(params, function(data){ 630 aDeferred.resolve(data); 631 }); 632 return aDeferred.promise(); 633 }, 634 635 /* 636 * Function which is reposible to handle the line item popups 637 * @params : popupImageElement - popup image element 638 */ 639 lineItemPopupEventHandler : function(popupImageElement) { 640 var aDeferred = jQuery.Deferred(); 641 var thisInstance = this; 642 var referenceModule = popupImageElement.data('moduleName'); 643 var moduleName = app.getModuleName(); 644 //thisInstance.getModulePopUp(e,referenceModule); 645 var params = {}; 646 params.view = popupImageElement.data('popup'); 647 params.module = moduleName; 648 params.multi_select = true; 649 params.currency_id = jQuery('#currency_id option:selected').val(); 650 651 this.showPopup(params).then(function(data){ 652 var responseData = JSON.parse(data); 653 var len = Object.keys(responseData).length; 654 if(len >1 ){ 655 for(var i=0;i<len;i++){ 656 if(i == 0){ 657 thisInstance.mapResultsToFields(referenceModule,popupImageElement,responseData[i]); 658 }else if(i >= 1 && (referenceModule == 'Products' || referenceModule == 'Services')){ 659 if(referenceModule == 'Products') { 660 var row = jQuery('#addProduct').trigger('click'); 661 } else if(referenceModule == 'Services') { 662 var row1 = jQuery('#addService').trigger('click'); 663 } 664 //TODO : CLEAN : we might synchronus invocation since following elements needs to executed once new row is created 665 var newRow = jQuery('#lineItemTab > tbody > tr:last'); 666 var targetElem = jQuery('.lineItemPopup',newRow); 667 thisInstance.mapResultsToFields(referenceModule,targetElem,responseData[i]); 668 aDeferred.resolve(); 669 } 670 } 671 }else{ 672 thisInstance.mapResultsToFields(referenceModule,popupImageElement,responseData); 673 aDeferred.resolve(); 674 } 675 }) 676 return aDeferred.promise(); 677 }, 678 679 /** 680 * Function which will be used to handle price book popup 681 * @params : popupImageElement - popup image element 682 */ 683 pricebooksPopupHandler : function(popupImageElement){ 684 var thisInstance = this; 685 var lineItemRow = popupImageElement.closest('tr.'+ this.rowClass); 686 var lineItemProductOrServiceElement = lineItemRow.find('input.productName').closest('td'); 687 var params = {}; 688 params.module = 'PriceBooks'; 689 params.src_module = jQuery('img.lineItemPopup',lineItemProductOrServiceElement).data('moduleName'); 690 params.src_field = jQuery('img.lineItemPopup',lineItemProductOrServiceElement).data('fieldName'); 691 params.src_record = jQuery('input.selectedModuleId',lineItemProductOrServiceElement).val(); 692 params.get_url = 'getProductListPriceURL'; 693 params.currency_id = jQuery('#currency_id option:selected').val(); 694 this.showPopup(params).then(function(data){ 695 var responseData = JSON.parse(data); 696 for(var id in responseData){ 697 thisInstance.setListPriceValue(lineItemRow,responseData[id]); 698 } 699 thisInstance.quantityChangeActions(lineItemRow); 700 }); 701 }, 702 703 /** 704 * Function which will calculate line item total excluding discount and tax 705 * @params : lineItemRow - element which will represent lineItemRow 706 */ 707 calculateLineItemTotal : function (lineItemRow) { 708 var quantity = this.getQuantityValue(lineItemRow); 709 var listPrice = this.getListPriceValue(lineItemRow); 710 var lineItemTotal = parseFloat(quantity) * parseFloat(listPrice); 711 this.setLineItemTotal(lineItemRow,lineItemTotal); 712 }, 713 714 /** 715 * Function which will calculate discount for the line item 716 * @params : lineItemRow - element which will represent lineItemRow 717 */ 718 calculateDiscountForLineItem : function(lineItemRow) { 719 var discountContianer = lineItemRow.find('div.discountUI'); 720 var element = discountContianer.find('input.discounts').filter(':checked'); 721 var discountType = element.data('discountType'); 722 var discountRow = element.closest('tr'); 723 724 jQuery('input.discount_type',discountContianer).val(discountType); 725 var rowPercentageField = jQuery('input.discount_percentage',discountContianer); 726 var rowAmountField = jQuery('input.discount_amount',discountContianer); 727 728 //intially making percentage and amount discount fields as hidden 729 rowPercentageField.addClass('hide'); 730 rowAmountField.addClass('hide'); 731 732 var discountValue = discountRow.find('.discountVal').val(); 733 if(discountValue == ""){ 734 discountValue = 0; 735 } 736 if(isNaN(discountValue) || discountValue < 0){ 737 discountValue = 0; 738 } 739 if(discountType == Inventory_Edit_Js.percentageDiscountType){ 740 rowPercentageField.removeClass('hide').focus(); 741 //since it is percentage 742 var productTotal = this.getLineItemTotal(lineItemRow); 743 discountValue = (productTotal * discountValue)/100; 744 }else if(discountType == Inventory_Edit_Js.directAmountDiscountType){ 745 rowAmountField.removeClass('hide').focus(); 746 } 747 this.setDiscountTotal(lineItemRow,discountValue) 748 .calculateTotalAfterDiscount(lineItemRow); 749 }, 750 751 /** 752 * Function which will calculate line item total after discount 753 * @params : lineItemRow - element which will represent lineItemRow 754 */ 755 calculateTotalAfterDiscount: function(lineItemRow) { 756 var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val()); 757 var productTotal = this.getLineItemTotal(lineItemRow); 758 var discountTotal = this.getDiscountTotal(lineItemRow); 759 var totalAfterDiscount = productTotal - discountTotal; 760 totalAfterDiscount = totalAfterDiscount.toFixed(numberOfDecimal); 761 this.setTotalAfterDiscount(lineItemRow,totalAfterDiscount); 762 }, 763 764 /** 765 * Function which will calculate tax for the line item total after discount 766 */ 767 calculateTaxForLineItem : function(lineItemRow) { 768 var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val()); 769 var totalAfterDiscount = this.getTotalAfterDiscount(lineItemRow); 770 var taxPercentages = jQuery('.taxPercentage',lineItemRow); 771 //intially make the tax as zero 772 var taxTotal = 0; 773 jQuery.each(taxPercentages,function(index,domElement){ 774 var taxPercentage = jQuery(domElement); 775 var individualTaxRow = taxPercentage.closest('tr'); 776 var individualTaxPercentage = taxPercentage.val(); 777 if(individualTaxPercentage == ""){ 778 individualTaxPercentage = "0.00"; 779 } 780 if(isNaN(individualTaxPercentage)){ 781 var individualTaxTotal = "0.00"; 782 } else { 783 var individualTaxPercentage = parseFloat(individualTaxPercentage); 784 var individualTaxTotal = Math.abs(individualTaxPercentage * totalAfterDiscount)/100; 785 individualTaxTotal = individualTaxTotal.toFixed(numberOfDecimal); 786 } 787 jQuery('.taxTotal',individualTaxRow).val(individualTaxTotal); 788 taxTotal += parseFloat(individualTaxTotal); 789 }); 790 taxTotal = parseFloat(taxTotal.toFixed(numberOfDecimal)); 791 this.setLineItemTaxTotal(lineItemRow, taxTotal); 792 }, 793 794 /** 795 * Function which will calculate net price for the line item 796 */ 797 calculateLineItemNetPrice : function(lineItemRow) { 798 var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val()); 799 var totalAfterDiscount = this.getTotalAfterDiscount(lineItemRow); 800 var netPrice = parseFloat(totalAfterDiscount); 801 if(this.isIndividualTaxMode()) { 802 var productTaxTotal = this.getLineItemTaxTotal(lineItemRow); 803 netPrice += parseFloat(productTaxTotal) 804 } 805 netPrice = netPrice.toFixed(numberOfDecimal); 806 this.setLineItemNetPrice(lineItemRow,netPrice); 807 }, 808 809 /** 810 * Function which will caliculate the total net price for all the line items 811 */ 812 calculateNetTotal : function() { 813 var thisInstance = this 814 var lineItemTable = this.getLineItemContentsContainer(); 815 var netTotalValue = 0; 816 lineItemTable.find('tr.'+this.rowClass).each(function(index,domElement){ 817 var lineItemRow = jQuery(domElement); 818 netTotalValue += thisInstance.getLineItemNetPrice(lineItemRow); 819 }); 820 this.setNetTotal(netTotalValue); 821 }, 822 823 calculateFinalDiscount : function() { 824 var thisInstance = this; 825 var discountContainer = jQuery('#finalDiscountUI'); 826 var element = discountContainer.find('input.finalDiscounts').filter(':checked'); 827 var discountType = element.data('discountType'); 828 var discountRow = element.closest('tr'); 829 var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val()); 830 831 jQuery('#discount_type_final').val(discountType); 832 var rowPercentageField = discountContainer.find('input.discount_percentage_final'); 833 var rowAmountField = discountContainer.find('input.discount_amount_final'); 834 835 //intially making percentage and amount discount fields as hidden 836 rowPercentageField.addClass('hide'); 837 rowAmountField.addClass('hide'); 838 839 var discountValue = discountRow.find('.discountVal').val(); 840 if(discountValue == ""){ 841 discountValue = 0; 842 } 843 if(isNaN(discountValue) || discountValue < 0){ 844 discountValue = 0; 845 } 846 if(discountType == Inventory_Edit_Js.percentageDiscountType){ 847 rowPercentageField.removeClass('hide').focus(); 848 //since it is percentage 849 var productTotal = this.getNetTotal(); 850 discountValue = (productTotal * discountValue)/100; 851 }else if(discountType == Inventory_Edit_Js.directAmountDiscountType){ 852 if(thisInstance.prevSelectedCurrencyConversionRate){ 853 var conversionRate = jQuery('#conversion_rate').val(); 854 conversionRate = conversionRate / thisInstance.prevSelectedCurrencyConversionRate; 855 discountValue = discountValue * conversionRate; 856 discountRow.find('.discountVal').val(discountValue); 857 } 858 rowAmountField.removeClass('hide').focus(); 859 } 860 discountValue = parseFloat(discountValue).toFixed(numberOfDecimal); 861 this.setFinalDiscountTotal(discountValue); 862 this.calculatePreTaxTotal(); 863 }, 864 865 calculateGroupTax : function() { 866 var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val()); 867 var netTotal = this.getNetTotal(); 868 var finalDiscountValue = this.getFinalDiscountTotal(); 869 var amount = netTotal - finalDiscountValue; 870 amount = parseFloat(amount).toFixed(numberOfDecimal); 871 var groupTaxContainer = jQuery('#group_tax_div'); 872 var groupTaxTotal = 0; 873 groupTaxContainer.find('.groupTaxPercentage').each(function(index,domElement){ 874 var groupTaxPercentageElement = jQuery(domElement); 875 var groupTaxRow = groupTaxPercentageElement.closest('tr'); 876 if(isNaN(groupTaxPercentageElement.val())){ 877 var groupTaxValue = "0.00"; 878 } else { 879 var groupTaxValue = Math.abs(amount * groupTaxPercentageElement.val())/100; 880 } 881 groupTaxValue = parseFloat(groupTaxValue).toFixed(numberOfDecimal); 882 groupTaxRow.find('.groupTaxTotal').val(groupTaxValue); 883 groupTaxTotal += parseFloat(groupTaxValue); 884 }); 885 this.setGroupTaxTotal(groupTaxTotal); 886 }, 887 888 calculateShippingAndHandlingTaxCharges : function() { 889 var shippingHandlingCharge = this.getShippingAndHandling(); 890 var shippingTaxDiv = jQuery('#shipping_handling_div'); 891 var shippingTaxPercentage = shippingTaxDiv.find('.shippingTaxPercentage'); 892 893 jQuery.each(shippingTaxPercentage,function(index,domElement){ 894 var currentTaxPer = jQuery(domElement); 895 var currentParentRow = currentTaxPer.closest('tr'); 896 var currentTaxPerValue = currentTaxPer.val(); 897 var currentTaxTotal = "0.00"; 898 if(currentTaxPerValue == ""){ 899 currentTaxPerValue = "0.00"; 900 } 901 if(isNaN(currentTaxPerValue)){ 902 var currentTaxTotal = "0.00"; 903 } else { 904 currentTaxPerValue = parseFloat(currentTaxPerValue); 905 var currentTaxTotal = Math.abs(currentTaxPerValue * shippingHandlingCharge)/100; 906 } 907 jQuery('.shippingTaxTotal',currentParentRow).val(currentTaxTotal); 908 }); 909 }, 910 911 calculateGrandTotal : function(){ 912 var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val()); 913 var netTotal = this.getNetTotal(); 914 var discountTotal = this.getFinalDiscountTotal(); 915 var shippingHandlingCharge = this.getShippingAndHandling(); 916 var shippingHandlingTax = this.getShippingAndHandlingTaxTotal(); 917 var adjustment = this.getAdjustmentValue(); 918 var grandTotal = parseFloat(netTotal) - parseFloat(discountTotal) + parseFloat(shippingHandlingCharge) + parseFloat(shippingHandlingTax); 919 920 if(this.isGroupTaxMode()){ 921 grandTotal += this.getGroupTaxTotal(); 922 } 923 924 if(this.isAdjustMentAddType()) { 925 grandTotal += parseFloat(adjustment); 926 }else if(this.isAdjustMentDeductType()) { 927 grandTotal -= parseFloat(adjustment); 928 } 929 930 grandTotal = grandTotal.toFixed(numberOfDecimal); 931 this.setGrandTotal(grandTotal); 932 }, 933 934 registerFinalDiscountShowEvent : function(){ 935 var thisInstance = this; 936 jQuery('#finalDiscount').on('click',function(e){ 937 var finalDiscountUI = jQuery('#finalDiscountUI'); 938 thisInstance.hideLineItemPopup(); 939 finalDiscountUI.removeClass('hide'); 940 }); 941 }, 942 943 registerFinalDiscountChangeEvent : function() { 944 var lineItemResultTab = this.getLineItemResultContainer(); 945 var thisInstance = this; 946 947 lineItemResultTab.on('change','.finalDiscounts',function(e){ 948 thisInstance.finalDiscountChangeActions(); 949 }); 950 }, 951 952 registerFinalDiscountValueChangeEvent : function(){ 953 var thisInstance = this; 954 jQuery('.finalDiscountSave').on('click',function(e){ 955 thisInstance.finalDiscountChangeActions(); 956 }); 957 }, 958 959 registerLineItemActionSaveEvent : function(){ 960 var editForm = this.getForm(); 961 editForm.on('click','button[name="lineItemActionSave"]',function(){ 962 var match = true; 963 var formError = jQuery('#EditView').data('jqv').InvalidFields; 964 var closestDiv = jQuery('button[name="lineItemActionSave"]').closest('.validCheck').find('input[data-validation-engine]').not('.hide'); 965 jQuery(closestDiv).each(function(key,value){ 966 if(jQuery.inArray(value,formError) != -1){ 967 match = false; 968 } 969 }); 970 if(!match){ 971 editForm.removeData('submit'); 972 return false; 973 } else { 974 jQuery('.closeDiv').trigger('click'); 975 } 976 }); 977 }, 978 979 registerGroupTaxShowEvent : function() { 980 var thisInstance = this; 981 jQuery('#finalTax').on('click',function(e){ 982 var groupTaxContainer = jQuery('#group_tax_row'); 983 thisInstance.hideLineItemPopup(); 984 groupTaxContainer.find('.finalTaxUI').removeClass('hide'); 985 }); 986 }, 987 988 registerGroupTaxChangeEvent : function() { 989 var thisInstance = this; 990 var groupTaxContainer = jQuery('#group_tax_row'); 991 992 groupTaxContainer.on('focusout','.groupTaxPercentage',function(e){ 993 thisInstance.calculateGroupTax(); 994 thisInstance.calculateGrandTotal(); 995 }); 996 }, 997 998 registerShippingAndHandlingChargesChange : function(){ 999 var thisInstance = this; 1000 this.getShippingAndHandlingControlElement().on('focusout', function(e){ 1001 var value = jQuery(e.currentTarget).val(); 1002 if(value == ""){ 1003 jQuery(e.currentTarget).val("0.00"); 1004 } 1005 thisInstance.shippingAndHandlingChargesChangeActions(); 1006 }); 1007 jQuery('.shippingTaxPercentage').on('change',function(){ 1008 thisInstance.shippingAndHandlingChargesChangeActions(); 1009 }) 1010 jQuery('.finalTaxSave').on('click',function(){ 1011 thisInstance.setShippingAndHandlingTaxTotal(); 1012 }) 1013 }, 1014 1015 registerShippingAndHandlingTaxShowEvent : function(){ 1016 var thisInstance = this; 1017 jQuery('#shippingHandlingTax').on('click',function(e){ 1018 var finalShippingHandlingDiv = jQuery('#shipping_handling_div'); 1019 thisInstance.hideLineItemPopup(); 1020 finalShippingHandlingDiv.removeClass('hide'); 1021 }); 1022 }, 1023 1024 registerAdjustmentTypeChange : function() { 1025 var thisInstance = this; 1026 this.getAdjustmentTypeElement().on('change', function(e){ 1027 thisInstance.calculateGrandTotal(); 1028 }); 1029 }, 1030 1031 registerAdjustmentValueChange : function() { 1032 var thisInstance = this; 1033 this.getAdjustmentTextElement().on('focusout',function(e){ 1034 var value = jQuery(e.currentTarget).val(); 1035 if(value == ""){ 1036 jQuery(e.currentTarget).val("0.00"); 1037 } 1038 thisInstance.calculateGrandTotal(); 1039 }); 1040 }, 1041 1042 1043 registerLineItemsPopUpCancelClickEvent : function(){ 1044 var editForm = this.getForm(); 1045 editForm.on('click','.cancelLink',function(){ 1046 jQuery('.closeDiv').trigger('click') 1047 }) 1048 }, 1049 1050 lineItemResultActions: function(){ 1051 var thisInstance = this; 1052 var lineItemResultTab = this.getLineItemResultContainer(); 1053 1054 this.registerFinalDiscountShowEvent(); 1055 this.registerFinalDiscountValueChangeEvent(); 1056 this.registerFinalDiscountChangeEvent(); 1057 1058 this.registerLineItemActionSaveEvent(); 1059 this.registerLineItemsPopUpCancelClickEvent(); 1060 1061 this.registerGroupTaxShowEvent(); 1062 this.registerGroupTaxChangeEvent(); 1063 1064 this.registerShippingAndHandlingChargesChange(); 1065 this.registerShippingAndHandlingTaxShowEvent(); 1066 1067 this.registerAdjustmentTypeChange(); 1068 this.registerAdjustmentValueChange(); 1069 1070 lineItemResultTab.on('click','.closeDiv',function(e){ 1071 jQuery(e.target).closest('div').addClass('hide'); 1072 }); 1073 }, 1074 1075 1076 lineItemRowCalculations : function(lineItemRow) { 1077 this.calculateLineItemTotal(lineItemRow); 1078 this.calculateDiscountForLineItem(lineItemRow); 1079 this.calculateTaxForLineItem(lineItemRow); 1080 this.calculateLineItemNetPrice(lineItemRow); 1081 }, 1082 1083 lineItemToTalResultCalculations : function(){ 1084 this.calculateNetTotal(); 1085 this.calculateFinalDiscount(); 1086 if(this.isGroupTaxMode()){ 1087 this.calculateGroupTax(); 1088 } 1089 //this.calculateShippingAndHandlingTaxCharges(); 1090 this.calculateGrandTotal(); 1091 }, 1092 1093 /** 1094 * Function which will handle the actions that need to be preformed once the qty is changed like below 1095 * - calculate line item total -> discount and tax -> net price of line item -> grand total 1096 * @params : lineItemRow - element which will represent lineItemRow 1097 */ 1098 quantityChangeActions : function(lineItemRow) { 1099 this.lineItemRowCalculations(lineItemRow); 1100 this.lineItemToTalResultCalculations(); 1101 }, 1102 1103 lineItemDiscountChangeActions : function(lineItemRow){ 1104 this.calculateDiscountForLineItem(lineItemRow); 1105 this.calculateTaxForLineItem(lineItemRow); 1106 this.calculateLineItemNetPrice(lineItemRow); 1107 1108 this.lineItemToTalResultCalculations(); 1109 }, 1110 1111 1112 /** 1113 * Function which will handle the actions that need to be performed once the tax percentage is change for a line item 1114 * @params : lineItemRow - element which will represent lineItemRow 1115 */ 1116 1117 taxPercentageChangeActions : function(lineItemRow){ 1118 this.calculateLineItemNetPrice(lineItemRow); 1119 this.calculateNetTotal(); 1120 this.calculateFinalDiscount(); 1121 if(this.isGroupTaxMode()){ 1122 this.calculateGroupTax(); 1123 } 1124 //this.calculateShippingAndHandlingTaxCharges(); 1125 this.calculateGrandTotal(); 1126 }, 1127 1128 lineItemDeleteActions : function() { 1129 this.lineItemToTalResultCalculations(); 1130 }, 1131 1132 shippingAndHandlingChargesChangeActions : function(){ 1133 this.calculateShippingAndHandlingTaxCharges(); 1134 this.setShippingAndHandlingTaxTotal(); 1135 this.calculatePreTaxTotal(); 1136 this.calculateGrandTotal(); 1137 }, 1138 1139 finalDiscountChangeActions : function() { 1140 this.calculateFinalDiscount(); 1141 if(this.isGroupTaxMode()){ 1142 this.calculateGroupTax(); 1143 } 1144 this.calculateGrandTotal(); 1145 }, 1146 1147 /** 1148 * Function which will register change event for discounts radio buttons 1149 */ 1150 registerDisountChangeEvent : function() { 1151 var thisInstance = this; 1152 var lineItemTable = this.getLineItemContentsContainer(); 1153 lineItemTable.on('change','.discounts',function(e){ 1154 var lineItemRow = jQuery(e.currentTarget).closest('tr.'+thisInstance.rowClass); 1155 thisInstance.lineItemDiscountChangeActions(lineItemRow); 1156 }); 1157 }, 1158 1159 /** 1160 * Function which will register event for focusout of discount input fields like percentage and amount 1161 */ 1162 registerDisountValueChange : function() { 1163 var thisInstance = this; 1164 var lineItemTable = this.getLineItemContentsContainer(); 1165 lineItemTable.on('click','.discountSave', function(e){ 1166 var element = jQuery(e.currentTarget); 1167 //if the element is not hidden then we need to handle the focus out 1168 if(!app.isHidden(element)){ 1169 var lineItemRow = jQuery(e.currentTarget).closest('tr.'+thisInstance.rowClass); 1170 thisInstance.lineItemDiscountChangeActions(lineItemRow); 1171 } 1172 1173 }); 1174 }, 1175 1176 hideLineItemPopup : function(){ 1177 var editForm = this.getForm(); 1178 var popUpElementContainer = jQuery('.popupTable',editForm).closest('div'); 1179 if(popUpElementContainer.length > 0){ 1180 popUpElementContainer.addClass('hide'); 1181 } 1182 }, 1183 1184 registerLineItemDiscountShowEvent : function() { 1185 var thisInstance = this; 1186 var lineItemTable = this.getLineItemContentsContainer(); 1187 1188 lineItemTable.on('click','.individualDiscount',function(e){ 1189 var element = jQuery(e.currentTarget); 1190 var response = thisInstance.isProductSelected(element); 1191 if(response == true){ 1192 return; 1193 } 1194 var parentElem = jQuery(e.currentTarget).closest('td'); 1195 thisInstance.hideLineItemPopup(); 1196 parentElem.find('div.discountUI').removeClass('hide'); 1197 }); 1198 }, 1199 1200 /** 1201 * Function which will regiser events for product and service popup 1202 */ 1203 registerProductAndServicePopup : function() { 1204 var thisInstance = this; 1205 var lineItemTable = this.getLineItemContentsContainer(); 1206 lineItemTable.on('click','img.lineItemPopup', function(e){ 1207 var element = jQuery(e.currentTarget); 1208 thisInstance.lineItemPopupEventHandler(element).then(function(data){ 1209 var parent = element.closest('tr'); 1210 var deletedItemInfo = parent.find('.deletedItem'); 1211 if(deletedItemInfo.length > 0){ 1212 deletedItemInfo.remove(); 1213 } 1214 }) 1215 }); 1216 }, 1217 1218 /** 1219 * Function which will regisrer price book popup 1220 */ 1221 registerPriceBookPopUp : function () { 1222 var thisInstance = this; 1223 var lineItemTable = this.getLineItemContentsContainer(); 1224 1225 lineItemTable.on('click','.priceBookPopup',function(e){ 1226 var element = jQuery(e.currentTarget); 1227 var response = thisInstance.isProductSelected(element); 1228 if(response == true){ 1229 return; 1230 } 1231 thisInstance.pricebooksPopupHandler(element); 1232 }); 1233 }, 1234 1235 /* 1236 * Function which will register event for quantity change (focusout event) 1237 */ 1238 registerQuantityChangeEventHandler : function() { 1239 var thisInstance = this; 1240 var lineItemTable = this.getLineItemContentsContainer(); 1241 1242 lineItemTable.on('focusout','.qty',function(e){ 1243 var element = jQuery(e.currentTarget); 1244 var lineItemRow = element.closest('tr.'+thisInstance.rowClass); 1245 var quantityInStock = lineItemRow.data('quantityInStock'); 1246 if(typeof quantityInStock != 'undefined') { 1247 if(parseFloat(element.val()) > parseFloat(quantityInStock)) { 1248 lineItemRow.find('.stockAlert').removeClass('hide').find('.maxQuantity').text(quantityInStock); 1249 }else{ 1250 lineItemRow.find('.stockAlert').addClass('hide'); 1251 } 1252 } 1253 thisInstance.quantityChangeActions(lineItemRow); 1254 }); 1255 }, 1256 1257 /** 1258 * Function which will register event for list price event change 1259 */ 1260 registerListPriceChangeEvent : function() { 1261 var thisInstance = this; 1262 var lineItemTable = this.getLineItemContentsContainer(); 1263 1264 lineItemTable.on('focusout', 'input.listPrice',function(e){ 1265 var element = jQuery(e.currentTarget); 1266 var lineItemRow = thisInstance.getClosestLineItemRow(element); 1267 thisInstance.quantityChangeActions(lineItemRow); 1268 }); 1269 }, 1270 1271 registerTaxPercentageChange : function() { 1272 var thisInstance = this; 1273 var lineItemTable = this.getLineItemContentsContainer(); 1274 1275 lineItemTable.on('focusout','.taxPercentage',function(e){ 1276 var element = jQuery(e.currentTarget); 1277 var lineItemRow = thisInstance.getClosestLineItemRow(element); 1278 thisInstance.calculateTaxForLineItem(lineItemRow); 1279 }); 1280 1281 lineItemTable.on('click','.taxSave',function(e){ 1282 var element = jQuery(e.currentTarget); 1283 var lineItemRow = thisInstance.getClosestLineItemRow(element); 1284 thisInstance.taxPercentageChangeActions(lineItemRow); 1285 }); 1286 }, 1287 1288 isProductSelected : function(element){ 1289 var parentRow = element.closest('tr'); 1290 var productField = parentRow.find('.productName'); 1291 var response = productField.validationEngine('validate'); 1292 return response; 1293 }, 1294 1295 registerLineItemTaxShowEvent : function() { 1296 var thisInstance = this; 1297 var lineItemTable = this.getLineItemContentsContainer(); 1298 1299 lineItemTable.on('click','.individualTax',function(e){ 1300 var element = jQuery(e.currentTarget); 1301 var response = thisInstance.isProductSelected(element); 1302 if(response == true){ 1303 return; 1304 } 1305 var parentElem = jQuery(e.currentTarget).closest('td'); 1306 thisInstance.hideLineItemPopup() 1307 parentElem.find('.taxUI').removeClass('hide'); 1308 }); 1309 }, 1310 1311 registerDeleteLineItemEvent : function(){ 1312 var thisInstance = this; 1313 var lineItemTable = this.getLineItemContentsContainer(); 1314 1315 lineItemTable.on('click','.deleteRow',function(e){ 1316 var element = jQuery(e.currentTarget); 1317 //removing the row 1318 element.closest('tr.'+ thisInstance.rowClass).remove(); 1319 thisInstance.checkLineItemRow(); 1320 thisInstance.lineItemDeleteActions(); 1321 }); 1322 }, 1323 1324 registerTaxTypeChange : function() { 1325 var thisInstance = this; 1326 var lineItemTable = this.getLineItemContentsContainer(); 1327 1328 this.getTaxTypeSelectElement().on('change', function(e){ 1329 if(thisInstance.isIndividualTaxMode()) { 1330 jQuery('#group_tax_row').addClass('hide'); 1331 lineItemTable.find('tr.'+thisInstance.rowClass).each(function(index,domElement){ 1332 var lineItemRow = jQuery(domElement); 1333 lineItemRow.find('.individualTaxContainer,.productTaxTotal').removeClass('hide'); 1334 thisInstance.lineItemRowCalculations(lineItemRow); 1335 }); 1336 }else{ 1337 jQuery('#group_tax_row').removeClass('hide'); 1338 lineItemTable.find('tr.'+thisInstance.rowClass).each(function(index,domElement){ 1339 var lineItemRow = jQuery(domElement); 1340 lineItemRow.find('.individualTaxContainer,.productTaxTotal').addClass('hide'); 1341 thisInstance.calculateLineItemNetPrice(lineItemRow); 1342 }); 1343 } 1344 thisInstance.lineItemToTalResultCalculations(); 1345 }); 1346 }, 1347 1348 registerCurrencyChangeEvent : function() { 1349 var thisInstance = this; 1350 jQuery('#currency_id').change(function(e){ 1351 var element = jQuery(e.currentTarget); 1352 var currencyId = element.val(); 1353 var conversionRateElem = jQuery('#conversion_rate'); 1354 var prevSelectedCurrencyConversionRate = conversionRateElem.val(); 1355 thisInstance.prevSelectedCurrencyConversionRate = prevSelectedCurrencyConversionRate; 1356 var optionsSelected = element.find('option:selected'); 1357 var conversionRate = optionsSelected.data('conversionRate'); 1358 conversionRateElem.val(conversionRate); 1359 conversionRate = parseFloat(conversionRate)/ parseFloat(prevSelectedCurrencyConversionRate); 1360 thisInstance.LineItemDirectDiscountCal(conversionRate); 1361 var lineItemTable = thisInstance.getLineItemContentsContainer(); 1362 lineItemTable.find('tr.'+thisInstance.rowClass).each(function(index,domElement){ 1363 var lineItemRow = jQuery(domElement); 1364 var listPriceElement = jQuery(lineItemRow).find('[name^=listPrice]'); 1365 var listPriceValues = JSON.parse(listPriceElement.attr('list-info')); 1366 if(typeof listPriceValues[currencyId]!= 'undefined') { 1367 thisInstance.setListPriceValue(lineItemRow, listPriceValues[currencyId]); 1368 thisInstance.lineItemRowCalculations(lineItemRow); 1369 } else { 1370 var listPriceVal = thisInstance.getListPriceValue(lineItemRow); 1371 var convertedListPrice = listPriceVal * conversionRate; 1372 thisInstance.setListPriceValue(lineItemRow, convertedListPrice); 1373 thisInstance.lineItemRowCalculations(lineItemRow); 1374 } 1375 1376 }); 1377 thisInstance.AdjustmentShippingResultCalculation(conversionRate); 1378 thisInstance.lineItemToTalResultCalculations(); 1379 jQuery('#prev_selected_currency_id').val(optionsSelected.val()) 1380 }); 1381 }, 1382 1383 AdjustmentShippingResultCalculation: function(conversionRate){ 1384 //Adjustment 1385 var thisInstance = this; 1386 var adjustmentElement = thisInstance.getAdjustmentTextElement(); 1387 var newAdjustment = jQuery(adjustmentElement).val() * conversionRate; 1388 jQuery(adjustmentElement).val(newAdjustment); 1389 1390 //Shipping & handling 1391 var shippingHandlingElement = thisInstance.getShippingAndHandlingControlElement(); 1392 var resultVal = jQuery(shippingHandlingElement).val() * conversionRate; 1393 jQuery(shippingHandlingElement).val(resultVal); 1394 jQuery(shippingHandlingElement).trigger('focusout'); 1395 }, 1396 1397 LineItemDirectDiscountCal: function(conversionRate){ 1398 //LineItems Discount Calculations for direct Price reduction 1399 var thisInstance = this; 1400 1401 var lineItemRows = jQuery('.lineItemRow'); 1402 jQuery(lineItemRows).each(function(index) { 1403 var lineItemRow = jQuery(lineItemRows[index]); 1404 var discountContianer = lineItemRow.find('div.discountUI'); 1405 var element = discountContianer.find('input.discounts').filter(':checked'); 1406 var discountRow = element.closest('tr'); 1407 var discountType = element.data('discountType'); 1408 var discountValue = discountRow.find('.discountVal').val(); 1409 if((discountType == Inventory_Edit_Js.directAmountDiscountType) ){ 1410 var newdiscountValue = conversionRate * discountValue; 1411 discountRow.find('.discountVal').val(newdiscountValue); 1412 jQuery(element).closest('tr').find('.discountVal').val(newdiscountValue); 1413 thisInstance.setDiscountTotal(lineItemRow,newdiscountValue); 1414 } 1415 }); 1416 }, 1417 1418 lineItemActions: function() { 1419 var lineItemTable = this.getLineItemContentsContainer(); 1420 1421 this.registerDisountChangeEvent(); 1422 this.registerDisountValueChange(); 1423 this.registerLineItemDiscountShowEvent(); 1424 1425 this.registerLineItemAutoComplete(); 1426 this.registerClearLineItemSelection(); 1427 1428 this.registerProductAndServicePopup(); 1429 this.registerPriceBookPopUp(); 1430 1431 this.registerQuantityChangeEventHandler(); 1432 this.registerListPriceChangeEvent(); 1433 1434 this.registerTaxPercentageChange(); 1435 this.registerLineItemTaxShowEvent(); 1436 1437 this.registerDeleteLineItemEvent(); 1438 this.registerTaxTypeChange(); 1439 this.registerCurrencyChangeEvent(); 1440 1441 1442 1443 lineItemTable.on('click','.closeDiv',function(e){ 1444 jQuery(e.currentTarget).closest('div').addClass('hide'); 1445 }); 1446 1447 lineItemTable.on('click','.clearComment',function(e){ 1448 var elem = jQuery(e.currentTarget); 1449 var parentElem = elem.closest('div'); 1450 var comment = jQuery('.lineItemCommentBox',parentElem).val(''); 1451 }); 1452 1453 }, 1454 1455 /*** 1456 * Function which will update the line item row elements with the sequence number 1457 * @params : lineItemRow - tr line item row for which the sequence need to be updated 1458 * currentSequenceNUmber - existing sequence number that the elments is having 1459 * expectedSequenceNumber - sequence number to which it has to update 1460 * 1461 * @return : row element after changes 1462 */ 1463 updateLineItemsElementWithSequenceNumber : function(lineItemRow,expectedSequenceNumber , currentSequenceNumber){ 1464 if(typeof currentSequenceNumber == 'undefined') { 1465 //by default there will zero current sequence number 1466 currentSequenceNumber = 0; 1467 } 1468 1469 var idFields = new Array('productName','subproduct_ids','hdnProductId', 1470 'comment','qty','listPrice','discount_type','discount_percentage', 1471 'discount_amount','lineItemType','searchIcon','netPrice','subprod_names', 1472 'productTotal','discountTotal','totalAfterDiscount','taxTotal'); 1473 1474 var nameFields = new Array('discount'); 1475 var classFields = new Array('taxPercentage'); 1476 //To handle variable tax ids 1477 for(var classIndex in classFields) { 1478 var className = classFields[classIndex]; 1479 jQuery('.'+className,lineItemRow).each(function(index, domElement){ 1480 var idString = domElement.id 1481 //remove last character which will be the row number 1482 idFields.push(idString.slice(0,(idString.length-1))); 1483 }); 1484 } 1485 1486 var expectedRowId = 'row'+expectedSequenceNumber; 1487 for(var idIndex in idFields ) { 1488 var elementId = idFields[idIndex]; 1489 var actualElementId = elementId + currentSequenceNumber; 1490 var expectedElementId = elementId + expectedSequenceNumber; 1491 lineItemRow.find('#'+actualElementId).attr('id',expectedElementId) 1492 .filter('[name="'+actualElementId+'"]').attr('name',expectedElementId); 1493 } 1494 1495 for(var nameIndex in nameFields) { 1496 var elementName = nameFields[nameIndex]; 1497 var actualElementName = elementName + currentSequenceNumber; 1498 var expectedElementName = elementName + expectedSequenceNumber; 1499 lineItemRow.find('[name="'+actualElementName+'"]').attr('name',expectedElementName); 1500 } 1501 1502 1503 return lineItemRow.attr('id',expectedRowId); 1504 }, 1505 1506 1507 updateLineItemElementByOrder : function () { 1508 var lineItemContentsContainer = this.getLineItemContentsContainer(); 1509 var thisInstance = this; 1510 jQuery('tr.'+this.rowClass ,lineItemContentsContainer).each(function(index,domElement){ 1511 var lineItemRow = jQuery(domElement); 1512 var expectedRowIndex = (index+1); 1513 var expectedRowId = 'row'+expectedRowIndex; 1514 var actualRowId = lineItemRow.attr('id'); 1515 if(expectedRowId != actualRowId) { 1516 var actualIdComponents = actualRowId.split('row'); 1517 thisInstance.updateLineItemsElementWithSequenceNumber(lineItemRow, expectedRowIndex, actualIdComponents[1]); 1518 } 1519 }); 1520 }, 1521 1522 saveProductCount : function () { 1523 jQuery('#totalProductCount').val(jQuery('tr.'+this.rowClass, this.getLineItemContentsContainer()).length); 1524 }, 1525 1526 saveSubTotalValue : function() { 1527 jQuery('#subtotal').val(this.getNetTotal()); 1528 }, 1529 1530 saveTotalValue : function() { 1531 jQuery('#total').val(this.getGrandTotal()); 1532 }, 1533 1534 makeLineItemsSortable : function() { 1535 var thisInstance = this; 1536 var lineItemTable = this.getLineItemContentsContainer(); 1537 lineItemTable.sortable({ 1538 'containment' : lineItemTable, 1539 'items' : 'tr.'+this.rowClass, 1540 'revert' : true, 1541 'tolerance':'pointer', 1542 'helper' : function(e,ui){ 1543 //while dragging helper elements td element will take width as contents width 1544 //so we are explicity saying that it has to be same width so that element will not 1545 //look like distrubed 1546 ui.children().each(function(index,element){ 1547 element = jQuery(element); 1548 element.width(element.width()); 1549 }) 1550 return ui; 1551 } 1552 }).mousedown(function(event){ 1553 //TODO : work around for issue of mouse down even hijack in sortable plugin 1554 thisInstance.getClosestLineItemRow(jQuery(event.target)).find('input:focus').trigger('focusout'); 1555 }); 1556 }, 1557 1558 registerSubmitEvent : function () { 1559 var thisInstance = this; 1560 var editViewForm = this.getForm(); 1561 this._super(); 1562 editViewForm.submit(function(e){ 1563 var deletedItemInfo = jQuery('.deletedItem',editViewForm); 1564 if(deletedItemInfo.length > 0){ 1565 e.preventDefault(); 1566 var msg = app.vtranslate('JS_PLEASE_REMOVE_LINE_ITEM_THAT_IS_DELETED'); 1567 var params = { 1568 text : msg, 1569 type: 'error' 1570 } 1571 Vtiger_Helper_Js.showPnotify(params); 1572 editViewForm.removeData('submit'); 1573 return false; 1574 } 1575 thisInstance.updateLineItemElementByOrder(); 1576 var lineItemTable = thisInstance.getLineItemContentsContainer(); 1577 jQuery('.discountSave',lineItemTable).trigger('click'); 1578 thisInstance.lineItemToTalResultCalculations(); 1579 thisInstance.saveProductCount(); 1580 thisInstance.saveSubTotalValue(); 1581 thisInstance.saveTotalValue(); 1582 thisInstance.savePreTaxTotalValue(); 1583 }) 1584 }, 1585 1586 /** 1587 * Function which will register event for Reference Fields Selection 1588 */ 1589 registerReferenceSelectionEvent : function(container) { 1590 var thisInstance = this; 1591 1592 jQuery('input[name="contact_id"]', container).on(Vtiger_Edit_Js.referenceSelectionEvent, function(e, data){ 1593 thisInstance.referenceSelectionEventHandler(data, container); 1594 }); 1595 }, 1596 1597 /** 1598 * Reference Fields Selection Event Handler 1599 */ 1600 referenceSelectionEventHandler : function(data,container){ 1601 var thisInstance = this; 1602 var message = app.vtranslate('OVERWRITE_EXISTING_MSG1')+app.vtranslate('SINGLE_'+data['source_module'])+' ('+data['selectedName']+') '+app.vtranslate('OVERWRITE_EXISTING_MSG2'); 1603 Vtiger_Helper_Js.showConfirmationBox({'message' : message}).then( 1604 function(e) { 1605 thisInstance.copyAddressDetails(data, container); 1606 }, 1607 function(error, err){ 1608 }); 1609 }, 1610 1611 /** 1612 * Function which will copy the address details 1613 */ 1614 copyAddressDetails : function(data,container,addressMap) { 1615 var thisInstance = this; 1616 var sourceModule = data['source_module']; 1617 var noAddress = true; 1618 var errorMsg; 1619 1620 thisInstance.getRecordDetails(data).then( 1621 function(data){ 1622 var response = data['result']; 1623 if(typeof addressMap != "undefined"){ 1624 var result = response['data']; 1625 for(var key in addressMap) { 1626 if(result[addressMap[key]] != ""){ 1627 noAddress = false; 1628 break; 1629 } 1630 } 1631 if(noAddress){ 1632 if(sourceModule == "Accounts"){ 1633 errorMsg = 'JS_SELECTED_ACCOUNT_DOES_NOT_HAVE_AN_ADDRESS'; 1634 } else if(sourceModule == "Contacts"){ 1635 errorMsg = 'JS_SELECTED_CONTACT_DOES_NOT_HAVE_AN_ADDRESS'; 1636 } 1637 Vtiger_Helper_Js.showPnotify(app.vtranslate(errorMsg)); 1638 } else{ 1639 thisInstance.mapAddressDetails(addressMap, result, container); 1640 } 1641 } else{ 1642 thisInstance.mapAddressDetails(thisInstance.addressFieldsMapping[sourceModule], response['data'], container); 1643 if(sourceModule == "Accounts"){ 1644 container.find('.accountAddress').attr('checked','checked'); 1645 }else if(sourceModule == "Contacts"){ 1646 container.find('.contactAddress').attr('checked','checked'); 1647 } 1648 } 1649 }, 1650 function(error, err){ 1651 1652 }); 1653 }, 1654 1655 /** 1656 * Function which will copy the address details of the selected record 1657 */ 1658 mapAddressDetails : function(addressDetails, result, container) { 1659 for(var key in addressDetails) { 1660 container.find('[name="'+key+'"]').val(result[addressDetails[key]]); 1661 container.find('[name="'+key+'"]').trigger('change'); 1662 } 1663 }, 1664 1665 registerLineItemAutoComplete : function(container) { 1666 var thisInstance = this; 1667 if(typeof container == 'undefined') { 1668 container = thisInstance.getLineItemContentsContainer(); 1669 } 1670 container.find('input.autoComplete').autocomplete({ 1671 'minLength' : '3', 1672 'source' : function(request, response){ 1673 //element will be array of dom elements 1674 //here this refers to auto complete instance 1675 var inputElement = jQuery(this.element[0]); 1676 var tdElement = inputElement.closest('td'); 1677 var searchValue = request.term; 1678 var params = {}; 1679 var searchModule = tdElement.find('.lineItemPopup').data('moduleName'); 1680 params.search_module = searchModule 1681 params.search_value = searchValue; 1682 thisInstance.searchModuleNames(params).then(function(data){ 1683 var reponseDataList = new Array(); 1684 var serverDataFormat = data.result 1685 if(serverDataFormat.length <= 0) { 1686 serverDataFormat = new Array({ 1687 'label' : app.vtranslate('JS_NO_RESULTS_FOUND'), 1688 'type' : 'no results' 1689 }); 1690 } 1691 for(var id in serverDataFormat){ 1692 var responseData = serverDataFormat[id]; 1693 reponseDataList.push(responseData); 1694 } 1695 response(reponseDataList); 1696 }); 1697 }, 1698 'select' : function(event, ui ){ 1699 var selectedItemData = ui.item; 1700 //To stop selection if no results is selected 1701 if(typeof selectedItemData.type != 'undefined' && selectedItemData.type=="no results"){ 1702 return false; 1703 } 1704 var element = jQuery(this); 1705 element.attr('disabled','disabled'); 1706 var tdElement = element.closest('td'); 1707 var selectedModule = tdElement.find('.lineItemPopup').data('moduleName'); 1708 var popupElement = tdElement.find('.lineItemPopup'); 1709 var dataUrl = "index.php?module=Inventory&action=GetTaxes&record="+selectedItemData.id+"¤cy_id="+jQuery('#currency_id option:selected').val(); 1710 AppConnector.request(dataUrl).then( 1711 function(data){ 1712 for(var id in data){ 1713 if(typeof data[id] == "object"){ 1714 var recordData = data[id]; 1715 thisInstance.mapResultsToFields(selectedModule, popupElement, recordData); 1716 } 1717 } 1718 }, 1719 function(error,err){ 1720 1721 } 1722 ); 1723 }, 1724 'change' : function(event, ui) { 1725 var element = jQuery(this); 1726 //if you dont have disabled attribute means the user didnt select the item 1727 if(element.attr('disabled')== undefined) { 1728 element.closest('td').find('.clearLineItem').trigger('click'); 1729 } 1730 } 1731 }); 1732 }, 1733 1734 registerClearLineItemSelection : function() { 1735 var thisInstance = this; 1736 var lineItemTable = this.getLineItemContentsContainer(); 1737 lineItemTable.on('click','.clearLineItem',function(e){ 1738 var elem = jQuery(e.currentTarget); 1739 var parentElem = elem.closest('td'); 1740 thisInstance.clearLineItemDetails(parentElem); 1741 parentElem.find('input.productName').removeAttr('disabled').val(''); 1742 e.preventDefault(); 1743 }); 1744 }, 1745 1746 clearLineItemDetails : function(parentElem) { 1747 var thisInstance = this; 1748 var lineItemRow = parentElem.closest('tr.'+thisInstance.rowClass); 1749 jQuery('input.selectedModuleId',lineItemRow).val(''); 1750 jQuery('input.listPrice',lineItemRow).val('0'); 1751 jQuery('.lineItemCommentBox', lineItemRow).val(''); 1752 thisInstance.quantityChangeActions(lineItemRow); 1753 }, 1754 1755 checkLineItemRow : function(){ 1756 var lineItemTable = this.getLineItemContentsContainer(); 1757 var noRow = lineItemTable.find('.lineItemRow').length; 1758 if(noRow >1){ 1759 this.showLineItemsDeleteIcon(); 1760 }else{ 1761 this.hideLineItemsDeleteIcon(); 1762 } 1763 }, 1764 1765 showLineItemsDeleteIcon : function(){ 1766 var lineItemTable = this.getLineItemContentsContainer(); 1767 lineItemTable.find('.deleteRow').show(); 1768 }, 1769 1770 hideLineItemsDeleteIcon : function(){ 1771 var lineItemTable = this.getLineItemContentsContainer(); 1772 lineItemTable.find('.deleteRow').hide(); 1773 }, 1774 1775 /** 1776 * Function to swap array 1777 * @param Array that need to be swapped 1778 */ 1779 swapObject : function(objectToSwap){ 1780 var swappedArray = {}; 1781 var newKey,newValue; 1782 for(var key in objectToSwap){ 1783 newKey = objectToSwap[key]; 1784 newValue = key; 1785 swappedArray[newKey] = newValue; 1786 } 1787 return swappedArray; 1788 }, 1789 1790 /** 1791 * Function to copy address between fields 1792 * @param strings which accepts value as either odd or even 1793 */ 1794 copyAddress : function(swapMode){ 1795 var thisInstance = this; 1796 var formElement = this.getForm(); 1797 var addressMapping = this.addressFieldsMappingInModule; 1798 if(swapMode == "false"){ 1799 for(var key in addressMapping) { 1800 var fromElement = formElement.find('[name="'+key+'"]'); 1801 var toElement = formElement.find('[name="'+addressMapping[key]+'"]'); 1802 toElement.val(fromElement.val()); 1803 } 1804 } else if(swapMode){ 1805 var swappedArray = thisInstance.swapObject(addressMapping); 1806 for(var key in swappedArray) { 1807 var fromElement = formElement.find('[name="'+key+'"]'); 1808 var toElement = formElement.find('[name="'+swappedArray[key]+'"]'); 1809 toElement.val(fromElement.val()); 1810 } 1811 toElement.val(fromElement.val()); 1812 } 1813 }, 1814 1815 /** 1816 * Function to register event for copying addresses 1817 */ 1818 registerEventForCopyAddress : function(){ 1819 var thisInstance = this; 1820 var formElement = this.getForm(); 1821 jQuery('[name="copyAddressFromRight"],[name="copyAddressFromLeft"]').change(function(){ 1822 var element = jQuery(this); 1823 var elementClass = element.attr('class'); 1824 var targetCopyAddress = element.data('copyAddress'); 1825 var objectToMapAddress; 1826 if(elementClass == "accountAddress"){ 1827 var recordRelativeAccountId = jQuery('[name="account_id"]').val(); 1828 if(recordRelativeAccountId == "" || recordRelativeAccountId == "0"){ 1829 Vtiger_Helper_Js.showPnotify(app.vtranslate('JS_PLEASE_SELECT_AN_ACCOUNT_TO_COPY_ADDRESS')); 1830 } else { 1831 var recordRelativeAccountName = jQuery('#account_id_display').val(); 1832 var data = { 1833 'record' : recordRelativeAccountId, 1834 'selectedName' : recordRelativeAccountName, 1835 'source_module': "Accounts" 1836 } 1837 if(targetCopyAddress == "billing"){ 1838 objectToMapAddress = thisInstance.addressFieldsMappingBetweenModules['AccountsBillMap']; 1839 } else if(targetCopyAddress == "shipping"){ 1840 objectToMapAddress = thisInstance.addressFieldsMappingBetweenModules['AccountsShipMap']; 1841 } 1842 thisInstance.copyAddressDetails(data,element.closest('table'),objectToMapAddress); 1843 element.attr('checked','checked'); 1844 } 1845 }else if(elementClass == "contactAddress"){ 1846 var recordRelativeContactId = jQuery('[name="contact_id"]').val(); 1847 if(recordRelativeContactId == "" || recordRelativeContactId == "0"){ 1848 Vtiger_Helper_Js.showPnotify(app.vtranslate('JS_PLEASE_SELECT_AN_CONTACT_TO_COPY_ADDRESS')); 1849 } else { 1850 var recordRelativeContactName = jQuery('#contact_id_display').val(); 1851 var data = { 1852 'record' : recordRelativeContactId, 1853 'selectedName' : recordRelativeContactName, 1854 source_module: "Contacts" 1855 } 1856 if(targetCopyAddress == "billing"){ 1857 objectToMapAddress = thisInstance.addressFieldsMappingBetweenModules['ContactsBillMap']; 1858 } else if(targetCopyAddress == "shipping"){ 1859 objectToMapAddress = thisInstance.addressFieldsMappingBetweenModules['ContactsShipMap']; 1860 } 1861 thisInstance.copyAddressDetails(data,element.closest('table'),objectToMapAddress); 1862 element.attr('checked','checked'); 1863 } 1864 } else if(elementClass == "shippingAddress"){ 1865 var target = element.data('target'); 1866 if(target == "shipping"){ 1867 var swapMode = "true"; 1868 } 1869 thisInstance.copyAddress(swapMode); 1870 } else if(elementClass == "billingAddress"){ 1871 var target = element.data('target'); 1872 if(target == "billing"){ 1873 var swapMode = "false"; 1874 } 1875 thisInstance.copyAddress(swapMode); 1876 } 1877 }) 1878 jQuery('[name="copyAddress"]').on('click',function(e){ 1879 var element = jQuery(e.currentTarget); 1880 var swapMode; 1881 var target = element.data('target'); 1882 if(target == "billing"){ 1883 swapMode = "false"; 1884 }else if(target == "shipping"){ 1885 swapMode = "true"; 1886 } 1887 thisInstance.copyAddress(swapMode); 1888 }) 1889 }, 1890 1891 /** 1892 * Function to toggle shipping and billing address according to layout 1893 */ 1894 registerForTogglingBillingandShippingAddress : function(){ 1895 var billingAddressPosition = jQuery('[name="bill_street"]').closest('td').index(); 1896 var copyAddress1Block = jQuery('[name="copyAddress1"]'); 1897 var copyAddress2Block = jQuery('[name="copyAddress2"]'); 1898 var copyHeader1 = jQuery('[name="copyHeader1"]'); 1899 var copyHeader2 = jQuery('[name="copyHeader2"]'); 1900 var copyAddress1toggleAddressLeftContainer = copyAddress1Block.find('[name="togglingAddressContainerLeft"]'); 1901 var copyAddress1toggleAddressRightContainer = copyAddress1Block.find('[name="togglingAddressContainerRight"]'); 1902 var copyAddress2toggleAddressLeftContainer = copyAddress2Block.find('[name="togglingAddressContainerLeft"]') 1903 var copyAddress2toggleAddressRightContainer = copyAddress2Block.find('[name="togglingAddressContainerRight"]'); 1904 var headerText1 = copyHeader1.html(); 1905 var headerText2 = copyHeader2.html(); 1906 1907 if(billingAddressPosition == 3){ 1908 if(copyAddress1toggleAddressLeftContainer.hasClass('hide')){ 1909 copyAddress1toggleAddressLeftContainer.removeClass('hide'); 1910 } 1911 copyAddress1toggleAddressRightContainer.addClass('hide'); 1912 if(copyAddress2toggleAddressRightContainer.hasClass('hide')){ 1913 copyAddress2toggleAddressRightContainer.removeClass('hide'); 1914 } 1915 copyAddress2toggleAddressLeftContainer.addClass('hide'); 1916 copyHeader1.html(headerText2); 1917 copyHeader2.html(headerText1); 1918 copyAddress1Block.find('[data-copy-address]').each(function(){ 1919 jQuery(this).data('copyAddress','shipping'); 1920 }) 1921 copyAddress2Block.find('[data-copy-address]').each(function(){ 1922 jQuery(this).data('copyAddress','billing'); 1923 }) 1924 } 1925 }, 1926 1927 /** 1928 * Function to check for relation operation 1929 * if relation exist calculation should happen by default 1930 */ 1931 registerForRealtionOperation : function(){ 1932 var form = this.getForm(); 1933 var relationExist = form.find('[name="relationOperation"]').val(); 1934 if(relationExist){ 1935 jQuery('.qty').trigger('focusout'); 1936 } 1937 }, 1938 1939 //Related to preTaxTotal Field 1940 1941 /** 1942 * Function to set the pre tax total 1943 */ 1944 setPreTaxTotal : function(preTaxTotalValue){ 1945 jQuery('#preTaxTotal').text(preTaxTotalValue); 1946 return this; 1947 }, 1948 1949 /** 1950 * Function to get the pre tax total 1951 */ 1952 getPreTaxTotal : function() { 1953 return parseFloat(jQuery('#preTaxTotal').text()); 1954 }, 1955 1956 /** 1957 * Function to calculate the preTaxTotal value 1958 */ 1959 calculatePreTaxTotal : function() { 1960 var numberOfDecimal = parseInt(jQuery('.numberOfCurrencyDecimal').val()); 1961 var netTotal = this.getNetTotal(); 1962 var shippingHandlingCharge = this.getShippingAndHandling(); 1963 var finalDiscountValue = this.getFinalDiscountTotal(); 1964 var preTaxTotal = netTotal+shippingHandlingCharge-finalDiscountValue; 1965 var preTaxTotalValue = parseFloat(preTaxTotal).toFixed(numberOfDecimal); 1966 this.setPreTaxTotal(preTaxTotalValue); 1967 }, 1968 1969 /** 1970 * Function to save the pre tax total value 1971 */ 1972 savePreTaxTotalValue : function() { 1973 jQuery('#pre_tax_total').val(this.getPreTaxTotal()); 1974 }, 1975 1976 /** 1977 * Function which will register all the events 1978 */ 1979 registerBasicEvents : function(container) { 1980 this._super(container); 1981 this.registerReferenceSelectionEvent(container); 1982 }, 1983 1984 registerEvents: function(){ 1985 this._super(); 1986 this.registerAddingNewProductsAndServices(); 1987 this.lineItemActions(); 1988 this.lineItemResultActions(); 1989 //TODO : this might be costier operation. This we added to calculate tax for each line item 1990 this.makeLineItemsSortable(); 1991 this.checkLineItemRow(); 1992 this.registerForRealtionOperation(); 1993 } 1994 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |