fork(1) download
  1. /**
  2. * @name QuoteDocumentWrapper2
  3. * @description Quote Document Wrapper class for Quote with all columns and school Summary grouped by SchoolProduct FamilySegment
  4. **/
  5. public class QuoteDocumentWrapper2 {
  6. private static String IMPLEMENTATION_PHASE = 'Implementation Phase';
  7. private static Boolean IS_STUB_INDEX = false;
  8. private static Set<String> quoteIncludesFamily = new Set<String>();
  9. private static Set<Id> schoolIdSet = new Set<Id>();
  10.  
  11. public class QuoteOutput {
  12. public String quoteProductFamily;
  13. public Integer schoolCount;
  14. public List<SchoolOutputWrapper> schools;
  15. }
  16.  
  17. public class SchoolOutputWrapper {
  18. public String name;
  19. public Decimal subListAmount = 0.0;
  20. public Decimal subTotalDiscount = 0.0;
  21. public Decimal subTotalAmount = 0.0;
  22. public List<ProductFamilyOutputWrapper> productFamilies;
  23. public Boolean hasDiscount = false;
  24. public Boolean isNegativeSubTotalAmount = false;
  25.  
  26. public SchoolOutputWrapper(
  27. String Name,
  28. Decimal SubListAmount,
  29. Decimal SubTotalDiscount,
  30. Decimal SubTotalAmount,
  31. List<ProductFamilyOutputWrapper> productFamilies
  32. ) {
  33. this.Name = Name;
  34. this.SubListAmount = SubListAmount;
  35. this.SubTotalAmount = SubTotalAmount;
  36. this.SubTotalDiscount = SubTotalDiscount;
  37. this.productFamilies = productFamilies;
  38. this.isNegativeSubTotalAmount = SubTotalAmount < 0;
  39. }
  40. }
  41.  
  42. public class ProductFamilyOutputWrapper {
  43. public String name;
  44. public Decimal subTotalAmount = 0.0;
  45. public Decimal subTotalDiscount = 0.0;
  46. public Decimal quantity = 0;
  47. public List<SegmentOutputWrapper> segments;
  48. public Boolean hasDiscount = false;
  49. public Boolean isNegativeSubTotalAmount = false;
  50.  
  51. public ProductFamilyOutputWrapper(
  52. String name,
  53. Decimal subTotalAmount,
  54. Decimal subTotalDiscount,
  55. Decimal quantity,
  56. List<SegmentOutputWrapper> segments
  57. ) {
  58. this.name = name;
  59. this.subTotalAmount = subTotalAmount;
  60. this.subTotalDiscount = subTotalDiscount;
  61. this.quantity = quantity;
  62. this.segments = segments;
  63. this.hasDiscount = subTotalDiscount != 0;
  64. this.isNegativeSubTotalAmount = subTotalAmount < 0;
  65. }
  66. }
  67.  
  68. public class SegmentOutputWrapper implements Comparable {
  69. public String segmentIndex;
  70. public Boolean additionalPhase;
  71. public Decimal subTotalAmount = 0.0;
  72. public Decimal subTotalDiscount = 0.0;
  73. public Decimal quantity = 0;
  74. public String effectiveEndDate;
  75. public String effectiveStartDate;
  76. public List<ProductOutput> products;
  77. public Boolean hasDiscount = false;
  78. public Boolean isNegativeSubTotalAmount = false;
  79. public String cqlStartDate;
  80. public String cqlEndDate;
  81.  
  82. public SegmentOutputWrapper(
  83. String segmentIndex,
  84. Decimal subTotalAmount,
  85. Decimal subTotalDiscount,
  86. Decimal quantity,
  87. String effectiveEndDate,
  88. String effectiveStartDate,
  89. String cqlStartDate,
  90. String cqlEndDate,
  91. List<ProductOutput> products
  92. ) {
  93. this.segmentIndex = IS_STUB_INDEX == true && segmentIndex.isNumeric()
  94. ? String.valueOf(Integer.valueOf(segmentIndex) + 1)
  95. : segmentIndex;
  96. this.additionalPhase = segmentIndex == IMPLEMENTATION_PHASE;
  97. this.subTotalAmount = subTotalAmount;
  98. this.subTotalDiscount = subTotalDiscount;
  99. this.quantity = quantity;
  100. this.effectiveEndDate = effectiveEndDate;
  101. this.effectiveStartDate = effectiveStartDate;
  102. this.products = products;
  103. this.hasDiscount = subTotalDiscount != 0;
  104. this.isNegativeSubTotalAmount = subTotalAmount < 0;
  105. }
  106.  
  107. public Integer compareTo(Object obj) {
  108. SegmentOutputWrapper that = (SegmentOutputWrapper) obj;
  109. if (this.segmentIndex == IMPLEMENTATION_PHASE) {
  110. return -1;
  111. } else if (that.segmentIndex == IMPLEMENTATION_PHASE) {
  112. return 1;
  113. } else {
  114. return Integer.valueOf(this.segmentIndex) -
  115. Integer.valueOf(that.segmentIndex);
  116. }
  117. }
  118. }
  119.  
  120. public class SchoolOutput {
  121. public String Name;
  122. public Decimal SubListAmount = 0.0;
  123. public Decimal SubTotalDiscount = 0.0;
  124. public Decimal SubTotalAmount = 0.0;
  125. public Map<String, ProductFamilyOutput> productFamilies;
  126. public Boolean hasDiscount = false;
  127.  
  128. public SchoolOutput(
  129. String Name,
  130. Decimal SubListAmount,
  131. Decimal SubTotalDiscount,
  132. Decimal SubTotalAmount,
  133. Map<String, ProductFamilyOutput> productFamilies
  134. ) {
  135. this.Name = Name;
  136. this.SubListAmount = SubListAmount;
  137. this.SubTotalAmount = SubTotalAmount;
  138. this.SubTotalDiscount = SubTotalDiscount;
  139. this.productFamilies = productFamilies;
  140. }
  141. }
  142.  
  143. public class ProductFamilyOutput {
  144. public String name;
  145. public Decimal subTotalAmount = 0.0;
  146. public Decimal subTotalDiscount = 0.0;
  147. public Decimal quantity = 0;
  148. public Map<String, SegmentOutput> segments;
  149. public Boolean hasDiscount = false;
  150.  
  151. public ProductFamilyOutput(
  152. String name,
  153. Decimal subTotalAmount,
  154. Decimal subTotalDiscount,
  155. Decimal quantity,
  156. Map<String, SegmentOutput> segments
  157. ) {
  158. this.name = name;
  159. this.subTotalAmount = subTotalAmount;
  160. this.subTotalDiscount = subTotalDiscount;
  161. this.quantity = quantity;
  162. this.segments = segments;
  163. this.hasDiscount = subTotalDiscount != 0;
  164. }
  165. }
  166.  
  167. public class SegmentOutput {
  168. public String segmentIndex;
  169. public Boolean additionalPhase;
  170. public Decimal subTotalAmount = 0.0;
  171. public Decimal subTotalDiscount = 0.0;
  172. public Decimal quantity = 0;
  173. public String effectiveEndDate;
  174. public String effectiveStartDate;
  175. public String cqlStartDate;
  176. public String cqlEndDate;
  177. public List<ProductOutput> products;
  178. public Boolean hasDiscount = false;
  179.  
  180. public SegmentOutput(
  181. String segmentIndex,
  182. Decimal subTotalAmount,
  183. Decimal subTotalDiscount,
  184. Decimal quantity,
  185. String effectiveEndDate,
  186. String effectiveStartDate,
  187. String cqlStartDate,
  188. String cqlEndDate,
  189. List<ProductOutput> products
  190. ) {
  191. this.segmentIndex = segmentIndex;
  192. this.additionalPhase = segmentIndex == IMPLEMENTATION_PHASE;
  193. this.subTotalAmount = subTotalAmount;
  194. this.subTotalDiscount = subTotalDiscount;
  195. this.quantity = quantity;
  196. if (effectiveEndDate == null || effectiveEndDate == '') {
  197. this.effectiveEndDate = effectiveEndDate;
  198. } else {
  199. DateTime dtEffectiveEndDate = Date.valueOf(effectiveEndDate);
  200. this.effectiveEndDate = String.valueOf(
  201. dtEffectiveEndDate.formatGmt('dd-MMM-yyyy')
  202. );
  203. }
  204. this.effectiveStartDate = effectiveStartDate;
  205. DateTime dtEffectiveStartDate = Date.valueOf(effectiveStartDate);
  206. this.effectiveStartDate = String.valueOf(
  207. dtEffectiveStartDate.formatGmt('dd-MMM-yyyy')
  208. );
  209. this.products = products;
  210. this.hasDiscount = subTotalDiscount != 0;
  211. this.cqlStartDate = cqlStartDate;
  212. this.cqlEndDate = cqlStartDate;
  213. }
  214. }
  215.  
  216. public class ProductOutput {
  217. public String name;
  218. public Decimal listPrice;
  219. public Decimal netPrice;
  220. public Decimal discountAmount;
  221. public Decimal netTotal;
  222. public Decimal listTotal;
  223. public Decimal quantity;
  224. public Boolean hasDiscount = false;
  225. public Boolean isNegativeNetTotal = false;
  226. public Boolean isCreditProduct = false;
  227. public String creditUsage = '';
  228. public Boolean hidden;
  229. public Decimal netUnitPrice;
  230. public Decimal totalCost;
  231.  
  232. public ProductOutput(
  233. String name,
  234. Decimal listPrice,
  235. Decimal netPrice,
  236. Decimal discountAmount,
  237. Decimal netTotal,
  238. Decimal listTotal,
  239. Decimal quantity
  240. ) {
  241. this.name = name;
  242. this.listPrice = listPrice;
  243. this.netPrice = netPrice;
  244. this.discountAmount = discountAmount;
  245. this.netTotal = netTotal;
  246. this.listTotal = listTotal;
  247. this.quantity = quantity;
  248. this.hasDiscount = discountAmount != 0;
  249. this.isNegativeNetTotal = netTotal < 0;
  250. }
  251. }
  252.  
  253. public class Quote {
  254. public String name;
  255. public List<QuoteLine> quoteLines;
  256. }
  257.  
  258. public class QuoteLine {
  259. public Integer segmentIndex;
  260. public Decimal quantity;
  261. public Decimal netTotal;
  262. public Decimal listPrice;
  263. public Decimal additionalDiscountAmount;
  264. public String effectiveEndDate;
  265. public String effectiveStartDate;
  266. public Integer effectiveSubscriptionTerm;
  267. public Decimal effectiveQuantity;
  268. public Decimal netPrice;
  269. public Decimal listTotal;
  270. public String creditUsage;
  271. public List<ChildQuoteLine> childQuoteLines;
  272. }
  273.  
  274. public class ChildQuoteLine {
  275. public School school;
  276. public Decimal effectiveQuantity;
  277. public Id childQuoteLineId;
  278. public Product product;
  279. public Integer SegmentIndex;
  280. public Boolean hidden;
  281. public Decimal netUnitPrice;
  282. public Decimal totalCost;
  283. public String cqlEndDate;
  284. public String cqlStartDate;
  285. }
  286.  
  287. public class Product {
  288. public String name;
  289. public String family;
  290. public String quoteIncludesFamily;
  291. public String subscriptionPricing;
  292. public String productCategory;
  293. }
  294.  
  295. public class School {
  296. public String name;
  297. public String schoolId;
  298. }
  299.  
  300. /**
  301. * @description Method to create the document data to be displayed in the quote document
  302. * @param Object arg
  303. * @return QuoteOutput
  304. **/
  305. public QuoteOutput createDocumentData(Object arg) {
  306. List<Quote> quotes = parseQuoteJson(JSON.serialize(arg));
  307. Map<String, SchoolOutput> schoolOutputList = processQuotes(quotes);
  308. List<SchoolOutputWrapper> schoolOutput = convertToNewFormat(
  309. schoolOutputList
  310. );
  311.  
  312. QuoteOutput outputWrapper = new QuoteOutput();
  313. outputWrapper.quoteProductFamily = getQuoteIncludesFamily(
  314. new List<String>(quoteIncludesFamily)
  315. );
  316. outputWrapper.schoolCount = schoolIdSet.size();
  317. outputWrapper.schools = schoolOutput;
  318. return outputWrapper;
  319. }
  320.  
  321. /**
  322. * @description Method to parse the JSON string to Input Wrapper classes
  323. * @param String jsonString
  324. * @return List<Quote>
  325. **/
  326. public static List<Quote> parseQuoteJson(String jsonString) {
  327. List<Quote> result = new List<Quote>();
  328. List<Object> parsed = (List<Object>) JSON.deserializeUntyped(jsonString);
  329.  
  330. for (Object obj : parsed) {
  331. Map<String, Object> quoteRecord = (Map<String, Object>) obj;
  332. Quote quote = new Quote();
  333. quote.name = (String) quoteRecord.get('Name');
  334.  
  335. IMPLEMENTATION_PHASE = (String) quoteRecord.get(
  336. 'OverrideImplementationPhaseText'
  337. ) == null
  338. ? IMPLEMENTATION_PHASE
  339. : (String) quoteRecord.get('OverrideImplementationPhaseText');
  340.  
  341. IS_STUB_INDEX = (Boolean) quoteRecord.get('OverrideNonstubIndex');
  342. Boolean displayUnchangedProducts = (Boolean) quoteRecord.get(
  343. 'Display_Unchanged_Products__c'
  344. );
  345.  
  346. // Deserialize quote lines
  347. List<Object> quoteLines = new List<Object>();
  348. if (quoteRecord.get('QuoteLines') instanceof Map<String, Object>) {
  349. quoteLines.add(quoteRecord.get('QuoteLines'));
  350. } else {
  351. quoteLines = (List<Object>) quoteRecord.get('QuoteLines');
  352. }
  353.  
  354. List<QuoteLine> quoteLineList = new List<QuoteLine>();
  355.  
  356. for (Object quoteLineRecord : quoteLines) {
  357. Map<String, Object> qlwMap = (Map<String, Object>) quoteLineRecord;
  358. if ((Decimal) qlwMap.get('EffectiveQuantity') == 0) {
  359. continue;
  360. }
  361. QuoteLine quoteLine = new QuoteLine();
  362. quoteLine.segmentIndex = (Integer) qlwMap.get('SegmentIndex');
  363. quoteLine.quantity = (Decimal) qlwMap.get('Quantity');
  364. quoteLine.netTotal = (Decimal) qlwMap.get('NetTotal');
  365. quoteLine.listPrice = (Decimal) qlwMap.get('ListPrice');
  366. quoteLine.netPrice = (Decimal) qlwMap.get('NetPrice');
  367. quoteLine.listTotal = (Decimal) qlwMap.get('ListTotal');
  368. quoteLine.effectiveEndDate = (String) qlwMap.get('EffectiveEndDate');
  369. quoteLine.effectiveStartDate = (String) qlwMap.get(
  370. 'EffectiveStartDate'
  371. );
  372. quoteLine.effectiveSubscriptionTerm = (Integer) qlwMap.get(
  373. 'EffectiveSubscriptionTerm'
  374. );
  375. quoteLine.effectiveQuantity = (Decimal) qlwMap.get('EffectiveQuantity');
  376. quoteLine.additionalDiscountAmount = (Decimal) qlwMap.get(
  377. 'AdditionalDiscountAmount'
  378. );
  379. quoteLine.creditUsage = (String) qlwMap.get('CreditUsage');
  380.  
  381. // Deserialize child quote lines
  382. List<Object> childQuoteLines = new List<Object>();
  383. if (qlwMap.get('ChildQuoteLines') instanceof Map<String, Object>) {
  384. childQuoteLines.add(qlwMap.get('ChildQuoteLines'));
  385. } else {
  386. childQuoteLines = (List<Object>) qlwMap.get('ChildQuoteLines');
  387. }
  388.  
  389. List<ChildQuoteLine> childQuoteLineList = new List<ChildQuoteLine>();
  390. String segmentStartDate = null; // Temporary storage
  391. String segmentEndDate = null; // Temporary storage
  392.  
  393. if (childQuoteLines != null) {
  394. for (Object childQuoteLineWrapperRecord : childQuoteLines) {
  395. Map<String, Object> childQuoteLineWrapperRecordMap = (Map<String, Object>) childQuoteLineWrapperRecord;
  396. Boolean hidden = (Boolean) childQuoteLineWrapperRecordMap.get(
  397. 'Hidden'
  398. );
  399. if (hidden != null && hidden == true) {
  400. continue; // Skip this child quote line if Hidden is true
  401. }
  402. if (
  403. displayUnchangedProducts == false &&
  404. (Decimal) childQuoteLineWrapperRecordMap.get(
  405. 'EffectiveQuantity'
  406. ) == 0
  407. ) {
  408. continue;
  409. }
  410.  
  411. ChildQuoteLine childQuoteLine = new ChildQuoteLine();
  412. childQuoteLine.effectiveQuantity = (Decimal) childQuoteLineWrapperRecordMap.get(
  413. 'EffectiveQuantity'
  414. );
  415. childQuoteLine.netUnitPrice = (Decimal) childQuoteLineWrapperRecordMap.get(
  416. 'NetUnitPrice'
  417. );
  418. childQuoteLine.totalCost = (Decimal) childQuoteLineWrapperRecordMap.get(
  419. 'TotalCost'
  420. );
  421. childQuoteLine.hidden = hidden;
  422. childQuoteLine.childQuoteLineId = (Id) childQuoteLineWrapperRecordMap.get(
  423. 'ChildQuoteLineId'
  424. );
  425. childQuoteLine.segmentIndex = (Integer) childQuoteLineWrapperRecordMap.get(
  426. 'SegmentIndex'
  427. );
  428. childQuoteLine.cqlStartDate = (String) childQuoteLineWrapperRecordMap.get(
  429. 'CQL_Start_Date__c'
  430. );
  431. childQuoteLine.cqlEndDate = (String) childQuoteLineWrapperRecordMap.get(
  432. 'CQL_End_Date__c'
  433. );
  434.  
  435. // Safely deserialize nested School
  436. Object schoolObj = childQuoteLineWrapperRecordMap.get('School');
  437. if (schoolObj != null) {
  438. childQuoteLine.school = (School) JSON.deserialize(
  439. JSON.serialize(schoolObj),
  440. School.class
  441. );
  442. }
  443.  
  444. // Safely deserialize nested Product
  445. Object productObj = childQuoteLineWrapperRecordMap.get('Product');
  446. if (productObj != null) {
  447. childQuoteLine.product = (Product) JSON.deserialize(
  448. JSON.serialize(productObj),
  449. Product.class
  450. );
  451. }
  452.  
  453. if (
  454. childQuoteLine.product != null &&
  455. childQuoteLine.product.productCategory == 'Subscription (Credits)'
  456. ) {
  457. childQuoteLine.effectiveQuantity = (Decimal) childQuoteLineWrapperRecordMap.get(
  458. 'StudentsCreditsCover'
  459. );
  460. quoteLine.effectiveQuantity = (Decimal) qlwMap.get(
  461. 'StudentsCreditsCover'
  462. );
  463. }
  464.  
  465. childQuoteLineList.add(childQuoteLine);
  466. }
  467. }
  468.  
  469. quoteLine.childQuoteLines = childQuoteLineList;
  470. quoteLineList.add(quoteLine);
  471. }
  472.  
  473. quote.quoteLines = quoteLineList;
  474. result.add(quote);
  475. }
  476.  
  477. return result;
  478. }
  479.  
  480. /**
  481. * @description Method to get the Quote Includes Family
  482. * @param List<String> families
  483. * @return String
  484. **/
  485. public static String getQuoteIncludesFamily(
  486. List<String> quoteIncludesFamily
  487. ) {
  488. String quoteProductFamily = '';
  489. if (quoteIncludesFamily.size() > 1) {
  490. for (Integer i = 0; i < quoteIncludesFamily.size(); i++) {
  491. if (i == quoteIncludesFamily.size() - 1) {
  492. quoteProductFamily += ' and ' + quoteIncludesFamily[i];
  493. } else if (i == 0) {
  494. quoteProductFamily += quoteIncludesFamily[i];
  495. } else {
  496. quoteProductFamily += ', ' + quoteIncludesFamily[i];
  497. }
  498. }
  499. } else if (quoteIncludesFamily == null || quoteIncludesFamily.size() == 0) {
  500. return '';
  501. } else {
  502. quoteProductFamily = quoteIncludesFamily[0];
  503. }
  504. return quoteProductFamily;
  505. }
  506.  
  507. /**
  508. * @description Method to process the quotes and create a map of SchoolOutputWrapper
  509. * @param List<Quote> quotes
  510. * @return Map<String, SchoolOutputWrapper>
  511. **/
  512. public static Map<String, SchoolOutput> processQuotes(List<Quote> quotes) {
  513. Map<String, SchoolOutput> schoolOutputList = new Map<String, SchoolOutput>();
  514.  
  515. for (Quote quote : quotes) {
  516. for (QuoteLine quoteLine : quote.quoteLines) {
  517. if (quoteLine.childQuoteLines.size() > 0) {
  518. for (ChildQuoteLine childQuoteLine : quoteLine.childQuoteLines) {
  519. processChildQuoteLine(childQuoteLine, quoteLine, schoolOutputList);
  520. schoolIdSet.add(childQuoteLine.school.schoolId);
  521. }
  522. }
  523. }
  524. }
  525. return schoolOutputList;
  526. }
  527.  
  528. /**
  529. * @description Method to process a quote line and populate the product family output map
  530. * @param QuoteLineInputWrapper quoteLineWrapper
  531. * @param Map<String, ProductFamilyOutputWrapper> productFamilyOutputWrapperMap
  532. **/
  533. public static void processChildQuoteLine(
  534. ChildQuoteLine childQuoteLineWrapper,
  535. QuoteLine quoteLineWrapper,
  536. Map<String, SchoolOutput> schoolOutputList
  537. ) {
  538. SchoolOutput schoolOutputWrapper = getSchoolOutput(
  539. childQuoteLineWrapper,
  540. schoolOutputList
  541. );
  542.  
  543. ProductFamilyOutput productFamilyOutputWrapper = getProductFamilyOutput(
  544. schoolOutputWrapper,
  545. childQuoteLineWrapper
  546. );
  547.  
  548. String segmentIndex = getSegmentIndex(
  549. quoteLineWrapper.effectiveSubscriptionTerm,
  550. childQuoteLineWrapper.segmentIndex == null
  551. ? 1
  552. : childQuoteLineWrapper.segmentIndex
  553. );
  554. SegmentOutput segmentOutputWrapper = getSegmentOutput(
  555. segmentIndex,
  556. productFamilyOutputWrapper,
  557. quoteLineWrapper
  558. );
  559.  
  560. ProductOutput productOutputWrapper = createProductOutputWrapper(
  561. childQuoteLineWrapper,
  562. quoteLineWrapper
  563. );
  564. addProductToSegment(segmentOutputWrapper, productOutputWrapper);
  565.  
  566. updateTotals(
  567. schoolOutputWrapper,
  568. segmentOutputWrapper,
  569. productOutputWrapper,
  570. productFamilyOutputWrapper
  571. );
  572.  
  573. if (
  574. childQuoteLineWrapper.product.quoteIncludesFamily != null &&
  575. childQuoteLineWrapper.product.quoteIncludesFamily != ''
  576. )
  577. quoteIncludesFamily.add(
  578. String.valueOf(childQuoteLineWrapper.product.quoteIncludesFamily)
  579. );
  580. }
  581.  
  582. /**
  583. * @description Retrieves or creates a SchoolOutputWrapper for a given school id
  584. * @param ChildQuoteLine childQuoteLineWrapper
  585. * @param Map<String, SchoolOutputWrapper> schoolOutputList
  586. * @return SchoolOutputWrapper
  587. **/
  588. private static SchoolOutput getSchoolOutput(
  589. ChildQuoteLine childQuoteLineWrapper,
  590. Map<String, SchoolOutput> schoolOutputList
  591. ) {
  592. SchoolOutput schoolOutputWrapper = schoolOutputList.get(
  593. childQuoteLineWrapper.school.schoolId
  594. );
  595. if (schoolOutputWrapper == null) {
  596. schoolOutputWrapper = new SchoolOutput(
  597. childQuoteLineWrapper.school.name,
  598. 0.0,
  599. 0.0,
  600. 0.0,
  601. new Map<String, ProductFamilyOutput>()
  602. );
  603. schoolOutputList.put(
  604. childQuoteLineWrapper.school.schoolId,
  605. schoolOutputWrapper
  606. );
  607. }
  608. return schoolOutputWrapper;
  609. }
  610.  
  611. /**
  612. * @description Retrieves or creates a ProductFamilyOutputWrapper for a given product family
  613. * @param SegmentOutputWrapper segmentOutputWrapper
  614. * @param ChildQuoteLine childQuoteLineWrapper
  615. * @return ProductFamilyOutputWrapper
  616. **/
  617. private static ProductFamilyOutput getProductFamilyOutput(
  618. SchoolOutput schoolOutputWrapper,
  619. ChildQuoteLine childQuoteLineWrapper
  620. ) {
  621. ProductFamilyOutput productFamilyOutputWrapper = schoolOutputWrapper.productFamilies.get(
  622. childQuoteLineWrapper.product.family
  623. );
  624. if (productFamilyOutputWrapper == null) {
  625. productFamilyOutputWrapper = new ProductFamilyOutput(
  626. childQuoteLineWrapper.product.family,
  627. 0.0,
  628. 0.0,
  629. 0.0,
  630. new Map<String, SegmentOutput>()
  631. );
  632. schoolOutputWrapper.productFamilies.put(
  633. childQuoteLineWrapper.product.family,
  634. productFamilyOutputWrapper
  635. );
  636. }
  637. return productFamilyOutputWrapper;
  638. }
  639.  
  640. /**
  641. * @description Retrieves or creates a SegmentOutputWrapper for a given segment index
  642. * @param String segmentIndex
  643. * @param ProductFamilyOutputWrapper productFamilyOutputWrapper
  644. * @param QuoteLineInputWrapper quoteLineWrapper
  645. * @return SegmentOutputWrapper
  646. **/
  647. private static SegmentOutput getSegmentOutput(
  648. String segmentIndex,
  649. ProductFamilyOutput productFamilyOutputWrapper,
  650. QuoteLine quoteLineWrapper
  651. ) {
  652. SegmentOutput segmentOutputWrapper = productFamilyOutputWrapper.segments.get(
  653. segmentIndex
  654. );
  655. if (segmentOutputWrapper == null) {
  656. segmentOutputWrapper = new SegmentOutput(
  657. segmentIndex,
  658. 0.0,
  659. 0.0,
  660. 0.0,
  661. quoteLineWrapper.effectiveEndDate,
  662. quoteLineWrapper.effectiveStartDate,
  663. cqlStartDate,
  664. cqlEndDate,
  665. new List<ProductOutput>()
  666. );
  667.  
  668. productFamilyOutputWrapper.segments.put(
  669. segmentIndex,
  670. segmentOutputWrapper
  671. );
  672. } else if (
  673. (segmentOutputWrapper.effectiveEndDate == null ||
  674. segmentOutputWrapper.effectiveEndDate == '') &&
  675. (quoteLineWrapper.effectiveEndDate != null &&
  676. quoteLineWrapper.effectiveEndDate != '')
  677. ) {
  678. DateTime dtEffectiveEndDate = Date.valueOf(
  679. quoteLineWrapper.effectiveEndDate
  680. );
  681. segmentOutputWrapper.effectiveEndDate = String.valueOf(
  682. dtEffectiveEndDate.formatGmt('dd-MMM-yyyy')
  683. );
  684. }
  685. return segmentOutputWrapper;
  686. }
  687.  
  688. /**
  689. * @description Determines the segment index based on the subscription term
  690. * @param Integer effectiveSubscriptionTerm
  691. * @param Integer segmentIndex
  692. * @return String
  693. **/
  694. private static String getSegmentIndex(
  695. Integer effectiveSubscriptionTerm,
  696. Integer segmentIndex
  697. ) {
  698. return effectiveSubscriptionTerm < 12
  699. ? IMPLEMENTATION_PHASE
  700. : String.valueOf(segmentIndex);
  701. }
  702.  
  703. /**
  704. * @description Adds a product to a product family
  705. * @param ProductFamilyOutputWrapper productFamilyOutputWrapper
  706. * @param ProductOutputWrapper productOutputWrapper
  707. * @return void
  708. **/
  709. private static void addProductToSegment(
  710. SegmentOutput segmentOutputWrapper,
  711. ProductOutput productOutputWrapper
  712. ) {
  713. // segmentOutputWrapper.subTotalAmount += productOutputWrapper.netTotal;
  714. // segmentOutputWrapper.subTotalDiscount += productOutputWrapper.discountAmount;
  715. segmentOutputWrapper.quantity += productOutputWrapper.quantity;
  716. segmentOutputWrapper.products.add(productOutputWrapper);
  717. }
  718.  
  719. /**
  720. * @description Creates a ProductOutputWrapper from a QuoteLineInputWrapper
  721. * @param QuoteLineInput quoteLineWrapper
  722. * @return ProductOutputWrapper
  723. **/
  724. private static ProductOutput createProductOutputWrapper(
  725. ChildQuoteLine childQuoteLineWrapper,
  726. QuoteLine quoteLineWrapper
  727. ) {
  728. ProductOutput productOutputWrapper = new ProductOutput(
  729. childQuoteLineWrapper.product.name,
  730. 0.0,
  731. 0.0,
  732. 0.0,
  733. 0.0,
  734. 0.0,
  735. 0.0
  736. );
  737. productOutputWrapper.name = childQuoteLineWrapper.product.name;
  738. if (
  739. childQuoteLineWrapper.effectiveQuantity == 0 ||
  740. quoteLineWrapper.effectiveQuantity == 0
  741. ) {
  742. ProductOutputWrapper.quantity = quoteLineWrapper.Quantity;
  743. ProductOutputWrapper.discountAmount = quoteLineWrapper.AdditionalDiscountAmount;
  744. ProductOutputWrapper.netTotal = 0;
  745. } else {
  746. ProductOutputWrapper.Quantity = childQuoteLineWrapper.EffectiveQuantity;
  747. ProductOutputWrapper.DiscountAmount =
  748. (quoteLineWrapper.AdditionalDiscountAmount /
  749. quoteLineWrapper.effectiveQuantity) *
  750. childQuoteLineWrapper.EffectiveQuantity;
  751. ProductOutputWrapper.netTotal =
  752. (quoteLineWrapper.NetTotal / quoteLineWrapper.effectiveQuantity) *
  753. childQuoteLineWrapper.EffectiveQuantity;
  754. ProductOutputWrapper.listTotal =
  755. (quoteLineWrapper.ListTotal / quoteLineWrapper.effectiveQuantity) *
  756. childQuoteLineWrapper.EffectiveQuantity;
  757. }
  758.  
  759. productOutputWrapper.listPrice = quoteLineWrapper.listPrice;
  760. productOutputWrapper.netPrice = quoteLineWrapper.netPrice;
  761. productOutputWrapper.quantity = childQuoteLineWrapper.effectiveQuantity;
  762. productOutputWrapper.isNegativeNetTotal = productOutputWrapper.netTotal < 0;
  763. productOutputWrapper.isCreditProduct =
  764. quoteLineWrapper.childQuoteLines[0].product.productCategory ==
  765. 'Subscription (Credits)';
  766. productOutputWrapper.creditUsage = quoteLineWrapper.creditUsage;
  767. productOutputWrapper.hidden = childQuoteLineWrapper.hidden;
  768. productOutputWrapper.netUnitPrice = childQuoteLineWrapper.netUnitPrice;
  769. productOutputWrapper.totalCost = childQuoteLineWrapper.totalCost;
  770. return productOutputWrapper;
  771. }
  772.  
  773. /**
  774. * @description Method to update totals for the segment
  775. * @param SegmentOutputWrapper segmentWrapper
  776. * @param ProductOutputWrapper productOutputWrapper
  777. **/
  778. public static void updateTotals(
  779. SchoolOutput schoolOutputWrapper,
  780. SegmentOutput segmentWrapper,
  781. ProductOutput productOutputWrapper,
  782. ProductFamilyOutput productFamilyOutputWrapper
  783. ) {
  784. productFamilyOutputWrapper.subTotalAmount += productOutputWrapper.netTotal;
  785. productFamilyOutputWrapper.subTotalDiscount += productOutputWrapper.discountAmount;
  786. productFamilyOutputWrapper.hasDiscount =
  787. productFamilyOutputWrapper.subTotalDiscount != 0;
  788. segmentWrapper.subTotalAmount += productOutputWrapper.netTotal;
  789. segmentWrapper.subTotalDiscount += productOutputWrapper.discountAmount;
  790. schoolOutputWrapper.subTotalAmount += productOutputWrapper.netTotal;
  791. schoolOutputWrapper.subTotalDiscount += productOutputWrapper.discountAmount;
  792. }
  793.  
  794. /**
  795. * @description Method to convert the processed data into the new format of SchoolOutputWrapper
  796. * @param Map<String, SchoolOutput> schoolOutputMap
  797. * @return List<SchoolOutputWrapper>
  798. **/
  799. public static List<SchoolOutputWrapper> convertToNewFormat(
  800. Map<String, SchoolOutput> schoolOutputMap
  801. ) {
  802. List<SchoolOutputWrapper> schoolOutputList = new List<SchoolOutputWrapper>();
  803.  
  804. for (SchoolOutput schoolOutput : schoolOutputMap.values()) {
  805. List<ProductFamilyOutputWrapper> productFamilies = new List<ProductFamilyOutputWrapper>();
  806. for (
  807. ProductFamilyOutput productFamilyOutput : schoolOutput.productFamilies.values()
  808. ) {
  809. List<SegmentOutputWrapper> segments = new List<SegmentOutputWrapper>();
  810. for (
  811. SegmentOutput segmentOutput : productFamilyOutput.segments.values()
  812. ) {
  813. List<ProductOutput> products = segmentOutput.products;
  814. segments.add(
  815. new SegmentOutputWrapper(
  816. segmentOutput.segmentIndex,
  817. segmentOutput.subTotalAmount,
  818. segmentOutput.subTotalDiscount,
  819. segmentOutput.quantity,
  820. segmentOutput.effectiveEndDate,
  821. segmentOutput.effectiveStartDate,
  822. segmentOutput.cqlStartDate,
  823. segmentOutput.cqlEndDate,
  824. products
  825. )
  826. );
  827. }
  828. segments.sort();
  829. productFamilies.add(
  830. new ProductFamilyOutputWrapper(
  831. productFamilyOutput.name,
  832. productFamilyOutput.subTotalAmount,
  833. productFamilyOutput.subTotalDiscount,
  834. productFamilyOutput.quantity,
  835. segments
  836. )
  837. );
  838. }
  839. schoolOutputList.add(
  840. new SchoolOutputWrapper(
  841. schoolOutput.Name,
  842. schoolOutput.SubListAmount,
  843. schoolOutput.SubTotalDiscount,
  844. schoolOutput.SubTotalAmount,
  845. productFamilies
  846. )
  847. );
  848. }
  849. return schoolOutputList;
  850. }
  851. }
Success #stdin #stdout #stderr 0.01s 7904KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
./prog:1: expected expression
./prog:3: Invalid character 0xe2
./prog:3: Invalid character 0x86
./prog:3: Invalid character 0x92
./prog:3: Invalid character 0xe2
./prog:3: Invalid character 0x86
./prog:3: Invalid character 0x92
./prog:63: expected expression
./prog:103: expected expression
./prog:163: expected expression
./prog:210: expected expression
./prog:248: expected expression
./prog:393: expected expression
./prog:399: expected expression
./prog:437: expected expression
./prog:446: expected expression
./prog:454: expected expression
./prog:574: expected expression
./prog:575: expected expression
./prog:675: expected expression
./prog:676: expected expression
./prog:787: expected expression