1$(document).ready(function() { 2 3 goodList = s360.NSCA.GoodList.get(); 4 laborList = s360.NSCA.LaborList.get(); 5 employeeList = s360.NSCA.EmployeeList.get(); 6 unallocatedHoursList = s360.NSCA.UnallocatedHoursList.get(); 7 workCalendarList = s360.NSCA.WorkCalendarList.get(); 8 summary = s360.NSCA.Summary.get(); 9 10 11 12 goodList.calculationsCompleteSignal.add(s360.NSCA.Summary.calculateAndUpdateAll); 13 14 goodList.childAddedSignal 15 .add(s360.NSCA.Summary.goodItemAdd) 16 goodList.childRemovedSignal 17 .add(s360.NSCA.Summary.goodItemRemove) 18 19 20 21 laborList.calculationsCompleteSignal.add(s360.NSCA.Summary.calculateAndUpdateAll); 22 23 var listensToLaborList = ['SkillList','UnallocatedHoursList','Summary']; 24 25 _.each(listensToLaborList, function(listeningObject){ 26 laborList.childAddedSignal.add(s360.NSCA[listeningObject].laborItemAdd); 27 laborList.childRemovedSignal.add(s360.NSCA[listeningObject].laborItemRemove); 28 }); 29 30 //When a labor item name changes I need to update that value in the calendars 31 //laborList.childValuesUpdatedSignal.add(workCalendarList.titlesUpdate.bind(workCalendarList)); 32 33 //When I add an employee I need to add their calendar 34 employeeList.childAddedSignal 35 .add(s360.NSCA.WorkCalendarList.employeeAdd) 36 employeeList.childRemovedSignal 37 .add(s360.NSCA.WorkCalendarList.employeeRemove) 38 employeeList.childValuesUpdatedSignal 39 .add(laborList.calculateLaborCost.bind(laborList)) 40 41 42 workCalendarList.childValuesUpdatedSignal 43 .add(laborList.calculateLaborCost.bind(laborList)) 44 workCalendarList.childValuesUpdatedSignal 45 .add(s360.NSCA.UnallocatedHoursList.recalculate); 46 47 48 49 50 51 goodList.default(); 52 laborList.default(); 53 employeeList.default(); 54 //unallocatedHoursList.default(); 55 //Temporary to get it to the bottom of the list 56 //window.scrollTo(0,2000); 57 58 $(".fieldInfo").tooltip({ 59 show: { 60 effect: "slideDown", 61 delay: 250 62 } 63 }); 64 65 // jprice 2024-08-07 this initializes the main tab for proper navigation so it doesn't get "stuck" 66 $("a[href='#step1']").tab('show'); 67 68 intro = introJs(); 69 70 intro.goToStep = function(step) { 71 /* this fixes some dumb problem occuring in library. */ 72 this._currentStep = step - 1; 73 return this; 74 } 75 76 intro.setOptions({ 77 steps: [ 78 { 79 intro: "<h3>Welcome to the NSCA Project Contribution Calculator!</h3><hr/>\ 80This tutorial will run through the calculator to give you a quick overview on how to do project costing! You can cancel the tutorial by clicking outside of this popup and continue again by clicking on the small ? next to the page headers." 81 } 82 ,{ 83 intro: "This calculator uses material, labor and other hidden costs to generate a profitable quote." 84 } 85 ,{ 86 element:'.s360GoodItem' 87 ,intro: "Here you can insert, edit and remove goods that apply to your project. The markup percentage will be used later to determine how much to charge for these materials." 88 } 89 ,{ 90 element:'.s360LaborItem' 91 ,intro: "The same can be done with labor items, but labor items will be calculated by the cost of the employees assigned to doing them (Steps 2 and 3)" 92 } 93 ,{ 94 element: '.childAdd' 95 ,intro: 'For both Goods and Labor you can add and remove line items' 96 } 97 ,{ 98 element: '.delete' 99 ,intro: "Remove here" 100 } 101 ,{ 102 element: '.tabButtons' 103 ,intro: "You can go directly to any step by using these tabs, but Step 4 won't give you proper calculations until you've filled out Steps 1 - 3" 104 } 105 ,{ 106 element: '.next' 107 ,intro: "The forward and back buttons will move you between steps" 108 ,position: "left" 109 } 110 ,{ 111 element: '.skillList' 112 ,intro: 'On this page you can define employees and what skills they have. Skills become important as you cannot assign labor hours of that type to employees who do not have that skill.' 113 } 114 ,{ 115 element: ".employeeDetails > div > span:nth-child(1) > div" 116 ,intro: 'This section allows you to input the various costs of an employee, use the rates that are applicable for your state/province/region' 117 ,position: "left" 118 } 119 ,{ 120 element: ".employeeDetails > div > span:nth-child(2) > div" 121 ,intro: 'The section allows you to input and calculate various details with regards to your employees labor rate' 122 ,position: "left" 123 } 124 ,{ 125 element: ".calc1" 126 ,intro: "This labor utilization rate is calculated by looking at the ratio of unbillable to billable hours you've allocated in step 3" 127 } 128 , { 129 element: ".calc2" 130 ,intro: "You can override this rate by unchecking the 'Use Calculated Rate' option or simply by entering a manual utilization rate. Do this if you've already worked out your employee's labor utilization rate over a long period of time" 131 } 132 ,{ 133 element: ".s360WorkCalendarEmployee > span" 134 ,intro: "The employee work calendar looks at the skills you've given an employee and allows you to allocate hours of work to them, the Calculated Labor Utilization is determined by the ratio of unbillable to billable hours." 135 } 136 ,{ 137 element: ".s360-NSCA-UnallocatedHoursItem > span" 138 ,intro: "When adding or removing hours, the total allocated to a particular labor will appear here. Once you've allocated the correct number of hours this will turn green. If all of the labor hours aren't properly allocated the calculations on Step 4 will not be accurate." 139 } 140 ,{ 141 element: ".s360Summary > div" 142 ,intro: "On this page we take all of the information you've given us and use it to calculate the final project contribution" 143 ,position: "top" 144 } 145 ,{ 146 element: ".laborTallyHelpAnchor" 147 ,intro: "Keep in mind that labor costs are based on which employee you've allocated hours to, and won't be accurate until you've properly allocated your hours (Step 3)" 148 } 149 ,{ 150 element: ".pc1" 151 ,intro: "When finished your final project contribution will appear here, unless you enter a discount ... in which case a discount section will appear" 152 } 153 ,{ 154 element: ".jumpToStep" 155 ,intro: "If at any point you need a refresher on what a page does, click this question mark" 156 } 157 158 159 ] 160 ,showStepNumbers: false 161 });
162 163 164 165 intro.onchange(function(targetElement) { 166 167 if ($(targetElement).hasClass('tab-pane')) { 168 var theElementId = $(targetElement).attr('id'); 169 $("a[href='#" + theElementId + "']").tab('show'); 170 } else if ( $(targetElement).parents('.tab-pane').length > 0 ) { 171 var theElementId = $(targetElement).parents('.tab-pane').attr('id'); 172 $("a[href='#" + theElementId + "']").tab('show'); 173 } 174 refreshNavButtons(); 175 }); 176 177 $("#intro").on('click', function(){ 178 intro.start(); 179 }); 180 181 $(".jumpToStep").on("click", function(e){ 182 e.preventDefault(); 183 if (_.isUndefined(intro._currentStep)) { 184 var theStep = $(this).attr("data-step"); 185 intro.goToStep(theStep).start(); 186 } 187 }) 188 189 $('.tabButtons a').on('click', function(e){ 190 e.preventDefault(); 191 var currentActiveTab = $('.tabButtons .active a') 192 193 $(this).tab('show'); 194 195 currentActiveTab.removeClass('active') 196 currentActiveTab.parent().removeClass('active') 197 198 $(this).addClass('active') 199 $(this).parent().addClass('active') 200 201 refreshNavButtons(); 202 }); 203 204 $('.stepNav a').on('click', function(e){ 205 e.preventDefault(); 206 var currentActiveTab = $('.tabButtons .active a') 207 var currentActiveTabID = currentActiveTab.attr('href'); 208 var stepNumber = parseInt(accounting.format(currentActiveTabID)); 209 210 var next = $(this).hasClass("next") //boolean - if true: next | if false: previous 211 212 var newStep = next ? stepNumber + 1 : stepNumber - 1; 213 var newActiveTabID = "#step" + newStep 214 215 var newActiveTab = $("a[href='#step" + newStep + "']") 216 217 //if (next) { 218 if ( !$(this).hasClass("disable") ) { 219 newActiveTab.tab('show'); 220 currentActiveTab.removeClass('active') 221 currentActiveTab.parent().removeClass('active') 222 newActiveTab.parent().addClass('active') 223 newActiveTab.addClass('active') 224 } 225 //} else { 226 227 //if ( !$(this).hasClass("disable") ) { 228 //$("a[href='#step" + newStep + "']").tab('show'); 229 //} 230 //} 231 232 refreshNavButtons(); 233 }); 234 235 236//And skip to tab2 for now 237//intro.start(); 238// var skills = employeeList.childComponentsGet()[0].skillList.childComponentsGet(); 239// _.invoke(skills,"hasSkillSet",true); 240// $("a[href='#step3']").tab('show'); 241}); 242 243function refreshNavButtons() { 244var activeTabID = $('.tabButtons .active a').attr('href'); 245var stepNumber = parseInt(accounting.format(activeTabID)); 246 247if (stepNumber <= 1) { 248$('.stepNav .previous').addClass("disable"); 249} else { 250$('.stepNav .previous').removeClass("disable"); 251} 252 253if (stepNumber >= _.size( $('.tabButtons li') ) ) { 254$('.stepNav .next').addClass("disable"); 255} else { 256$('.stepNav .next').removeClass("disable"); 257} 258}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.