reportItem.service.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import { Injectable } from '@angular/core';
  2. // import {bootstrapItem} from "../../../node_modules/@angular/cli/lib/ast-tools";
  3. export enum ReportItemType {
  4. food = 'Food',
  5. travel = 'Travel',
  6. training = 'Training',
  7. transport = 'Transport',
  8. unselected = ''
  9. }
  10. export type ReportItem = {
  11. description: string;
  12. amount: number;
  13. hasReceipt: boolean;
  14. type: ReportItemType;
  15. date: Date;
  16. };
  17. function validateRequired(item: ReportItem): boolean {
  18. // false is a valid value for these, so exclude them from check.
  19. const exclude: (keyof ReportItem)[] = ['hasReceipt'];
  20. return Object.keys(item)
  21. .reduce((isValid, memberKey: keyof ReportItem) => {
  22. if (!isValid) {
  23. return isValid;
  24. }
  25. if (memberKey === 'date') {
  26. // date is of type Date, because of the keyof typing.
  27. const date = item[memberKey];
  28. if (date < new Date(1970)) {
  29. return false;
  30. }
  31. }
  32. return exclude.includes(memberKey) || !!item[memberKey];
  33. }, true);
  34. }
  35. function validateFoodItem(item: ReportItem): string {
  36. if (item.amount >= 50 && !item.hasReceipt) {
  37. return 'A food item with a value greater than $50 must have a receipt';
  38. }
  39. return '';
  40. }
  41. function validateReceipt(item: ReportItem): string {
  42. return item.hasReceipt ? '' : 'The item must have a receipt';
  43. }
  44. function validateTraining(item: ReportItem): string {
  45. if (item.amount < 50 && !item.hasReceipt) {
  46. return '';
  47. }
  48. return 'A training item with a value greater than $50 must have a receipt';
  49. }
  50. const validateDate = (minDate: Date, maxDate: Date) => (item: ReportItem): string => {
  51. return +item.date >= +minDate && +item.date <= +maxDate ? '' : 'The date is invalid';
  52. };
  53. @Injectable()
  54. export class ReportItemService {
  55. private validateDate: (item: ReportItem) => string;
  56. constructor() {
  57. const today = new Date();
  58. const maxDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
  59. const minDate = new Date(maxDate);
  60. minDate.setMonth(-3);
  61. this.validateDate = validateDate(minDate, maxDate);
  62. }
  63. isValid(item: ReportItem): string {
  64. if (!validateRequired(item)) {
  65. return 'One of the required fields was not filled.';
  66. }
  67. switch (item.type) {
  68. case ReportItemType.food: {
  69. const validatedFood = validateFoodItem(item);
  70. if (validatedFood) {
  71. return validatedFood;
  72. }
  73. return this.validateDate(item);
  74. }
  75. case ReportItemType.training:
  76. return validateTraining(item);
  77. case ReportItemType.transport:
  78. case ReportItemType.travel: {
  79. const validatedReceipt = validateReceipt(item);
  80. if (validatedReceipt) {
  81. return validatedReceipt;
  82. }
  83. return this.validateDate(item);
  84. }
  85. case ReportItemType.unselected:
  86. default:
  87. return 'The item type is not supported';
  88. }
  89. }
  90. }