@chevre/domain 27.1.0-alpha.2 → 27.1.0-alpha.3

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.
Files changed (42) hide show
  1. package/lib/chevre/repo/adminEvent.d.ts +236 -0
  2. package/lib/chevre/repo/adminEvent.js +388 -0
  3. package/lib/chevre/repo/aggregateEvent.d.ts +42 -0
  4. package/lib/chevre/repo/aggregateEvent.js +221 -0
  5. package/lib/chevre/repo/event.d.ts +5 -263
  6. package/lib/chevre/repo/event.js +3 -636
  7. package/lib/chevre/repository.d.ts +10 -0
  8. package/lib/chevre/repository.js +24 -2
  9. package/lib/chevre/service/aggregation/event/aggregateScreeningEvent.d.ts +2 -0
  10. package/lib/chevre/service/aggregation/event/aggregateScreeningEvent.js +1 -1
  11. package/lib/chevre/service/aggregation/event/importFromCOA.d.ts +2 -2
  12. package/lib/chevre/service/aggregation/event/importFromCOA.js +1 -1
  13. package/lib/chevre/service/aggregation/system.d.ts +2 -2
  14. package/lib/chevre/service/aggregation/system.js +1 -1
  15. package/lib/chevre/service/event/saveScreeningEvents.d.ts +2 -2
  16. package/lib/chevre/service/event/saveScreeningEvents.js +1 -1
  17. package/lib/chevre/service/event.d.ts +2 -0
  18. package/lib/chevre/service/event.js +1 -1
  19. package/lib/chevre/service/offer/eventServiceByCOA/acceptOffer.js +2 -3
  20. package/lib/chevre/service/offer/onEventChanged.d.ts +2 -0
  21. package/lib/chevre/service/offer/onEventChanged.js +1 -1
  22. package/lib/chevre/service/project.d.ts +3 -3
  23. package/lib/chevre/service/project.js +1 -1
  24. package/lib/chevre/service/task/aggregateScreeningEvent.js +2 -0
  25. package/lib/chevre/service/task/importEventCapacitiesFromCOA.js +2 -2
  26. package/lib/chevre/service/task/importEventsFromCOA.js +2 -0
  27. package/lib/chevre/service/task/onEventChanged.js +2 -0
  28. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesByEventSeries.d.ts +2 -2
  29. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesByEventSeries.js +1 -1
  30. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesByMovieTheater.d.ts +2 -2
  31. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesByMovieTheater.js +1 -1
  32. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesByOfferCatalog.d.ts +2 -2
  33. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesByOfferCatalog.js +1 -1
  34. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesByProduct.d.ts +2 -2
  35. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesByProduct.js +1 -1
  36. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesByRoom.d.ts +2 -2
  37. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesByRoom.js +1 -1
  38. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesBySeller.d.ts +2 -2
  39. package/lib/chevre/service/task/onResourceDeleted/deleteResourcesBySeller.js +1 -1
  40. package/lib/chevre/service/task/onResourceDeleted.js +2 -2
  41. package/lib/chevre/service/task/syncResourcesFromCOA.js +2 -2
  42. package/package.json +1 -1
@@ -1,43 +1,7 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.EventRepo = void 0;
37
- const mongoose_1 = require("mongoose");
38
- const errorHandler_1 = require("../errorHandler");
39
4
  const factory_1 = require("../factory");
40
- const EventFactory = __importStar(require("../factory/event"));
41
5
  const settings_1 = require("../settings");
42
6
  const event_1 = require("./mongoose/schemas/event");
43
7
  const AVAILABLE_PUBLIC_PROJECT_FIELDS = [
@@ -56,14 +20,6 @@ class EventRepo {
56
20
  constructor(connection) {
57
21
  this.eventModel = connection.model(event_1.modelName, (0, event_1.createSchema)());
58
22
  }
59
- /**
60
- * イベントIDを生成する
61
- */
62
- static CREATE_ID() {
63
- // implement using ObjectId(2025-10-17~)
64
- // return (USE_OBJECT_ID_AS_EVENT_ID) ? new Types.ObjectId().toHexString() : uniqid();
65
- return new mongoose_1.Types.ObjectId().toHexString(); // 設定を廃止(2025-11-20~)
66
- }
67
23
  static CREATE_MONGO_CONDITIONS(conditions) {
68
24
  const andConditions = [];
69
25
  const typeOfEq = conditions.typeOf;
@@ -264,247 +220,6 @@ class EventRepo {
264
220
  }
265
221
  return andConditions;
266
222
  }
267
- /**
268
- * イベントコードをキーにして冪等置換
269
- */
270
- async upsertManyScreeningEventByIdentifier(params, options) {
271
- const { update } = options;
272
- const bulkWriteOps = [];
273
- const queryFilters = [];
274
- if (Array.isArray(params)) {
275
- params.forEach(({ $set, $unset }) => {
276
- const { project, identifier } = $set;
277
- if (typeof identifier !== 'string' || identifier.length === 0) {
278
- throw new factory_1.factory.errors.ArgumentNull('identifier');
279
- }
280
- // リソースのユニークネスを保証するfilter
281
- const filter = {
282
- 'project.id': { $eq: project.id },
283
- identifier: { $exists: true, $eq: identifier }
284
- };
285
- queryFilters.push({
286
- 'project.id': { $eq: project.id },
287
- identifier: { $exists: true, $eq: identifier }
288
- });
289
- if (update === true) {
290
- const { maximumPhysicalAttendeeCapacity, additionalProperty, eventStatus, location, name, superEvent, offers, doorTime, endDate, startDate } = $set;
291
- const setFields = {
292
- maximumPhysicalAttendeeCapacity, additionalProperty,
293
- eventStatus, location, name, superEvent, offers,
294
- doorTime, endDate, startDate
295
- };
296
- const updateOne = {
297
- filter,
298
- update: {
299
- $set: setFields,
300
- ...($unset !== undefined) ? { $unset } : undefined
301
- },
302
- upsert: false
303
- };
304
- bulkWriteOps.push({ updateOne });
305
- }
306
- else {
307
- const { id, coaInfo, description, // eslint-disable-line @typescript-eslint/no-unused-vars
308
- maximumAttendeeCapacity, remainingAttendeeCapacity, checkInCount, attendeeCount, aggregateReservation, // eslint-disable-line @typescript-eslint/no-unused-vars
309
- ...setOnInsertFields } = $set;
310
- const setOnInsert = {
311
- ...setOnInsertFields,
312
- identifier,
313
- _id: EventRepo.CREATE_ID()
314
- };
315
- const updateOne = {
316
- filter,
317
- update: {
318
- $setOnInsert: setOnInsert
319
- },
320
- upsert: true
321
- };
322
- bulkWriteOps.push({ updateOne });
323
- }
324
- });
325
- }
326
- if (bulkWriteOps.length > 0) {
327
- const bulkWriteResult = await this.eventModel.bulkWrite(bulkWriteOps, { ordered: false });
328
- // update:falseの場合、upsertedIdsのみmodifiedEventsとして返せばよい(2026-01-16~)
329
- if (!update) {
330
- // BulkWriteResult -> upsertedIds: { '0': '7iri6p4m54k0r3g' }
331
- return {
332
- bulkWriteResult,
333
- modifiedEvents: Object.values(bulkWriteResult.upsertedIds)
334
- .map((id) => ({ id: String(id) }))
335
- };
336
- }
337
- else {
338
- // modifiedの場合upsertedIdsに含まれないので、idを検索する
339
- const modifiedEvents = await this.eventModel.find({ $or: queryFilters }, {
340
- _id: 0,
341
- id: { $toString: '$_id' }
342
- })
343
- .lean()
344
- .exec();
345
- return { bulkWriteResult, modifiedEvents };
346
- }
347
- }
348
- return { modifiedEvents: [] };
349
- }
350
- /**
351
- * イベント部分更新
352
- */
353
- async updatePartiallyById(params) {
354
- // let doc: Document | null;
355
- const { typeOf, ...updateFields } = params.attributes;
356
- if (typeof typeOf !== 'string' || typeOf.length === 0) {
357
- throw new factory_1.factory.errors.ArgumentNull('attributes.typeOf');
358
- }
359
- const doc = await this.eventModel.findOneAndUpdate({
360
- _id: { $eq: params.id },
361
- 'project.id': { $eq: params.project.id },
362
- typeOf: { $eq: typeOf }
363
- }, {
364
- $set: updateFields
365
- }, { upsert: false, new: false, projection: { _id: 1 } })
366
- .lean()
367
- .exec();
368
- if (doc === null) {
369
- throw new factory_1.factory.errors.NotFound(this.eventModel.modelName);
370
- }
371
- }
372
- /**
373
- * 単一イベント編集
374
- */
375
- async updateEventById(params) {
376
- let doc;
377
- const { identifier, project, typeOf, // eslint-disable-line @typescript-eslint/no-unused-vars
378
- organizer, aggregateReservation, maximumAttendeeCapacity, remainingAttendeeCapacity, checkInCount, attendeeCount, // eslint-disable-line @typescript-eslint/no-unused-vars
379
- coaInfo, // eslint-disable-line @typescript-eslint/no-unused-vars
380
- ...updateFields
381
- // maximumPhysicalAttendeeCapacity, additionalProperty,
382
- // eventStatus, location, name, superEvent, offers,
383
- // doorTime, endDate, startDate
384
- } = params.attributes;
385
- if (typeof typeOf !== 'string' || typeOf.length === 0) {
386
- throw new factory_1.factory.errors.ArgumentNull('attributes.typeOf');
387
- }
388
- if (typeof params.id !== 'string' || params.id === '') {
389
- throw new factory_1.factory.errors.ArgumentNull('id');
390
- }
391
- try {
392
- doc = await this.eventModel.findOneAndUpdate({
393
- _id: { $eq: params.id },
394
- typeOf: { $eq: typeOf }
395
- }, {
396
- // 編集のためのみのメソッドになったので、setOnInsertは廃止(2025-10-27~)
397
- // 上書き禁止属性を除外(2022-08-24~)
398
- // $setOnInsert: {
399
- // typeOf,
400
- // project,
401
- // ...(typeof identifier === 'string' && identifier !== '') ? { identifier } : undefined
402
- // },
403
- $set: updateFields,
404
- ...(params.$unset !== undefined) ? { $unset: params.$unset } : undefined
405
- }, {
406
- upsert: false,
407
- new: true,
408
- projection: { _id: 1 }
409
- })
410
- .lean()
411
- .exec();
412
- }
413
- catch (error) {
414
- if (await (0, errorHandler_1.isMongoDuplicateError)(error)) {
415
- throw new factory_1.factory.errors.AlreadyInUse(factory_1.factory.eventType.ScreeningEvent, ['offeredBy.member.identifier']);
416
- }
417
- throw error;
418
- }
419
- if (doc === null) {
420
- throw new factory_1.factory.errors.NotFound(this.eventModel.modelName);
421
- }
422
- }
423
- /**
424
- * sskts専用
425
- */
426
- async saveManyEvents(params) {
427
- const bulkWriteOps = []; // eslint-disable-line @typescript-eslint/no-explicit-any
428
- if (Array.isArray(params)) {
429
- params.forEach((p) => {
430
- const upsert = p.upsert === true;
431
- if (p.attributes.typeOf === factory_1.factory.eventType.ScreeningEvent) {
432
- // 上書き禁止属性を除外(2022-08-24~)
433
- const { identifier, project, typeOf, remainingAttendeeCapacity, ...updateFields } = p.attributes; // eslint-disable-line @typescript-eslint/no-unused-vars
434
- bulkWriteOps.push({
435
- updateOne: {
436
- filter: {
437
- _id: p.id,
438
- typeOf: p.attributes.typeOf
439
- },
440
- update: {
441
- $setOnInsert: {
442
- typeOf: p.attributes.typeOf,
443
- project: p.attributes.project,
444
- ...(typeof p.attributes.identifier === 'string')
445
- ? { identifier: p.attributes.identifier } : undefined,
446
- ...(typeof p.attributes.remainingAttendeeCapacity === 'number')
447
- ? { remainingAttendeeCapacity: p.attributes.remainingAttendeeCapacity }
448
- : undefined
449
- },
450
- $set: updateFields,
451
- // $unsetに対応(2022-08-31~)
452
- ...(p.$unset !== undefined) ? { $unset: p.$unset } : undefined
453
- },
454
- upsert
455
- }
456
- });
457
- }
458
- else if (p.attributes.typeOf === factory_1.factory.eventType.ScreeningEventSeries) {
459
- throw new factory_1.factory.errors.Internal('typeOf: ScreeningEventSeries discontinued');
460
- }
461
- });
462
- }
463
- if (bulkWriteOps.length > 0) {
464
- await this.eventModel.bulkWrite(bulkWriteOps, { ordered: false });
465
- }
466
- }
467
- // /**
468
- // * tttsイベントを識別子によって冪等作成する
469
- // */
470
- // public async saveEventByIdentifier4ttts(params: {
471
- // // oldEventId: string;
472
- // attributes: ICreatingEvent4ttts;
473
- // }): Promise<{ id: string }> {
474
- // // const { oldEventId } = params;
475
- // const { project, typeOf, eventStatus, identifier, organizer, ...updateFields } = params.attributes;
476
- // // const identifier = oldEventId;
477
- // if (typeof identifier !== 'string' || identifier.length === 0) {
478
- // throw new factory.errors.ArgumentNull('identifier');
479
- // }
480
- // const id = EventRepo.CREATE_ID();
481
- // const doc = await this.eventModel.findOneAndUpdate(
482
- // {
483
- // 'project.id': { $eq: project.id },
484
- // identifier: { $exists: true, $eq: identifier }
485
- // },
486
- // // upsertの場合、createがありうるので属性を除外しない
487
- // {
488
- // $setOnInsert: {
489
- // _id: id,
490
- // typeOf,
491
- // project,
492
- // eventStatus,
493
- // organizer,
494
- // identifier // イベントコードを必ず追加(2025-09-03~)
495
- // // ...(typeof identifier === 'string' && identifier !== '') ? { identifier } : undefined
496
- // },
497
- // $set: updateFields
498
- // },
499
- // { upsert: true, new: true, projection: { _id: 1 } }
500
- // )
501
- // .lean<{ _id: string }>()
502
- // .exec();
503
- // if (doc === null) {
504
- // throw new factory.errors.NotFound(this.eventModel.modelName);
505
- // }
506
- // return { id: doc._id }; // optimize(2024-07-31~)
507
- // }
508
223
  /**
509
224
  * イベントを検索する(inclusion projection)
510
225
  */
@@ -644,6 +359,9 @@ class EventRepo {
644
359
  }
645
360
  return doc.toObject();
646
361
  }
362
+ /**
363
+ * COAイベントキャンセル時に使用
364
+ */
647
365
  async searchEventIds(params) {
648
366
  const conditions = EventRepo.CREATE_MONGO_CONDITIONS(params);
649
367
  const query = this.eventModel.distinct('_id', { $and: conditions });
@@ -680,356 +398,5 @@ class EventRepo {
680
398
  }
681
399
  return doc;
682
400
  }
683
- /**
684
- * イベントをキャンセルする
685
- */
686
- async cancelEvent(params) {
687
- return this.eventModel.updateOne({
688
- _id: { $eq: params.id },
689
- 'project.id': { $eq: params.project.id }
690
- }, { $set: { eventStatus: factory_1.factory.eventStatusType.EventCancelled } }, {
691
- // includeResultMetadata: true
692
- })
693
- .exec();
694
- }
695
- /**
696
- * 興行イベントのsuperEventを最新の情報に同期する
697
- */
698
- async syncScreeningEventSeries2screeningEvents(params) {
699
- const superEvent = EventFactory.minimizeSuperEvent({ superEventFromDB: params.superEventFromDB });
700
- await this.eventModel.updateMany({
701
- typeOf: { $eq: factory_1.factory.eventType.ScreeningEvent },
702
- 'project.id': { $eq: params.project.id },
703
- 'superEvent.id': { $exists: true, $eq: params.superEventFromDB.id },
704
- startDate: { $gte: params.startDate.$gte }
705
- }, {
706
- $set: {
707
- superEvent
708
- }
709
- })
710
- .exec();
711
- }
712
- async deleteEventById(params) {
713
- await this.eventModel.findOneAndDelete({
714
- _id: params.id,
715
- 'project.id': { $eq: params.project.id }
716
- })
717
- .exec();
718
- }
719
- async deleteManyEventByOrganizerId(params) {
720
- return this.eventModel.deleteMany({
721
- 'project.id': { $eq: params.project.id },
722
- 'organizer.id': { $exists: true, $eq: params.organizer.id }
723
- })
724
- .exec();
725
- }
726
- async deleteManyEventsByScreeningRoom(params) {
727
- return this.eventModel.deleteMany({
728
- 'project.id': { $eq: params.project.id },
729
- 'location.branchCode': { $exists: true, $eq: params.location.branchCode },
730
- 'superEvent.location.id': { $exists: true, $eq: params.location.containedInPlace.id }
731
- })
732
- .exec();
733
- }
734
- async deleteManyBySuperEventId(params) {
735
- return this.eventModel.deleteMany({
736
- 'project.id': { $eq: params.project.id },
737
- 'superEvent.id': { $exists: true, $eq: params.superEvent.id }
738
- })
739
- .exec();
740
- }
741
- async deleteManyBySuperEventLocationId(params) {
742
- return this.eventModel.deleteMany({
743
- 'project.id': { $eq: params.project.id },
744
- 'superEvent.location.id': { $exists: true, $eq: params.superEvent.location.id }
745
- })
746
- .exec();
747
- }
748
- /**
749
- * 興行(プロダクト)から削除する
750
- */
751
- async deleteManyEventsByItemOfferedId(params) {
752
- return this.eventModel.deleteMany({
753
- 'project.id': { $eq: params.project.id },
754
- 'offers.itemOffered.id': { $exists: true, $in: params.offers.itemOffered.id.$in }
755
- })
756
- .exec();
757
- }
758
- async deleteManyEventsEndedByProject(params) {
759
- return this.eventModel.deleteMany({
760
- typeOf: { $in: params.typeOf.$in },
761
- 'project.id': { $eq: params.project.id },
762
- endDate: { $lte: params.endDate.$lte }
763
- })
764
- .exec();
765
- }
766
- async deleteManyEventsEnded(params) {
767
- return this.eventModel.deleteMany({
768
- typeOf: { $eq: params.typeOf.$eq },
769
- endDate: { $lte: params.endDate.$lte }
770
- })
771
- .exec();
772
- }
773
- async deleteByProject(params) {
774
- await this.eventModel.deleteMany({
775
- 'project.id': { $eq: params.project.id }
776
- })
777
- .exec();
778
- }
779
- /**
780
- * 集計属性を更新する
781
- */
782
- async updateAggregationById(params, update) {
783
- const doc = await this.eventModel.findOneAndUpdate({ _id: { $eq: params.id } }, update, {
784
- new: false,
785
- projection: { _id: 1 }
786
- })
787
- .lean()
788
- .exec();
789
- if (doc === null) {
790
- throw new factory_1.factory.errors.NotFound(this.eventModel.modelName);
791
- }
792
- }
793
- async bulkWrite(bulkWriteOps) {
794
- return this.eventModel.bulkWrite(bulkWriteOps, { ordered: false });
795
- }
796
- getCursor(conditions, projection) {
797
- return this.eventModel.find(conditions, projection)
798
- .sort({ startDate: factory_1.factory.sortType.Descending })
799
- .cursor();
800
- }
801
- // /**
802
- // * アプリケーションオファー廃止用のメソッド
803
- // */
804
- // public async removeAvailableAtOrFrom(params: {
805
- // id: string;
806
- // offers: {
807
- // seller: {
808
- // makesOffer: Pick<factory.event.screeningEvent.ISellerMakesOffer, 'availableAtOrFrom'>;
809
- // };
810
- // };
811
- // }) {
812
- // return this.eventModel.updateOne(
813
- // { _id: { $eq: params.id } },
814
- // {
815
- // $pull: {
816
- // 'offers.seller.makesOffer': {
817
- // 'availableAtOrFrom.id': { $eq: params.offers.seller.makesOffer.availableAtOrFrom.id }
818
- // }
819
- // }
820
- // }
821
- // )
822
- // .exec();
823
- // }
824
- async unsetUnnecessaryFields(params) {
825
- return this.eventModel.updateMany(params.filter, { $unset: params.$unset }, { timestamps: false })
826
- .exec();
827
- }
828
- async aggregateEvent(params) {
829
- const statuses = await Promise.all([
830
- factory_1.factory.eventStatusType.EventScheduled,
831
- factory_1.factory.eventStatusType.EventCancelled,
832
- factory_1.factory.eventStatusType.EventPostponed
833
- ].map(async (eventStatus) => {
834
- const matchConditions = {
835
- startDate: {
836
- $gte: params.startFrom,
837
- $lte: params.startThrough
838
- },
839
- typeOf: { $eq: params.typeOf },
840
- eventStatus: { $eq: eventStatus },
841
- ...(typeof params.project?.id?.$ne === 'string')
842
- ? { 'project.id': { $ne: params.project.id.$ne } }
843
- : undefined
844
- };
845
- return this.agggregateByStatus({ matchConditions, status: eventStatus });
846
- }));
847
- return { statuses };
848
- }
849
- async agggregateByStatus(params) {
850
- const matchConditions = params.matchConditions;
851
- const eventStatus = params.status;
852
- const aggregations = await this.eventModel.aggregate([
853
- {
854
- $match: matchConditions
855
- },
856
- {
857
- $project: {
858
- remainingCapacityRate: {
859
- $cond: {
860
- if: {
861
- $and: [
862
- { $isNumber: '$maximumAttendeeCapacity' },
863
- { $isNumber: '$remainingAttendeeCapacity' }
864
- ]
865
- },
866
- then: {
867
- $cond: {
868
- if: { $gt: ['$maximumAttendeeCapacity', 0] },
869
- then: {
870
- $multiply: [
871
- { $divide: ['$remainingAttendeeCapacity', '$maximumAttendeeCapacity'] },
872
- 100
873
- ]
874
- },
875
- else: 0
876
- }
877
- },
878
- else: 0
879
- }
880
- },
881
- eventStatus: '$eventStatus',
882
- startDate: '$startDate',
883
- endDate: '$endDate',
884
- typeOf: '$typeOf',
885
- maximumAttendeeCapacity: {
886
- $cond: {
887
- if: { $isNumber: '$maximumAttendeeCapacity' },
888
- then: '$maximumAttendeeCapacity',
889
- else: 0
890
- }
891
- },
892
- remainingAttendeeCapacity: {
893
- $cond: {
894
- if: { $isNumber: '$remainingAttendeeCapacity' },
895
- then: '$remainingAttendeeCapacity',
896
- else: 0
897
- }
898
- },
899
- reservationCount: {
900
- $cond: {
901
- if: { $isNumber: '$aggregateReservation.reservationCount' },
902
- then: '$aggregateReservation.reservationCount',
903
- else: 0
904
- }
905
- },
906
- offerCount: {
907
- $cond: {
908
- if: { $isNumber: '$aggregateOffer.offerCount' },
909
- then: '$aggregateOffer.offerCount',
910
- else: 0
911
- }
912
- }
913
- }
914
- },
915
- {
916
- $group: {
917
- _id: '$typeOf',
918
- eventCount: { $sum: 1 },
919
- reservationCount: { $sum: '$reservationCount' },
920
- avgOfferCount: { $avg: '$offerCount' },
921
- maximumAttendeeCapacity: { $sum: '$maximumAttendeeCapacity' },
922
- remainingAttendeeCapacity: { $sum: '$remainingAttendeeCapacity' },
923
- avgRemainingCapacityRate: { $avg: '$remainingCapacityRate' },
924
- maxRemainingCapacityRate: { $max: '$remainingCapacityRate' },
925
- minRemainingCapacityRate: { $min: '$remainingCapacityRate' }
926
- }
927
- },
928
- {
929
- $project: {
930
- _id: 0,
931
- eventCount: '$eventCount',
932
- reservationCount: '$reservationCount',
933
- avgOfferCount: '$avgOfferCount',
934
- maximumAttendeeCapacity: '$maximumAttendeeCapacity',
935
- remainingAttendeeCapacity: '$remainingAttendeeCapacity',
936
- avgRemainingCapacityRate: '$avgRemainingCapacityRate',
937
- maxRemainingCapacityRate: '$maxRemainingCapacityRate',
938
- minRemainingCapacityRate: '$minRemainingCapacityRate'
939
- }
940
- }
941
- ])
942
- .exec();
943
- const percents = [50, 95, 99];
944
- if (aggregations.length === 0) {
945
- return {
946
- status: eventStatus,
947
- aggregation: {
948
- eventCount: 0,
949
- reservationCount: 0,
950
- avgOfferCount: 0,
951
- maximumAttendeeCapacity: 0,
952
- remainingAttendeeCapacity: 0,
953
- avgRemainingCapacityRate: 0,
954
- maxRemainingCapacityRate: 0,
955
- minRemainingCapacityRate: 0,
956
- percentilesRemainingCapacityRate: percents.map((percent) => {
957
- return {
958
- name: String(percent),
959
- value: 0
960
- };
961
- })
962
- }
963
- };
964
- }
965
- const ranks4percentile = percents.map((percentile) => {
966
- return {
967
- percentile,
968
- rank: Math.floor(aggregations[0].eventCount * percentile / 100)
969
- };
970
- });
971
- const aggregations2 = await this.eventModel.aggregate([
972
- {
973
- $match: matchConditions
974
- },
975
- {
976
- $project: {
977
- remainingCapacityRate: {
978
- $cond: {
979
- if: {
980
- $and: [
981
- { $isNumber: '$maximumAttendeeCapacity' },
982
- { $isNumber: '$remainingAttendeeCapacity' }
983
- ]
984
- },
985
- then: {
986
- $cond: {
987
- if: { $gt: ['$maximumAttendeeCapacity', 0] },
988
- then: {
989
- $multiply: [
990
- { $divide: ['$remainingAttendeeCapacity', '$maximumAttendeeCapacity'] },
991
- 100
992
- ]
993
- },
994
- else: 0
995
- }
996
- },
997
- else: 0
998
- }
999
- },
1000
- eventStatus: '$eventStatus',
1001
- startDate: '$startDate',
1002
- endDate: '$endDate',
1003
- typeOf: '$typeOf'
1004
- }
1005
- },
1006
- { $sort: { remainingCapacityRate: 1 } },
1007
- {
1008
- $group: {
1009
- _id: '$typeOf',
1010
- remainingCapacityRates: { $push: '$remainingCapacityRate' }
1011
- }
1012
- },
1013
- {
1014
- $project: {
1015
- _id: 0,
1016
- percentilesRemainingCapacityRate: ranks4percentile.map((rank) => {
1017
- return {
1018
- name: String(rank.percentile),
1019
- value: { $arrayElemAt: ['$remainingCapacityRates', rank.rank] }
1020
- };
1021
- })
1022
- }
1023
- }
1024
- ])
1025
- .exec();
1026
- return {
1027
- status: eventStatus,
1028
- aggregation: {
1029
- ...aggregations[0],
1030
- ...aggregations2[0]
1031
- }
1032
- };
1033
- }
1034
401
  }
1035
402
  exports.EventRepo = EventRepo;