@chevre/domain 22.9.0-alpha.115 → 22.9.0-alpha.117

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.
@@ -0,0 +1,92 @@
1
+ // tslint:disable:no-console
2
+ import * as mongoose from 'mongoose';
3
+
4
+ import { chevre } from '../../../../lib/index';
5
+
6
+ const project = { id: String(process.env.PROJECT_ID) };
7
+ const NUM_CREATE_OFFERS = 300;
8
+
9
+ // tslint:disable-next-line:max-func-body-length
10
+ async function main() {
11
+ await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
12
+
13
+ const aggregateOfferRepo = await chevre.repository.AggregateOffer.createInstance(mongoose.connection);
14
+ const offerCatalogRepo = await chevre.repository.OfferCatalog.createInstance(mongoose.connection);
15
+ const productRepo = await chevre.repository.Product.createInstance(mongoose.connection);
16
+ // const offerCatalogItemRepo = await chevre.repository.OfferCatalogItem.createInstance(mongoose.connection);
17
+
18
+ const savingOffers: Omit<chevre.factory.unitPriceOffer.IUnitPriceOffer, 'id'>[] =
19
+ // tslint:disable-next-line:prefer-array-literal
20
+ [...Array(NUM_CREATE_OFFERS)].map<Omit<chevre.factory.unitPriceOffer.IUnitPriceOffer, 'id'>>((__, i) => {
21
+ const identifier = `sampleFreeOffer${i}`;
22
+ const priceSpecification: chevre.factory.unitPriceOffer.IUnitPriceOfferPriceSpecification = {
23
+ typeOf: chevre.factory.priceSpecificationType.UnitPriceSpecification,
24
+ priceCurrency: chevre.factory.priceCurrency.JPY,
25
+ valueAddedTaxIncluded: true,
26
+ price: 0,
27
+ referenceQuantity: {
28
+ value: 1,
29
+ typeOf: 'QuantitativeValue',
30
+ unitCode: chevre.factory.unitCode.C62
31
+ },
32
+ accounting: {
33
+ typeOf: 'Accounting',
34
+ accountsReceivable: 0
35
+ }
36
+ };
37
+
38
+ return {
39
+ project: { id: project.id, typeOf: chevre.factory.organizationType.Project },
40
+ typeOf: chevre.factory.offerType.Offer,
41
+ identifier,
42
+ description: { en: identifier, ja: identifier },
43
+ alternateName: { ja: identifier },
44
+ name: { en: identifier, ja: identifier },
45
+ availability: chevre.factory.itemAvailability.InStock,
46
+ availableAtOrFrom: [
47
+ { id: '51qbjcfr72h62m06vtv5kkhgje' }
48
+ ],
49
+ itemOffered: { typeOf: chevre.factory.product.ProductType.EventService },
50
+ priceCurrency: chevre.factory.priceCurrency.JPY,
51
+ priceSpecification
52
+ };
53
+ });
54
+ const saveOfferResult = await aggregateOfferRepo.upsertByIdentifier(savingOffers);
55
+ console.log('saveOfferResult:', saveOfferResult);
56
+
57
+ const offerIds: string[] = (Array.isArray(saveOfferResult?.modifiedOffers)) ? saveOfferResult.modifiedOffers.map(({ id }) => id) : [];
58
+ const catalogIdentifier = 'sampleFreeOffersCatalog';
59
+ const savingOfferCatalog: chevre.factory.offerCatalog.IOfferCatalog = {
60
+ project: { id: project.id, typeOf: chevre.factory.organizationType.Project },
61
+ typeOf: 'OfferCatalog',
62
+ identifier: catalogIdentifier,
63
+ description: { en: catalogIdentifier, ja: catalogIdentifier },
64
+ name: { en: catalogIdentifier, ja: catalogIdentifier },
65
+ itemListElement: offerIds.map((id) => ({ id, typeOf: chevre.factory.offerType.Offer })),
66
+ itemOffered: { typeOf: chevre.factory.product.ProductType.EventService }
67
+ };
68
+ const saveCatalogResult = await offerCatalogRepo.saveByIdentifier(savingOfferCatalog);
69
+ console.log('saveCatalogResult:', saveCatalogResult);
70
+
71
+ const productId = 'sampleFreeEventService';
72
+ const savingProduct: chevre.factory.product.IProduct & {
73
+ offers?: never;
74
+ } = {
75
+ project: { id: project.id, typeOf: chevre.factory.organizationType.Project },
76
+ typeOf: chevre.factory.product.ProductType.EventService,
77
+ name: { en: productId, ja: productId },
78
+ productID: productId,
79
+ hasOfferCatalog: {
80
+ typeOf: 'OfferCatalog',
81
+ itemListElement: [{ id: saveCatalogResult.id }]
82
+ }
83
+ };
84
+ const saveProductResult = await productRepo.upsertManyByProductId([{
85
+ $set: savingProduct
86
+ }]);
87
+ console.log('saveProductResult:', saveProductResult);
88
+ }
89
+
90
+ main()
91
+ .then()
92
+ .catch(console.error);
@@ -0,0 +1,54 @@
1
+ // tslint:disable:no-console
2
+ import * as mongoose from 'mongoose';
3
+
4
+ import { chevre } from '../../../../lib/index';
5
+
6
+ // const project = { id: String(process.env.PROJECT_ID) };
7
+
8
+ const formatter = new Intl.NumberFormat('ja-JP');
9
+
10
+ // tslint:disable-next-line:max-func-body-length
11
+ async function main() {
12
+ let startTime: [number, number] = process.hrtime();
13
+ let diff: [number, number] = process.hrtime(startTime);
14
+ let result: any;
15
+
16
+ await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
17
+
18
+ const offerCatalogRepo = await chevre.repository.OfferCatalog.createInstance(mongoose.connection);
19
+ const offerCatalogItemRepo = await chevre.repository.OfferCatalogItem.createInstance(mongoose.connection);
20
+
21
+ // startTime = process.hrtime();
22
+ // result = await offerCatalogRepo.searchItemListElementById({
23
+ // id: 'blpc770py',
24
+ // limit: 100,
25
+ // page: 1
26
+ // });
27
+ // diff = process.hrtime(startTime);
28
+ // console.log('diff:', [diff[0], formatter.format(diff[1])]);
29
+ // console.log('result:', result);
30
+
31
+ startTime = process.hrtime();
32
+ result = await offerCatalogRepo.sliceItemListElementById({
33
+ id: 'blpc770py',
34
+ limit: 10,
35
+ page: 1
36
+ });
37
+ diff = process.hrtime(startTime);
38
+ console.log('diff:', [diff[0], formatter.format(diff[1])]);
39
+ console.log('result:', result);
40
+
41
+ startTime = process.hrtime();
42
+ result = await offerCatalogItemRepo.sliceItemListElementById({
43
+ id: '65669285c7b871dba60ed72e',
44
+ limit: 10,
45
+ page: 1
46
+ });
47
+ diff = process.hrtime(startTime);
48
+ console.log('diff:', [diff[0], formatter.format(diff[1])]);
49
+ console.log('result:', result);
50
+ }
51
+
52
+ main()
53
+ .then()
54
+ .catch(console.error);
@@ -0,0 +1,44 @@
1
+ // tslint:disable:no-console
2
+ import * as mongoose from 'mongoose';
3
+
4
+ import { chevre } from '../../../../lib/index';
5
+
6
+ // const project = { id: String(process.env.PROJECT_ID) };
7
+
8
+ mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
9
+
10
+ // tslint:disable-next-line:max-func-body-length
11
+ async function main() {
12
+ const offerRepo = await chevre.repository.Offer.createInstance(mongoose.connection);
13
+
14
+ const result = await offerRepo.searchByOfferCatalogIdWithSortIndex({
15
+ offerCatalog: { id: '65669285c7b871dba60ed72e', isOfferCatalogItem: true },
16
+ // availableAtOrFrom: { id: params.store?.id },
17
+ // unacceptedPaymentMethod: params.unacceptedPaymentMethod,
18
+ excludeAppliesToMovieTicket: false,
19
+ priceSpecification: {
20
+ appliesToMovieTicket: {
21
+ // serviceOutput: {
22
+ // typeOf: {
23
+ // ...(typeof req.query.priceSpecification?.appliesToMovieTicket?.serviceOutput?.typeOf?.$eq === 'string')
24
+ // ? { $eq: req.query.priceSpecification.appliesToMovieTicket.serviceOutput.typeOf.$eq }
25
+ // : undefined
26
+ // }
27
+ // },
28
+ serviceType: {
29
+ $exists: false
30
+ }
31
+ }
32
+ },
33
+ onlyValid: false,
34
+ useIncludeInDataCatalog: true,
35
+ limit: 10,
36
+ page: 1
37
+ });
38
+ console.log('result:', result);
39
+ console.log(result.offers.map(({ name }) => name));
40
+ }
41
+
42
+ main()
43
+ .then()
44
+ .catch(console.error);
@@ -0,0 +1,68 @@
1
+ // tslint:disable:no-console
2
+ import * as mongoose from 'mongoose';
3
+
4
+ import { chevre } from '../../../../lib/index';
5
+
6
+ const formatter = new Intl.NumberFormat('ja-JP');
7
+
8
+ // const PROJECT_ID = process.env.PROJECT_ID;
9
+ mongoose.Model.on('index', (...args) => {
10
+ console.error('******** index event emitted. ********\n', args);
11
+ });
12
+
13
+ async function main() {
14
+ let startTime: [number, number] = process.hrtime();
15
+ let diff: [number, number] = process.hrtime(startTime);
16
+ let result: any;
17
+
18
+ await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
19
+
20
+ const eventRepo = await chevre.repository.Event.createInstance(mongoose.connection);
21
+ const offerRepo = await chevre.repository.Offer.createInstance(mongoose.connection);
22
+ const offerCatalogRepo = await chevre.repository.OfferCatalog.createInstance(mongoose.connection);
23
+ const productRepo = await chevre.repository.Product.createInstance(mongoose.connection);
24
+
25
+ // startTime = process.hrtime();
26
+ // result = await (await chevre.service.offer.createService()).event.searchOfferCatalogItemAvailability({
27
+ // event: {
28
+ // id: 'cm8dwc74j'
29
+ // },
30
+ // limit: 10,
31
+ // page: 1,
32
+ // availableAtOrFrom: { id: '51qbjcfr72h62m06vtv5kkhgje' },
33
+ // options: { considerUnacceptedPaymentMethod: true, useIncludeInDataCatalog: true }
34
+ // })({
35
+ // event: eventRepo,
36
+ // offer: offerRepo,
37
+ // offerCatalog: offerCatalogRepo,
38
+ // product: productRepo
39
+ // });
40
+ // diff = process.hrtime(startTime);
41
+ // console.log(result);
42
+ // console.log(result.length);
43
+ // console.log('diff:', [diff[0], formatter.format(diff[1])]);
44
+
45
+ startTime = process.hrtime();
46
+ result = await (await chevre.service.offer.createService()).event.searchOfferCatalogItemAvailability({
47
+ event: {
48
+ id: 'cm8dwc74j'
49
+ },
50
+ limit: 10,
51
+ page: 1,
52
+ availableAtOrFrom: { id: '51qbjcfr72h62m06vtv5kkhgje' },
53
+ options: { considerUnacceptedPaymentMethod: true, useIncludeInDataCatalog: false }
54
+ })({
55
+ event: eventRepo,
56
+ offer: offerRepo,
57
+ offerCatalog: offerCatalogRepo,
58
+ product: productRepo
59
+ });
60
+ diff = process.hrtime(startTime);
61
+ console.log(result);
62
+ console.log(result.length);
63
+ console.log('diff:', [diff[0], formatter.format(diff[1])]);
64
+ }
65
+
66
+ main()
67
+ .then(console.log)
68
+ .catch(console.error);
@@ -84,27 +84,27 @@ const indexes = [
84
84
  [
85
85
  { identifier: 1, dateCreated: -1 },
86
86
  { name: 'identifier' }
87
- ],
88
- // tslint:disable-next-line:no-suspicious-comment
89
- [
90
- { identifier: 1 },
91
- { name: 'searchByIdentifier' }
92
- ],
93
- // tslint:disable-next-line:no-suspicious-comment
94
- [
95
- { 'project.id': 1, identifier: 1 },
96
- { name: 'searchByProjectId' }
97
- ],
98
- // tslint:disable-next-line:no-suspicious-comment
99
- [
100
- { 'provider.id': 1, identifier: 1 },
101
- { name: 'searchByProviderId' }
102
- ],
103
- // tslint:disable-next-line:no-suspicious-comment
104
- [
105
- { 'about.id': 1, identifier: 1 },
106
- { name: 'searchByAboutId' }
107
87
  ]
88
+ // discontinue(2025-05-08~)
89
+ // [
90
+ // { identifier: 1 },
91
+ // { name: 'searchByIdentifier' }
92
+ // ],
93
+ // discontinue(2025-05-08~)
94
+ // [
95
+ // { 'project.id': 1, identifier: 1 },
96
+ // { name: 'searchByProjectId' }
97
+ // ],
98
+ // discontinue(2025-05-08~)
99
+ // [
100
+ // { 'provider.id': 1, identifier: 1 },
101
+ // { name: 'searchByProviderId' }
102
+ // ],
103
+ // discontinue(2025-05-08~)
104
+ // [
105
+ // { 'about.id': 1, identifier: 1 },
106
+ // { name: 'searchByAboutId' }
107
+ // ]
108
108
  ];
109
109
  exports.indexes = indexes;
110
110
  /**
@@ -122,6 +122,21 @@ export declare class OfferRepo implements OfferInCatalogReadOnlyRepo {
122
122
  }): Promise<{
123
123
  id: string;
124
124
  }[]>;
125
+ /**
126
+ * サブカタログがクライアントで利用可能かどうか
127
+ */
128
+ isCatalogAvailable(params: {
129
+ includedInDataCatalog: {
130
+ /**
131
+ * サブカタログID
132
+ */
133
+ id: string;
134
+ };
135
+ availableAtOrFrom: {
136
+ id: string;
137
+ };
138
+ unacceptedPaymentMethod: string[];
139
+ }): Promise<boolean>;
125
140
  count(params: Omit<factory.unitPriceOffer.ISearchConditions, 'limit' | 'page' | 'sort'>): Promise<number>;
126
141
  search(params: factory.unitPriceOffer.ISearchConditions, projection?: IProjection): Promise<IOfferInCatalog[]>;
127
142
  /**
@@ -308,6 +308,36 @@ class OfferRepo {
308
308
  return aggregate.exec();
309
309
  });
310
310
  }
311
+ /**
312
+ * サブカタログがクライアントで利用可能かどうか
313
+ */
314
+ isCatalogAvailable(params) {
315
+ return __awaiter(this, void 0, void 0, function* () {
316
+ const { unacceptedPaymentMethod } = params;
317
+ // サブカタログのみ対応でよい
318
+ const offerCatalogItem = yield this.offerCatalogItemModel.findOne({ _id: { $eq: params.includedInDataCatalog.id } }, { _id: 0, itemListElement: 1 })
319
+ .lean()
320
+ .exec();
321
+ const offerIds = offerCatalogItem === null || offerCatalogItem === void 0 ? void 0 : offerCatalogItem.itemListElement.map(({ id }) => id);
322
+ if (!Array.isArray(offerIds) || offerIds.length === 0) {
323
+ return false;
324
+ }
325
+ const doc = yield this.aggregateOfferModel.findOne(Object.assign({
326
+ // 'project.id': { $eq: params.project.id },
327
+ _id: { $in: offerIds }, 'offers.availableAtOrFrom.id': { $exists: true, $eq: params.availableAtOrFrom.id } }, (Array.isArray(unacceptedPaymentMethod) && unacceptedPaymentMethod.length > 0)
328
+ ? {
329
+ 'offers.priceSpecification.appliesToMovieTicket.serviceOutput.typeOf': {
330
+ $nin: unacceptedPaymentMethod
331
+ }
332
+ }
333
+ : undefined), {
334
+ _id: 1
335
+ })
336
+ .lean()
337
+ .exec();
338
+ return doc !== null;
339
+ });
340
+ }
311
341
  count(params) {
312
342
  return __awaiter(this, void 0, void 0, function* () {
313
343
  const matchStages = aggregateOffer_1.AggregateOfferRepo.CREATE_MATCH_STAGE(params);
@@ -101,8 +101,16 @@ export declare class OfferCatalogRepo {
101
101
  }): Promise<factory.offerCatalog.IItemListElement>;
102
102
  /**
103
103
  * カタログのitemListElementをpaging有で検索する
104
+ * reimplement as sliceItemListElementById(2025-05-06=)
104
105
  */
105
- searchItemListElementById(params: {
106
+ /**
107
+ * カタログのitemListElementをpaging有で検索する
108
+ * reimplement using $slice(2025-05-06=)
109
+ */
110
+ sliceItemListElementById(params: {
111
+ /**
112
+ * カタログID
113
+ */
106
114
  id: string;
107
115
  limit: number;
108
116
  page: number;
@@ -35,6 +35,7 @@ const AVAILABLE_PROJECT_FIELDS = [
35
35
  'itemListElementTypeOf',
36
36
  'dateSynced'
37
37
  ];
38
+ const SLICE_ITEM_LIST_ELEMENT_MAX_LIMIT = 100;
38
39
  /**
39
40
  * カタログリポジトリ
40
41
  */
@@ -393,30 +394,57 @@ class OfferCatalogRepo {
393
394
  }
394
395
  /**
395
396
  * カタログのitemListElementをpaging有で検索する
397
+ * reimplement as sliceItemListElementById(2025-05-06=)
396
398
  */
397
- searchItemListElementById(params) {
399
+ // public async searchItemListElementById(params: {
400
+ // id: string;
401
+ // limit: number;
402
+ // page: number;
403
+ // }): Promise<{ id: string; elementIndex: number }[]> {
404
+ // const page: number = (typeof params.page === 'number' && params.page > 0) ? params.page : 1;
405
+ // const matchStages: IMatchStage[] = [{ $match: { _id: { $eq: params.id } } }];
406
+ // return this.offerCatalogModel.aggregate<{ id: string; elementIndex: number }>([
407
+ // {
408
+ // $unwind: {
409
+ // path: '$itemListElement',
410
+ // includeArrayIndex: 'elementIndex'
411
+ // }
412
+ // },
413
+ // ...matchStages,
414
+ // {
415
+ // $project: {
416
+ // _id: 0,
417
+ // id: '$itemListElement.id',
418
+ // elementIndex: '$elementIndex'
419
+ // }
420
+ // }
421
+ // ])
422
+ // .limit(params.limit * page)
423
+ // .skip(params.limit * (page - 1))
424
+ // .exec();
425
+ // }
426
+ /**
427
+ * カタログのitemListElementをpaging有で検索する
428
+ * reimplement using $slice(2025-05-06=)
429
+ */
430
+ sliceItemListElementById(params) {
398
431
  return __awaiter(this, void 0, void 0, function* () {
399
- const page = (typeof params.page === 'number' && params.page > 0) ? params.page : 1;
400
- const matchStages = [{ $match: { _id: { $eq: params.id } } }];
401
- return this.offerCatalogModel.aggregate([
402
- {
403
- $unwind: {
404
- path: '$itemListElement',
405
- includeArrayIndex: 'elementIndex'
406
- }
407
- },
408
- ...matchStages,
409
- {
410
- $project: {
411
- _id: 0,
412
- id: '$itemListElement.id',
413
- elementIndex: '$elementIndex'
414
- }
415
- }
416
- ])
417
- .limit(params.limit * page)
418
- .skip(params.limit * (page - 1))
432
+ const { id, limit, page } = params;
433
+ if (limit < 1 || limit > SLICE_ITEM_LIST_ELEMENT_MAX_LIMIT) {
434
+ throw new factory.errors.Argument('limit', `must be >=1 and <=${SLICE_ITEM_LIST_ELEMENT_MAX_LIMIT}`);
435
+ }
436
+ const pageMustBePositive = (typeof page === 'number' && page > 0) ? page : 1;
437
+ const skip = params.limit * (pageMustBePositive - 1);
438
+ const doc = yield this.offerCatalogModel.findOne({ _id: { $eq: id } }, {
439
+ _id: 1,
440
+ itemListElement: { $slice: [skip, limit] }
441
+ })
442
+ .lean()
419
443
  .exec();
444
+ // console.log(doc);
445
+ return (doc !== null)
446
+ ? doc.itemListElement.map((item, i) => ({ id: item.id, elementIndex: i + skip }))
447
+ : [];
420
448
  });
421
449
  }
422
450
  /**
@@ -77,6 +77,21 @@ export declare class OfferCatalogItemRepo {
77
77
  id: string;
78
78
  }[];
79
79
  }>;
80
+ /**
81
+ * カタログのitemListElementをpaging有で検索する
82
+ * reimplement using $slice(2025-05-06=)
83
+ */
84
+ sliceItemListElementById(params: {
85
+ /**
86
+ * カタログID
87
+ */
88
+ id: string;
89
+ limit: number;
90
+ page: number;
91
+ }): Promise<{
92
+ id: string;
93
+ elementIndex: number;
94
+ }[]>;
80
95
  deleteById(params: {
81
96
  id: string;
82
97
  }): Promise<void>;
@@ -37,6 +37,7 @@ const AVAILABLE_PROJECT_FIELDS = [
37
37
  'dateSynced',
38
38
  'relatedOffer'
39
39
  ];
40
+ const SLICE_ITEM_LIST_ELEMENT_MAX_LIMIT = 100;
40
41
  /**
41
42
  * サブカタログリポジトリ
42
43
  */
@@ -365,6 +366,30 @@ class OfferCatalogItemRepo {
365
366
  return doc;
366
367
  });
367
368
  }
369
+ /**
370
+ * カタログのitemListElementをpaging有で検索する
371
+ * reimplement using $slice(2025-05-06=)
372
+ */
373
+ sliceItemListElementById(params) {
374
+ return __awaiter(this, void 0, void 0, function* () {
375
+ const { id, limit, page } = params;
376
+ if (limit < 1 || limit > SLICE_ITEM_LIST_ELEMENT_MAX_LIMIT) {
377
+ throw new factory.errors.Argument('limit', `must be >=1 and <=${SLICE_ITEM_LIST_ELEMENT_MAX_LIMIT}`);
378
+ }
379
+ const pageMustBePositive = (typeof page === 'number' && page > 0) ? page : 1;
380
+ const skip = params.limit * (pageMustBePositive - 1);
381
+ const doc = yield this.offerCatalogItemModel.findOne({ _id: { $eq: id } }, {
382
+ _id: 1,
383
+ itemListElement: { $slice: [skip, limit] }
384
+ })
385
+ .lean()
386
+ .exec();
387
+ // console.log(doc);
388
+ return (doc !== null)
389
+ ? doc.itemListElement.map((item, i) => ({ id: item.id, elementIndex: i + skip }))
390
+ : [];
391
+ });
392
+ }
368
393
  deleteById(params) {
369
394
  return __awaiter(this, void 0, void 0, function* () {
370
395
  yield this.offerCatalogItemModel.findOneAndDelete({ _id: { $eq: params.id } }, { projection: { _id: 1 } })
@@ -86,6 +86,15 @@ export declare class PendingReservationRepo implements AbstractStockHolderRepo {
86
86
  $eq: string;
87
87
  };
88
88
  }): Promise<IProjectSubReservationResult[]>;
89
+ /**
90
+ * expiresを最新の情報に同期する
91
+ */
92
+ syncEvent2expires(params: {
93
+ expires: Date;
94
+ reservationFor: {
95
+ id: string;
96
+ };
97
+ }): Promise<import("mongoose").UpdateWriteOpResult>;
89
98
  private aggregateNumSeats;
90
99
  private createReservationPackageIfPossible;
91
100
  private deleteReservationPackage;
@@ -468,6 +468,24 @@ class PendingReservationRepo {
468
468
  .exec();
469
469
  });
470
470
  }
471
+ /**
472
+ * expiresを最新の情報に同期する
473
+ */
474
+ syncEvent2expires(params) {
475
+ return __awaiter(this, void 0, void 0, function* () {
476
+ const { expires, reservationFor } = params;
477
+ if (!(expires instanceof Date)) {
478
+ throw new factory.errors.Argument('expires', 'must be Date');
479
+ }
480
+ return this.pendingReservationModel.updateMany({
481
+ 'reservationFor.id': { $eq: reservationFor.id },
482
+ numSeats: { $gte: 1 } // numSeats:0についてはもはや不要なドキュメントなので除外
483
+ }, {
484
+ $set: { expires }
485
+ })
486
+ .exec();
487
+ });
488
+ }
471
489
  aggregateNumSeats(params) {
472
490
  return __awaiter(this, void 0, void 0, function* () {
473
491
  const { bookingTime, dateCreated, reservationFor, limit } = params;
@@ -859,9 +859,7 @@ function createScreeningRoomFromCOA(project, seller, screenFromCOA) {
859
859
  };
860
860
  }
861
861
  function updateEvent4ttts(params) {
862
- return (repos
863
- // settings: Settings
864
- ) => __awaiter(this, void 0, void 0, function* () {
862
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
865
863
  const actionAttributes = Object.assign({ project: { typeOf: factory.organizationType.Project, id: params.project.id }, typeOf: factory.actionType.UpdateAction, agent: params.agent, object: {
866
864
  id: params.oldEventId,
867
865
  typeOf: factory.eventType.ScreeningEvent
@@ -899,7 +897,7 @@ function updateEvent4ttts(params) {
899
897
  isNew: false,
900
898
  useInform: true
901
899
  })(repos
902
- // settings
900
+ // スケジュールによるイベント作成ではendDateに変更がないのでpendingReservationsへの同期はひとまず必要なし
903
901
  );
904
902
  });
905
903
  }
@@ -38,6 +38,7 @@ declare function searchOfferCatalogItemAvailability(params: {
38
38
  */
39
39
  id: string;
40
40
  };
41
+ useIncludeInDataCatalog: boolean;
41
42
  };
42
43
  }): (repos: {
43
44
  event: EventRepo;
@@ -21,20 +21,26 @@ function getUnacceptedPaymentMethodByEvent(params) {
21
21
  }
22
22
  return unacceptedPaymentMethod;
23
23
  }
24
+ const MAX_LIMIT_SEARCH_OFFER_CATALOG_ITEMS = 10;
24
25
  /**
25
26
  * サブカタログ利用可能性検索
26
27
  */
27
28
  // tslint:disable-next-line:max-func-body-length
28
29
  function searchOfferCatalogItemAvailability(params) {
30
+ // tslint:disable-next-line:max-func-body-length
29
31
  return (repos) => __awaiter(this, void 0, void 0, function* () {
30
32
  var _a, _b, _c, _d;
31
- const { considerUnacceptedPaymentMethod } = params.options;
33
+ const { considerUnacceptedPaymentMethod, useIncludeInDataCatalog } = params.options;
32
34
  if (typeof params.limit !== 'number') {
33
35
  throw new factory.errors.Argument('limit', 'must be number');
34
36
  }
35
37
  if (typeof params.page !== 'number') {
36
38
  throw new factory.errors.Argument('page', 'must be number');
37
39
  }
40
+ // オファー検索時の_id条件がitemListElementCount * MAX_LIMIT_SEARCH_OFFER_CATALOG_ITEMS以下になるように制限
41
+ if (params.limit > MAX_LIMIT_SEARCH_OFFER_CATALOG_ITEMS) {
42
+ throw new factory.errors.Argument('limit', `must be <=${MAX_LIMIT_SEARCH_OFFER_CATALOG_ITEMS}`);
43
+ }
38
44
  let availabilities = [];
39
45
  // optimize(2024-07-18~)
40
46
  const event = yield repos.event.projectEventFieldsById({ id: params.event.id }, ['project', 'offers.itemOffered.id', 'offers.unacceptedPaymentMethod']);
@@ -78,26 +84,41 @@ function searchOfferCatalogItemAvailability(params) {
78
84
  }
79
85
  const offerCatalogFirstElement = yield repos.offerCatalog.findFirstItemListElementById({ id: catalogId });
80
86
  if (offerCatalogFirstElement.typeOf === 'OfferCatalog') {
81
- const catalogItemListElements = yield repos.offerCatalog.searchItemListElementById({
87
+ const catalogItemListElements = yield repos.offerCatalog.sliceItemListElementById({
82
88
  id: catalogId,
83
89
  limit: params.limit,
84
90
  page: params.page
85
91
  });
86
92
  const unacceptedPaymentMethod = getUnacceptedPaymentMethodByEvent({ event });
87
93
  if (catalogItemListElements.length > 0) {
88
- // 単価オファーから利用可能なサブカタログを検索
89
- const availableCatalogs = yield repos.offer.searchAvailableCatalogs({
90
- project: { id: event.project.id },
91
- includedInDataCatalog: { id: catalogItemListElements.map((element) => element.id) },
92
- availableAtOrFrom: { id: params.availableAtOrFrom.id },
93
- unacceptedPaymentMethod: (considerUnacceptedPaymentMethod) ? unacceptedPaymentMethod : []
94
- });
95
- availabilities = catalogItemListElements.map((element) => {
96
- return {
97
- id: element.id,
98
- isAvailable: availableCatalogs.some((item) => item.id === element.id)
99
- };
100
- });
94
+ if (useIncludeInDataCatalog) {
95
+ // 単価オファーから利用可能なサブカタログを検索
96
+ const availableCatalogs = yield repos.offer.searchAvailableCatalogs({
97
+ project: { id: event.project.id },
98
+ includedInDataCatalog: { id: catalogItemListElements.map((element) => element.id) },
99
+ availableAtOrFrom: { id: params.availableAtOrFrom.id },
100
+ unacceptedPaymentMethod: (considerUnacceptedPaymentMethod) ? unacceptedPaymentMethod : []
101
+ });
102
+ availabilities = catalogItemListElements.map((element) => {
103
+ return {
104
+ id: element.id,
105
+ isAvailable: availableCatalogs.some((item) => item.id === element.id)
106
+ };
107
+ });
108
+ }
109
+ else {
110
+ // support no dependency on includedInDataCatalog(2025-05-07~)
111
+ for (const element of catalogItemListElements) {
112
+ availabilities.push({
113
+ id: element.id,
114
+ isAvailable: yield repos.offer.isCatalogAvailable({
115
+ includedInDataCatalog: { id: element.id },
116
+ availableAtOrFrom: { id: params.availableAtOrFrom.id },
117
+ unacceptedPaymentMethod: (considerUnacceptedPaymentMethod) ? unacceptedPaymentMethod : []
118
+ })
119
+ });
120
+ }
121
+ }
101
122
  }
102
123
  }
103
124
  else {
@@ -67,7 +67,7 @@ function searchOfferCatalogItems(params) {
67
67
  }
68
68
  const offerCatalogFirstElement = yield repos.offerCatalog.findFirstItemListElementById({ id: catalogId });
69
69
  if (offerCatalogFirstElement.typeOf === 'OfferCatalog') {
70
- const catalogItemListElements = yield repos.offerCatalog.searchItemListElementById({
70
+ const catalogItemListElements = yield repos.offerCatalog.sliceItemListElementById({
71
71
  id: catalogId,
72
72
  limit: params.limit,
73
73
  page: params.page
@@ -1,5 +1,6 @@
1
1
  import type { EventRepo } from '../../repo/event';
2
2
  import type { EventSeriesRepo } from '../../repo/eventSeries';
3
+ import type { PendingReservationRepo } from '../../repo/pendingReservation';
3
4
  import type { ProjectRepo } from '../../repo/project';
4
5
  import type { SettingRepo } from '../../repo/setting';
5
6
  import type { TaskRepo } from '../../repo/task';
@@ -10,6 +11,7 @@ import * as factory from '../../factory';
10
11
  declare function onEventChanged(params: factory.task.onEventChanged.IData): (repos: {
11
12
  event: EventRepo;
12
13
  eventSeries: EventSeriesRepo;
14
+ pendingReservation?: PendingReservationRepo;
13
15
  project: ProjectRepo;
14
16
  setting: SettingRepo;
15
17
  task: TaskRepo;
@@ -10,7 +10,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.onEventChanged = onEventChanged;
13
+ const createDebug = require("debug");
14
+ const moment = require("moment");
13
15
  const factory = require("../../factory");
16
+ const debug = createDebug('chevre-domain:service:offer:onEventChanged');
14
17
  /**
15
18
  * イベント変更時処理
16
19
  */
@@ -49,6 +52,19 @@ function onEventChanged(params) {
49
52
  // no op
50
53
  }
51
54
  }
55
+ if (params.typeOf === factory.eventType.Event || params.typeOf === factory.eventType.ScreeningEvent) {
56
+ if (repos.pendingReservation !== undefined) {
57
+ // sync pendingReservations.expires(2025-05-08~)
58
+ yield syncEventEndDate2pendingReservations({
59
+ ids: params.id,
60
+ typeOf: params.typeOf
61
+ })({
62
+ event: repos.event,
63
+ pendingReservation: repos.pendingReservation,
64
+ setting: repos.setting
65
+ });
66
+ }
67
+ }
52
68
  }
53
69
  });
54
70
  }
@@ -263,3 +279,33 @@ function createInform2aggTasks(params, setting) {
263
279
  }
264
280
  });
265
281
  }
282
+ function syncEventEndDate2pendingReservations(params) {
283
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
284
+ var _a, _b;
285
+ const setting = yield repos.setting.findOne({ project: { id: { $eq: '*' } } }, ['storage']);
286
+ const stockHoldAfterEventEndInDays = (_a = setting === null || setting === void 0 ? void 0 : setting.storage) === null || _a === void 0 ? void 0 : _a.stockHoldAfterEventEndInDays;
287
+ if (typeof stockHoldAfterEventEndInDays !== 'number') {
288
+ throw new factory.errors.NotFound('setting.storage.stockHoldAfterEventEndInDays');
289
+ }
290
+ for (const eventId of params.ids) {
291
+ const events = yield repos.event.projectEventFields({
292
+ limit: 1,
293
+ page: 1,
294
+ id: { $eq: eventId },
295
+ typeOf: params.typeOf
296
+ }, ['endDate']);
297
+ const endDate = (_b = events.shift()) === null || _b === void 0 ? void 0 : _b.endDate;
298
+ if (endDate instanceof Date) {
299
+ const expires = moment(endDate)
300
+ .add(stockHoldAfterEventEndInDays, 'days')
301
+ .toDate();
302
+ debug('syncEvent2expires processing...', eventId, endDate, expires);
303
+ const syncResult = yield repos.pendingReservation.syncEvent2expires({
304
+ expires,
305
+ reservationFor: { id: eventId }
306
+ });
307
+ debug('syncEvent2expires processed.', syncResult);
308
+ }
309
+ }
310
+ });
311
+ }
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.call = call;
13
13
  const event_1 = require("../../repo/event");
14
14
  const eventSeries_1 = require("../../repo/eventSeries");
15
+ const pendingReservation_1 = require("../../repo/pendingReservation");
15
16
  const project_1 = require("../../repo/project");
16
17
  const setting_1 = require("../../repo/setting");
17
18
  const task_1 = require("../../repo/task");
@@ -24,11 +25,10 @@ function call(data) {
24
25
  yield (0, onEventChanged_1.onEventChanged)(data)({
25
26
  event: new event_1.EventRepo(connection),
26
27
  eventSeries: new eventSeries_1.EventSeriesRepo(connection),
28
+ pendingReservation: new pendingReservation_1.PendingReservationRepo(connection),
27
29
  project: new project_1.ProjectRepo(connection),
28
30
  setting: new setting_1.SettingRepo(connection),
29
31
  task: new task_1.TaskRepo(connection)
30
- }
31
- // settings
32
- );
32
+ });
33
33
  });
34
34
  }
package/package.json CHANGED
@@ -113,5 +113,5 @@
113
113
  "postversion": "git push origin --tags",
114
114
  "prepublishOnly": "npm run clean && npm run build && npm test && npm run doc"
115
115
  },
116
- "version": "22.9.0-alpha.115"
116
+ "version": "22.9.0-alpha.117"
117
117
  }
@@ -1,39 +0,0 @@
1
- // tslint:disable:no-console
2
- import * as mongoose from 'mongoose';
3
-
4
- import { chevre } from '../../../lib/index';
5
-
6
- // const PROJECT_ID = process.env.PROJECT_ID;
7
- mongoose.Model.on('index', (...args) => {
8
- console.error('******** index event emitted. ********\n', args);
9
- });
10
-
11
- async function main() {
12
- await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
13
-
14
- const eventRepo = await chevre.repository.Event.createInstance(mongoose.connection);
15
- const offerRepo = await chevre.repository.Offer.createInstance(mongoose.connection);
16
- const offerCatalogRepo = await chevre.repository.OfferCatalog.createInstance(mongoose.connection);
17
- const productRepo = await chevre.repository.Product.createInstance(mongoose.connection);
18
-
19
- const result = await (await chevre.service.offer.createService()).event.searchOfferCatalogItemAvailability({
20
- event: {
21
- id: 'bm0f0cadh'
22
- },
23
- limit: 10,
24
- page: 1,
25
- availableAtOrFrom: { id: '3eo6okferrsdpfd9j2ce1iv9k7' },
26
- options: { considerUnacceptedPaymentMethod: true }
27
- })({
28
- event: eventRepo,
29
- offer: offerRepo,
30
- offerCatalog: offerCatalogRepo,
31
- product: productRepo
32
- });
33
- console.log(result);
34
- console.log(result.length);
35
- }
36
-
37
- main()
38
- .then(console.log)
39
- .catch(console.error);