@sellout/models 0.0.354 → 0.0.356

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -65,10 +65,18 @@ message SuperAdminDeleteTasksResponse {
65
65
  bool deleted = 3;
66
66
  }
67
67
 
68
+ message DeleteTaskTypeTasksRequest {
69
+ string spanContext = 0;
70
+ string orgId = 1;
71
+ string eventId = 2;
72
+ string taskType = 3;
73
+ }
74
+
68
75
  service TaskService {
69
76
  // Create
70
77
  rpc createTask(CreateTaskRequest) returns (CreateTaskResponse) {}
71
78
  rpc deleteTask(DeleteTaskRequest) returns (DeleteTaskResponse) {}
72
79
  // Delete
73
80
  rpc superAdminDeleteTasks(SuperAdminDeleteTasksRequest) returns (SuperAdminDeleteTasksResponse) {}
81
+ rpc deleteTaskTypeTasks(DeleteTaskTypeTasksRequest) returns (SuperAdminDeleteTasksResponse) {}
74
82
  }
@@ -395,6 +395,11 @@ const TicketTier = {
395
395
  type: Number,
396
396
  required: true,
397
397
  },
398
+ isActive: {
399
+ type: Boolean,
400
+ required: true,
401
+ default: true,
402
+ },
398
403
  };
399
404
 
400
405
  const Subscription = {
@@ -5,7 +5,7 @@ const OrderIntegration = {
5
5
  apiURL: {
6
6
  type: String,
7
7
  required: false,
8
- default: false,
8
+ default: null,
9
9
  },
10
10
  orderIntegrationMethod: {
11
11
  type: String,
@@ -100,15 +100,15 @@ export default {
100
100
  },tegClientID:{
101
101
  type: String,
102
102
  required: false,
103
- default: false
103
+ default: null
104
104
  },tegSecret:{
105
105
  type: String,
106
106
  required: false,
107
- default: false
107
+ default: null
108
108
  },tegURL:{
109
109
  type: String,
110
110
  required: false,
111
- default: false
111
+ default: null
112
112
  },ticketFormat:{
113
113
  type:String,
114
114
  required:false,
@@ -116,6 +116,6 @@ export default {
116
116
  },locationId:{
117
117
  type: String,
118
118
  required: false,
119
- default: false
119
+ default: null
120
120
  },orderIntegration: OrderIntegration
121
121
  };
@@ -142,7 +142,7 @@ export default {
142
142
 
143
143
  // return doorsAt - 600;
144
144
 
145
- return startsAt - 28800
145
+ return startsAt - 28800;
146
146
  },
147
147
  shouldSendOrderReceipt(event): boolean {
148
148
  const now = Time.now();
@@ -235,12 +235,10 @@ export default {
235
235
  },
236
236
 
237
237
  /****************************************************************************************
238
- * Tickets Hold
239
- ****************************************************************************************/
238
+ * Tickets Hold
239
+ ****************************************************************************************/
240
240
  ticketHold(event, ticketHoldId): any {
241
- return event?.holds.find(
242
- (ticketHold) => ticketHold._id === ticketHoldId
243
- );
241
+ return event?.holds.find((ticketHold) => ticketHold._id === ticketHoldId);
244
242
  },
245
243
 
246
244
  /****************************************************************************************
@@ -337,7 +335,7 @@ export default {
337
335
  isUpgradeForSpecificTickets(event: IEvent, upgrade: IEventUpgrade): boolean {
338
336
  return Boolean(
339
337
  event?.ticketTypes?.map((t) => t._id).sort() ===
340
- upgrade?.ticketTypeIds?.sort()
338
+ upgrade?.ticketTypeIds?.sort()
341
339
  );
342
340
  },
343
341
  /****************************************************************************************
@@ -561,8 +559,8 @@ export default {
561
559
  },
562
560
 
563
561
  /****************************************************************************************
564
- * Ticket Hold validate
565
- ****************************************************************************************/
562
+ * Ticket Hold validate
563
+ ****************************************************************************************/
566
564
  validateTicketHold(ticketHold: ITicketHold): any {
567
565
  let ticketHoldSchema: any;
568
566
  let used = ticketHold?.ticketRemaining as number;
@@ -573,9 +571,12 @@ export default {
573
571
  name: Joi.string()
574
572
  .required()
575
573
  .messages({ "string.empty": '"Block name" is a required field' }),
576
- ticketType: Joi.string().required()
574
+ ticketType: Joi.string()
575
+ .required()
577
576
  .messages({ "string.empty": '"Ticket Type" is a required field' }),
578
- qty: Joi.number().required().min(1)
577
+ qty: Joi.number()
578
+ .required()
579
+ .min(1)
579
580
  .custom((value, helpers) => {
580
581
  if (value > 0 && value > used) {
581
582
  return helpers.error("totalqty.invalid");
@@ -643,27 +644,77 @@ export default {
643
644
  .messages({
644
645
  "array.min": "Ticket must have selected atleast one day.",
645
646
  }),
646
- tiers: Joi.array().items(
647
- Joi.object()
648
- .keys({
649
- name: Joi.string().required(),
650
- price: Joi.number().required(),
651
- remainingQty: Joi.number().required(),
652
- totalQty: Joi.number()
653
- .custom((value, helpers) => {
654
- if (value > 0 && value < used) {
655
- return helpers.error("totalqty.invalid");
656
- }
657
- return value;
658
- })
659
- .messages({
660
- "totalqty.invalid":
661
- '"Total qty." must be greater than or equal to number of ticket sold',
662
- })
663
- .required(),
664
- })
665
- .unknown(true)
666
- ),
647
+ tiers: Joi.array()
648
+ .items(
649
+ Joi.object()
650
+ .keys({
651
+ name: Joi.string().required().messages({
652
+ "string.empty": '"Tier name" is a required field',
653
+ "any.required": '"Tier name" must be provided',
654
+ }),
655
+ price: Joi.number().required(),
656
+ remainingQty: Joi.number().required(),
657
+ totalQty: Joi.number()
658
+ .custom((value, helpers) => {
659
+ if (value > 0 && value < used) {
660
+ return helpers.error("totalqty.invalid");
661
+ }
662
+ return value;
663
+ })
664
+ .messages({
665
+ "totalqty.invalid":
666
+ '"Total qty." must be greater than or equal to number of ticket sold',
667
+ })
668
+ .required(),
669
+ startsAt: Joi.date().allow(null),
670
+ endsAt: Joi.date().allow(null),
671
+ })
672
+ .unknown(true)
673
+ )
674
+ .custom((tiers, helpers) => {
675
+ // Only validate active tiers
676
+ const activeTiers = tiers.filter(t => t.isActive !== false);
677
+ for (let i = 0; i < activeTiers.length; i++) {
678
+ const tier = activeTiers[i];
679
+ if (tier.startsAt && tier.endsAt) {
680
+ const start = new Date(tier.startsAt);
681
+ const end = new Date(tier.endsAt);
682
+ if (isNaN(start.getTime()) || isNaN(end.getTime())) {
683
+ return helpers.error("tiers.invalidDate", { index: i + 1 });
684
+ }
685
+ if (end.getTime() <= start.getTime()) {
686
+ const tierLabel =
687
+ tier.name && tier.name.trim() !== ""
688
+ ? ` "${tier.name}"`
689
+ : ` #${i + 1}`;
690
+
691
+ return helpers.error("tiers.endsAtBeforeStartsAt", {
692
+ tierLabel,
693
+ });
694
+ }
695
+ }
696
+ }
697
+ for (let i = 1; i < activeTiers.length; i++) {
698
+ const prevTier = activeTiers[i - 1];
699
+ const currentTier = activeTiers[i];
700
+ const prevEndsAt = new Date(prevTier.endsAt).getTime();
701
+ const currStartsAt = new Date(currentTier.startsAt).getTime();
702
+ if (currStartsAt !== prevEndsAt) {
703
+ // TODO Return custom error
704
+ return helpers.error("tiers.startsAtMismatch", {
705
+ index: i + 1,
706
+ });
707
+ }
708
+ }
709
+
710
+ return tiers;
711
+ })
712
+ .messages({
713
+ "tiers.startsAtMismatch":
714
+ "Start date/time of Tier {#index} must match end date/time of previous tier.",
715
+ "tiers.endsAtBeforeStartsAt":
716
+ "End date/time of Tier{#tierLabel} must be after start date/time.",
717
+ }),
667
718
  })
668
719
  .unknown(true);
669
720
  return ticketSchema.validate(ticket);
@@ -773,38 +824,39 @@ export default {
773
824
  ****************************************************************************************/
774
825
  ValidateEventEmailSubjectFields(emailPreviewFields: IEmailHolders): any {
775
826
  const isEmptyHTML = (value: string) => {
776
- return !value || value.trim() === "" || value.trim() === "<p></p>" || value.trim() === "<p><br></p>";
827
+ return (
828
+ !value ||
829
+ value.trim() === "" ||
830
+ value.trim() === "<p></p>" ||
831
+ value.trim() === "<p><br></p>"
832
+ );
777
833
  };
778
-
834
+
779
835
  let validateEmailPreviewFields = Joi.object()
780
836
  .options({ abortEarly: false })
781
837
  .keys({
782
- eventEmailSubject: Joi.string()
783
- .required()
784
- .messages({
785
- "string.empty": 'Email Subject cannot be empty',
786
- "any.required": 'Email Subject is required'
787
- }),
788
-
838
+ eventEmailSubject: Joi.string().required().messages({
839
+ "string.empty": "Email Subject cannot be empty",
840
+ "any.required": "Email Subject is required",
841
+ }),
842
+
789
843
  eventEmailBody: Joi.string()
790
844
  .custom((value, helpers) => {
791
845
  if (isEmptyHTML(value)) {
792
- return helpers.error("string.empty");
846
+ return helpers.error("string.empty");
793
847
  }
794
848
  return value;
795
849
  })
796
850
  .required()
797
851
  .messages({
798
- "string.empty": 'Email Body cannot be empty',
799
- "any.required": 'Email Body is required'
852
+ "string.empty": "Email Body cannot be empty",
853
+ "any.required": "Email Body is required",
800
854
  }),
801
855
  })
802
856
  .unknown(true);
803
-
857
+
804
858
  return validateEmailPreviewFields.validate(emailPreviewFields);
805
859
  },
806
-
807
-
808
860
 
809
861
  /****************************************************************************************
810
862
  * CustomField validate
@@ -859,9 +911,9 @@ export default {
859
911
  event?.totalDays?.length === 0
860
912
  ? (event?.schedule?.endsAt as number)
861
913
  : (performance?.schedule &&
862
- (performance?.schedule[performance?.schedule?.length - 1]
863
- ?.endsAt as number)) ||
864
- 0;
914
+ (performance?.schedule[performance?.schedule?.length - 1]
915
+ ?.endsAt as number)) ||
916
+ 0;
865
917
  /* Actions */
866
918
  let message = "" as string;
867
919
 
@@ -870,8 +922,8 @@ export default {
870
922
  message =
871
923
  performance?.schedule && performance?.schedule?.length > 1
872
924
  ? "Doors Open should be less than or equal to Event Begins on day " +
873
- (i + 1) +
874
- "."
925
+ (i + 1) +
926
+ "."
875
927
  : "Doors Open should be less than or equal to Event Begins.";
876
928
  return message;
877
929
  } else if (
@@ -883,17 +935,17 @@ export default {
883
935
  message =
884
936
  performance?.schedule && performance?.schedule?.length > 1
885
937
  ? "Event Ends should be greater than Event Begins on day " +
886
- (i + 1) +
887
- "."
938
+ (i + 1) +
939
+ "."
888
940
  : "Event Ends should be greater than Event Begins.";
889
941
  return message;
890
942
  } else if (performance?.schedule && performance?.schedule?.length > 1) {
891
943
  const aa =
892
944
  performance?.schedule?.[i + 1]?.startsAt &&
893
945
  performance?.schedule?.[i + 1]?.startsAt >
894
- (event?.totalDays?.length === 0
895
- ? (event?.schedule?.endsAt as number)
896
- : a.endsAt);
946
+ (event?.totalDays?.length === 0
947
+ ? (event?.schedule?.endsAt as number)
948
+ : a.endsAt);
897
949
  if (!aa && aa !== undefined) {
898
950
  message =
899
951
  "Day " +
@@ -735,6 +735,107 @@ class PaymentUtil {
735
735
  ? guestFees + (guestFees * stripeFeesValue) / 100
736
736
  : 0;
737
737
  }
738
+ getApplicableFees({
739
+ price,
740
+ fees,
741
+ isTicketType = false,
742
+ isUpgradeType = false,
743
+ }: {
744
+ price: number;
745
+ fees: any[];
746
+ isTicketType?: boolean;
747
+ isUpgradeType?: boolean;
748
+ }): { label: string; amount: number }[] {
749
+ if (!fees || fees.length === 0) return [];
750
+
751
+ const filteredFees = fees.filter((fee) => {
752
+ const min = fee.minAppliedToPrice;
753
+ const max = fee.maxAppliedToPrice;
754
+ const baseCondition =
755
+ !fee.disabled &&
756
+ ((min === 0 && max === 0) || (price >= min && price <= max));
757
+
758
+ if (!baseCondition) return false;
759
+
760
+ const feeSeatedFilter = FeeFiltersEnum.Seated;
761
+ const guestFilter = FeeFiltersEnum.GuestTicket;
762
+ const feeCardEntryFilter = FeeFiltersEnum.CardEntry;
763
+ const feeCardReaderWifiFilter = FeeFiltersEnum.CardReader;
764
+ const feeCardReaderBluetoothFilter = FeeFiltersEnum.CardReaderBluetooth;
765
+
766
+ const excludedFilters = [
767
+ feeSeatedFilter,
768
+ guestFilter,
769
+ feeCardEntryFilter,
770
+ feeCardReaderWifiFilter,
771
+ feeCardReaderBluetoothFilter,
772
+ ];
773
+
774
+ const hasExcludedFilter =
775
+ fee.filters &&
776
+ fee.filters.some((filter: string) =>
777
+ excludedFilters.includes(filter as FeeFiltersEnum)
778
+ );
779
+ if (hasExcludedFilter) return false;
780
+
781
+ if (isTicketType) {
782
+ return fee.appliedTo === FeeAppliedToEnum.Ticket &&
783
+ (fee.appliedBy === FeeAppliedByEnum.Sellout);
784
+ }
785
+
786
+ if (isUpgradeType) {
787
+ return fee.appliedTo === FeeAppliedToEnum.Upgrade &&
788
+ (fee.appliedBy === FeeAppliedByEnum.Sellout);
789
+ }
790
+
791
+ return false;
792
+ });
793
+
794
+ //TODO Group by label and sum the amount
795
+ const feeMap = new Map<string, number>();
796
+
797
+ // filteredFees?.forEach((fee) => {
798
+ // const amount =
799
+ // fee?.type === FeeTypeEnum.Flat
800
+ // ? fee.value
801
+ // : (fee.value / 100) * price;
802
+
803
+ // const label =
804
+ // fee?.appliedBy === FeeAppliedByEnum.Sellout
805
+ // ? "Sellout service fees"
806
+ // : fee.name;
807
+
808
+ // const current = feeMap.get(label) || 0;
809
+ // feeMap.set(label, current + amount);
810
+ // });
811
+ filteredFees.forEach((fee) => {
812
+ const amount =
813
+ fee.type === FeeTypeEnum.Flat
814
+ ? fee.value
815
+ : (fee.value / 100) * price;
816
+
817
+ const label =
818
+ fee.appliedBy === FeeAppliedByEnum.Sellout ||
819
+ fee.appliedBy === FeeAppliedByEnum.Organization
820
+ ? "Sellout service fees"
821
+ : fee.name;
822
+
823
+ const current = feeMap.get(label) || 0;
824
+ feeMap.set(label, current + amount);
825
+ });
826
+ const result: { label: string; amount: number }[] = [];
827
+ feeMap.forEach((amount, label) => {
828
+ result.push({
829
+ label,
830
+ amount: parseFloat((amount / 100).toFixed(2)),
831
+ });
832
+ });
833
+
834
+ return result;
835
+ }
836
+
837
+
838
+
738
839
  }
739
840
 
740
841
  export default new PaymentUtil();