Guest User

Untitled

a guest
Sep 25th, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.50 KB | None | 0 0
  1. import _ from 'lodash';
  2.  
  3. /**
  4. * Declare our private methods
  5. * @type {symbol}
  6. */
  7. const replaceVariables = Symbol( 'replaceVariables' );
  8. const replaceOptions = Symbol( 'replaceOptions' );
  9. const replaceTakeoffs = Symbol( 'replaceTakeoffs' );
  10. const configureClass = Symbol( 'configureClass' );
  11.  
  12. class CalculationSolver{
  13.  
  14. constructor(){
  15. this[ configureClass ]();
  16. }
  17.  
  18. [ configureClass ](){
  19. this.debug = false;
  20. this.processSell = false;
  21. this.markup = 0;
  22. this.commission = 0;
  23. this.tax = 0;
  24. this.variables = {};
  25. this.takeoffs = {};
  26. this.options = {};
  27. this.material = false;
  28. this.calculation = "";
  29. this.material_cost = {
  30. original: 0,
  31. price: 0,
  32. tax: 0,
  33. commission: 0,
  34. markup: 0,
  35. };
  36. this.result = 0;
  37. this.is_removal = false;
  38.  
  39. window.roundup = function( number, place = 0 ){
  40.  
  41. let power = Math.pow( 10, place );
  42.  
  43. return Math.ceil( number * power ) / power;
  44.  
  45. };
  46.  
  47. window.rounddown = function( number, place = 0 ){
  48. let power = Math.pow( 10, place );
  49. return Math.floor( number * power ) / power;
  50. };
  51. }
  52.  
  53. //-- These are our setters
  54.  
  55. /**
  56. * Enable or Disable Debug (Printed to console)
  57. * @param value
  58. */
  59. setDebug( value = false ){
  60. this.debug = value;
  61. }
  62.  
  63. setIsRemoval( value ){
  64. this.is_removal = value;
  65. }
  66.  
  67. /**
  68. * Tell the parse if it is going to process markup/commision/tax
  69. * @param value
  70. */
  71. setProcessSell( value = false ){
  72. this.processSell = value;
  73. }
  74.  
  75. /**
  76. * This will set the markup's value (normally something like 0.1 *10%*)
  77. * @param value
  78. */
  79. setMarkup( value ){
  80. this.markup = value;
  81. }
  82.  
  83. /**
  84. * This will set the commission value (normally something like 0.1 *10%*)
  85. * @param value
  86. */
  87. setCommission( value ){
  88. this.commission = value;
  89. }
  90.  
  91. /**
  92. * This will set the tax rate of the system.
  93. * @param value
  94. */
  95. setTax( value ){
  96. this.tax = value;
  97. }
  98.  
  99. /**
  100. * Set the variables object ({variable_id:parsed_calculation})
  101. * @param variables
  102. */
  103. setVariables( variables ){
  104. this.variables = variables;
  105. }
  106.  
  107. /**
  108. * Set the takeoffs {takeoff_id: value}
  109. * @param takeoffs
  110. */
  111. setTakeoffs( takeoffs ){
  112. this.takeoffs = takeoffs;
  113. }
  114.  
  115. /**
  116. * Set the options {option_id: quantity}
  117. * @param options
  118. */
  119. setOptions( options ){
  120. this.options = options;
  121. }
  122.  
  123. /**
  124. * Sets the calculations material (if one exists... this is up to the user
  125. * @param material
  126. */
  127. setMaterial( material ){
  128.  
  129. this.material = material;
  130.  
  131. }
  132.  
  133. /**
  134. * Set the calculation
  135. * @param calculation
  136. */
  137. setCalculation( calculation ){
  138. this.calculation = calculation;
  139. }
  140.  
  141. //--Actions
  142. processCalculation(){
  143. let breakout = 1;
  144. while( this.calculation.includes( "{{" ) && breakout < 101 ){
  145.  
  146. if( this.debug ){
  147. console.log( "Starting Run #" + breakout );
  148. console.log( "Calculation before variable replacement", this.calculation );
  149. }
  150. this.calculation = this[ replaceVariables ]( this.calculation );
  151.  
  152. if( this.debug ){
  153. console.log( "Calculation after variable replacement", this.calculation );
  154. console.log( "Calculation before takeoff replacement", this.calculation );
  155. }
  156. this.calculation = this[ replaceTakeoffs ]( this.calculation );
  157. if( this.debug ){
  158. console.log( "Calculation after takeoff replacement", this.calculation );
  159. console.log( "Calculation before option replacement", this.calculation );
  160. }
  161. this.calculation = this[ replaceOptions ]( this.calculation );
  162.  
  163. this.calculation = this.calculation.replace( /<brcontenteditable="false">/g, "" );
  164.  
  165. if( this.debug ){
  166. console.log( "Calculation after option replacement", this.calculation );
  167. console.log( "Ending Run #" + breakout );
  168. console.log( "Calculation at end of run:", this.calculation );
  169. }
  170. breakout++;
  171.  
  172. //Sometimes we have //<brcontenteditable="false">// and we need to kill it.
  173. }
  174.  
  175. if( this.calculation && this.calculation !== '' ){
  176.  
  177. try{
  178. let parser = new Function( 'calculation', 'return eval(calculation)' );
  179. this.result = parser( this.calculation );
  180. }
  181. catch( e ){
  182. console.warn( e );
  183. console.error( this.calculation, 'This calculation could not be parsed properly' );
  184. this.result = 0;
  185. }
  186. }
  187. if( this.is_removal ){
  188. this.result *= -1;
  189. }
  190. return this.result;
  191. }
  192.  
  193. processComplexResults(){
  194.  
  195. let result = {
  196. quantity: this.result,
  197. cost: this.material_cost.original / 100,
  198. total_cost: ( this.material_cost.original / 100 ) * this.result,
  199. tax: ( this.material_cost.tax / 100 ) * this.result,
  200. mark_up: ( this.material_cost.markup / 100 ) * this.result,
  201. commission: ( this.material_cost.commission / 100 ) * this.result,
  202. };
  203.  
  204. result.up_charge_total = result.tax + result.commission + result.mark_up;
  205. result.total_sell_price = result.up_charge_total + result.total_cost;
  206.  
  207. return result;
  208. }
  209.  
  210. configureMaterialCosts(){
  211.  
  212. this.material_cost.original = parseInt( this.material.price.amount );
  213. let base = this.material_cost.original;
  214. //We need to handle each markup type
  215. switch( parseInt( this.material.material_type_id ) ){
  216. case 1:
  217. //We first do the tax
  218. this.material_cost.calculated_tax = this.material_cost.original * this.tax;
  219. this.material_cost.tax += this.material_cost.calculated_tax;
  220. base += this.material_cost.calculated_tax;
  221.  
  222. //Next comes the markup
  223. this.material_cost.calculated_markup = base * this.markup;
  224. this.material_cost.markup += this.material_cost.calculated_markup;
  225. this.material_cost.price += this.material_cost.calculated_markup;
  226. base += this.material_cost.calculated_markup;
  227.  
  228. //Finally We deal with commission
  229. this.material_cost.calculated_commission = base * this.commission;
  230. this.material_cost.commission += this.material_cost.calculated_commission;
  231. base += this.material_cost.calculated_commission;
  232.  
  233. if( this.debug ){
  234. console.log( "Adding in the required material costs", this.material_cost );
  235. }
  236.  
  237. break;
  238. case 2:
  239. //First We will with the Markup
  240. this.material_cost.calculated_markup = base * this.markup;
  241. this.material_cost.markup += this.material_cost.calculated_markup;
  242. this.material_cost.price += this.material_cost.calculated_markup;
  243. base += this.material_cost.calculated_markup;
  244.  
  245. //We take tax after markup
  246. this.material_cost.calculated_tax = this.material_cost.original * this.tax;
  247. this.material_cost.tax += this.material_cost.calculated_tax;
  248. base += this.material_cost.calculated_tax;
  249.  
  250. //Last we deal with commission
  251. this.material_cost.calculated_commission = base * this.commission;
  252. this.material_cost.commission += this.material_cost.calculated_commission;
  253. base += this.material_cost.calculated_commission;
  254.  
  255. if( this.debug ){
  256. console.log( "Adding in the required material costs", this.material_cost );
  257. }
  258.  
  259. break;
  260. case 3:
  261. default:
  262. //First comes markup
  263. this.material_cost.calculated_markup = base * this.markup;
  264. this.material_cost.markup += this.material_cost.calculated_markup;
  265. this.material_cost.price += this.material_cost.calculated_markup;
  266. base += this.material_cost.calculated_markup;
  267.  
  268. //Next is commission
  269. this.material_cost.calculated_commission = base * this.commission;
  270. this.material_cost.commission += this.material_cost.calculated_commission;
  271. base += this.material_cost.calculated_commission;
  272.  
  273. if( this.debug ){
  274. console.log( "Adding in the required material costs", this.material_cost );
  275. }
  276.  
  277. //We do NOT take tax here...
  278. break;
  279. }
  280.  
  281. this.material_cost.price = base;
  282. if( this.debug ){
  283. console.log( this.material_cost );
  284. }
  285.  
  286. }
  287.  
  288. //Private Helpers
  289. [ replaceVariables ]( calculation ){
  290. let matches = [ ...new Set( calculation.match( /{{variables\.[0-9]+}}/gm ) ) ];
  291.  
  292. if( matches ){
  293. matches.forEach( match => {
  294.  
  295. let match_id = parseInt( match.replace( "{{variables.", "" ).replace( "}}", "" ) );
  296.  
  297. let replacement = 0;
  298. if( this.variables[ match_id ] ){
  299. replacement = this.variables[ match_id ];
  300. }
  301.  
  302. let regex_replacement = new RegExp( match, "g" );
  303. calculation = calculation.replace( regex_replacement, replacement );
  304. } );
  305. }
  306.  
  307. return calculation;
  308. }
  309.  
  310. [ replaceOptions ]( calculation ){
  311. let matches = [ ...new Set( calculation.match( /{{selected_options\.[0-9]+}}/gm ) ) ];
  312. if( matches ){
  313.  
  314. matches.forEach( match => {
  315. // console.log( this.option.name + ' has selected options' );
  316. let match_id = parseInt( match.replace( "{{selected_options.", "" ).replace( "}}", "" ) );
  317.  
  318. let replacement = 0;
  319. if( this.options[ match_id ] ){
  320. replacement = this.options[ match_id ];
  321. }
  322.  
  323. let regex_replacement = new RegExp( match, "g" );
  324. calculation = calculation.replace( regex_replacement, replacement );
  325. } );
  326. }
  327. return calculation;
  328. }
  329.  
  330. [ replaceTakeoffs ]( calculation ){
  331. let matches = [ ...new Set( calculation.match( /{{takeoffs\.[0-9]+}}/gm ) ) ];
  332. if( matches ){
  333. matches.forEach( match => {
  334.  
  335. let match_id = parseInt( match.replace( "{{takeoffs.", "" ).replace( "}}", "" ) );
  336.  
  337. let replacement = 0;
  338. if( this.takeoffs[ match_id ] ){
  339. replacement = parseInt( this.takeoffs[ match_id ] );
  340. }
  341.  
  342. let regex_replacement = new RegExp( match, "g" );
  343. calculation = calculation.replace( regex_replacement, replacement );
  344. } );
  345. }
  346. return calculation;
  347. }
  348.  
  349.  
  350. showClass(){
  351.  
  352. let table = {
  353.  
  354. 'Debug': this.debug,
  355. 'Process Sell': this.processSell,
  356. 'Mark Up': this.markup,
  357. 'Commission': this.commission,
  358. 'Tax': this.tax,
  359. 'Variables': this.variables,
  360. 'Options': this.options,
  361. 'Takeoffs': this.takeoffs,
  362. "Material": this.material,
  363.  
  364. };
  365.  
  366. console.table( table );
  367.  
  368. }
  369. }
  370.  
  371. export default CalculationSolver;
Add Comment
Please, Sign In to add comment