@chevre/domain 21.37.0-alpha.8 → 21.37.0

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 (73) hide show
  1. package/example/src/chevre/processOrder.ts +87 -0
  2. package/example/src/chevre/transaction/processPlaceOrder.ts +17 -143
  3. package/lib/chevre/factory/reservedAgentIdentifireNames.js +2 -1
  4. package/lib/chevre/factory/transaction.d.ts +1 -4
  5. package/lib/chevre/repo/passport.d.ts +39 -0
  6. package/lib/chevre/repo/passport.js +134 -0
  7. package/lib/chevre/repo/task.d.ts +9 -0
  8. package/lib/chevre/repo/task.js +23 -2
  9. package/lib/chevre/repository.d.ts +5 -0
  10. package/lib/chevre/repository.js +15 -2
  11. package/lib/chevre/service/accountTransaction/deposit.js +0 -1
  12. package/lib/chevre/service/accountTransaction/transfer.js +0 -1
  13. package/lib/chevre/service/accountTransaction/withdraw.js +0 -1
  14. package/lib/chevre/service/assetTransaction/reserve/cancel.d.ts +22 -0
  15. package/lib/chevre/service/assetTransaction/reserve/cancel.js +41 -0
  16. package/lib/chevre/service/assetTransaction/reserve/confirm/factory.d.ts +8 -0
  17. package/lib/chevre/service/assetTransaction/reserve/confirm/factory.js +94 -0
  18. package/lib/chevre/service/assetTransaction/reserve/confirm.d.ts +19 -0
  19. package/lib/chevre/service/assetTransaction/reserve/confirm.js +93 -0
  20. package/lib/chevre/service/assetTransaction/reserve/exportTasksById.d.ts +15 -0
  21. package/lib/chevre/service/assetTransaction/reserve/exportTasksById.js +99 -0
  22. package/lib/chevre/service/assetTransaction/reserve/start/createSubReservations.d.ts +28 -0
  23. package/lib/chevre/service/assetTransaction/reserve/start/createSubReservations.js +405 -0
  24. package/lib/chevre/service/assetTransaction/reserve/start/factory/createPointAward.d.ts +15 -0
  25. package/lib/chevre/service/assetTransaction/reserve/start/factory/createPointAward.js +40 -0
  26. package/lib/chevre/service/assetTransaction/reserve/start/factory/createReservation.d.ts +54 -0
  27. package/lib/chevre/service/assetTransaction/reserve/{factory.js → start/factory/createReservation.js} +3 -222
  28. package/lib/chevre/service/assetTransaction/reserve/start/factory/createStartParams.d.ts +22 -0
  29. package/lib/chevre/service/assetTransaction/reserve/start/factory/createStartParams.js +90 -0
  30. package/lib/chevre/service/assetTransaction/reserve/{factory → start/factory}/price.d.ts +1 -1
  31. package/lib/chevre/service/assetTransaction/reserve/{factory → start/factory}/price.js +1 -1
  32. package/lib/chevre/service/assetTransaction/reserve/start.d.ts +74 -0
  33. package/lib/chevre/service/assetTransaction/reserve/start.js +570 -0
  34. package/lib/chevre/service/assetTransaction/reserve.d.ts +6 -128
  35. package/lib/chevre/service/assetTransaction/reserve.js +9 -1047
  36. package/lib/chevre/service/offer/event/{defaultOffer.d.ts → authorize/defaultOffer.d.ts} +1 -1
  37. package/lib/chevre/service/offer/event/{defaultOffer.js → authorize/defaultOffer.js} +1 -1
  38. package/lib/chevre/service/offer/event/{factory.d.ts → authorize/factory.d.ts} +13 -20
  39. package/lib/chevre/service/offer/event/{factory.js → authorize/factory.js} +72 -146
  40. package/lib/chevre/service/offer/event/{processStartReserve4chevre.d.ts → authorize/processStartReserve4chevre.d.ts} +19 -19
  41. package/lib/chevre/service/offer/event/{processStartReserve4chevre.js → authorize/processStartReserve4chevre.js} +8 -13
  42. package/lib/chevre/service/offer/event/authorize.d.ts +1 -1
  43. package/lib/chevre/service/offer/event/authorize.js +104 -128
  44. package/lib/chevre/service/offer/event/importFromCOA/factory.d.ts +9 -0
  45. package/lib/chevre/service/offer/event/importFromCOA/factory.js +67 -0
  46. package/lib/chevre/service/offer/event/importFromCOA.js +1 -1
  47. package/lib/chevre/service/offer/eventServiceByCOA/authorize.js +0 -3
  48. package/lib/chevre/service/offer/eventServiceByCOA/factory.d.ts +3 -3
  49. package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/factory.d.ts +4 -4
  50. package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/processOrder.d.ts +16 -0
  51. package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/processOrder.js +168 -0
  52. package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing.d.ts +4 -5
  53. package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing.js +4 -135
  54. package/lib/chevre/service/order/onOrderStatusChanged.d.ts +2 -2
  55. package/lib/chevre/service/order/onOrderStatusChanged.js +2 -1
  56. package/lib/chevre/service/order.d.ts +2 -2
  57. package/lib/chevre/service/order.js +2 -1
  58. package/lib/chevre/service/transaction/moneyTransfer.d.ts +3 -2
  59. package/lib/chevre/service/transaction/moneyTransfer.js +1 -2
  60. package/lib/chevre/service/transaction/placeOrderInProgress/start/factory.d.ts +10 -0
  61. package/lib/chevre/service/transaction/placeOrderInProgress/start/factory.js +36 -0
  62. package/lib/chevre/service/transaction/placeOrderInProgress/start.d.ts +6 -1
  63. package/lib/chevre/service/transaction/placeOrderInProgress/start.js +26 -12
  64. package/lib/chevre/service/validation/validateOrder.js +1 -1
  65. package/lib/chevre/settings.d.ts +1 -0
  66. package/lib/chevre/settings.js +5 -1
  67. package/package.json +3 -3
  68. package/example/src/chevre/migrateAuthorizeEventServiceOfferResult.ts +0 -163
  69. package/lib/chevre/service/assetTransaction/reserve/factory.d.ts +0 -96
  70. package/lib/chevre/service/transaction/placeOrderInProgress/factory.d.ts +0 -2
  71. package/lib/chevre/service/transaction/placeOrderInProgress/factory.js +0 -29
  72. package/lib/chevre/service/transaction/validation.d.ts +0 -14
  73. package/lib/chevre/service/transaction/validation.js +0 -101
@@ -0,0 +1,570 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.start = void 0;
13
+ const moment = require("moment");
14
+ const factory = require("../../../factory");
15
+ const pecorinoapi = require("../../../pecorinoapi");
16
+ const settings_1 = require("../../../settings");
17
+ const OfferService = require("../../offer");
18
+ const onEventChanged_1 = require("../../offer/onEventChanged");
19
+ const cancelReservation_1 = require("../../reserve/cancelReservation");
20
+ const createSubReservations_1 = require("./start/createSubReservations");
21
+ const createPointAward_1 = require("./start/factory/createPointAward");
22
+ const createStartParams_1 = require("./start/factory/createStartParams");
23
+ const validateStartRequest_1 = require("./validateStartRequest");
24
+ const ONE_MONTH_IN_DAYS = 31;
25
+ /**
26
+ * 取引開始
27
+ */
28
+ function start(params) {
29
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
30
+ var _a, _b;
31
+ const now = new Date();
32
+ const reservationNumber = params.transactionNumber;
33
+ if (typeof reservationNumber !== 'string' || reservationNumber.length === 0) {
34
+ throw new factory.errors.ArgumentNull('transactionNumber'); // 自動発行廃止(2022-05-17~)
35
+ }
36
+ // eventをfix
37
+ const event = yield fixEvent(params)(repos);
38
+ // validationを承認アクション開始前から移行(2023-01-27~)
39
+ (0, validateStartRequest_1.validateStartRequest)({
40
+ object: params.object,
41
+ event,
42
+ validateEventOfferPeriod: params.validateEventOfferPeriod,
43
+ validateEvent: params.validateEvent,
44
+ now,
45
+ store: { id: (_a = params.availableAtOrFrom) === null || _a === void 0 ? void 0 : _a.id }
46
+ });
47
+ // objectに必要な情報をそろえる
48
+ const { acceptedOffers4transactionObject, objectSubReservations } = yield createObjectAttributes({
49
+ // reservationFor: startParams.object.reservationFor,
50
+ transaction: { transactionNumber: reservationNumber },
51
+ now,
52
+ object: params.object,
53
+ event,
54
+ preSearchedTicketOffers: params.preSearchedTicketOffers,
55
+ preSearchedUnitPriceOffers: params.preSearchedUnitPriceOffers,
56
+ availableAtOrFrom: { id: (_b = params.availableAtOrFrom) === null || _b === void 0 ? void 0 : _b.id },
57
+ validateAppliesToMovieTicket: params.validateAppliesToMovieTicket,
58
+ stockHoldUntilDaysAfterEventEnd: params.stockHoldUntilDaysAfterEventEnd
59
+ })(repos);
60
+ const startParams = (0, createStartParams_1.createStartParams)(Object.assign(Object.assign({}, params), { provider: { id: event.organizer.id }, reservationNumber, event, acceptedOffers4transactionObject, objectSubReservations }));
61
+ // reimplement using startWithMinimalResponse(2024-07-02~)
62
+ // const transaction = await repos.assetTransaction.start<factory.assetTransactionType.Reserve>(startParams);
63
+ const { id } = yield repos.assetTransaction.startWithMinimalResponse(startParams);
64
+ yield addReservations({
65
+ reservationFor: startParams.object.reservationFor,
66
+ transaction: { id, transactionNumber: reservationNumber },
67
+ event,
68
+ stockHoldUntilDaysAfterEventEnd: params.stockHoldUntilDaysAfterEventEnd,
69
+ // acceptedOffers4transactionObject,
70
+ objectSubReservations
71
+ })(repos);
72
+ return {
73
+ transaction: { id },
74
+ objectSubReservations,
75
+ issuedThrough: startParams.object.issuedThrough,
76
+ reservationFor: startParams.object.reservationFor
77
+ };
78
+ });
79
+ }
80
+ exports.start = start;
81
+ function fixEvent(params) {
82
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
83
+ var _a, _b, _c;
84
+ const reservationForId = (_a = params.object.reservationFor) === null || _a === void 0 ? void 0 : _a.id;
85
+ if (typeof reservationForId !== 'string' || reservationForId.length === 0) {
86
+ throw new factory.errors.ArgumentNull('object.reservationFor.id');
87
+ }
88
+ let event;
89
+ if (typeof ((_b = params.preSearchedEvent) === null || _b === void 0 ? void 0 : _b.typeOf) === 'string') {
90
+ event = params.preSearchedEvent;
91
+ }
92
+ else {
93
+ event = yield repos.event.findMinimizedIndividualEventById({ id: reservationForId });
94
+ }
95
+ let offeredThrough = (_c = event.offers) === null || _c === void 0 ? void 0 : _c.offeredThrough;
96
+ if (offeredThrough === undefined) {
97
+ offeredThrough = { typeOf: 'WebAPI', identifier: factory.service.webAPI.Identifier.Chevre };
98
+ }
99
+ if (offeredThrough.identifier === factory.service.webAPI.Identifier.COA) {
100
+ throw new factory.errors.NotImplemented(`${offeredThrough.identifier} not implemented`);
101
+ }
102
+ return event;
103
+ });
104
+ }
105
+ function createObjectAttributes(params) {
106
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
107
+ var _a;
108
+ const { event, now } = params;
109
+ const reservationNumber = params.transaction.transactionNumber;
110
+ const acceptedOffers = (Array.isArray(params.object.acceptedOffer)) ? params.object.acceptedOffer : [];
111
+ if (event.typeOf !== factory.eventType.ScreeningEvent && event.typeOf !== factory.eventType.Event) {
112
+ throw new factory.errors.Argument('object.reservationFor.id', `invalid event type ${event.typeOf}`);
113
+ }
114
+ if (event.typeOf === factory.eventType.ScreeningEvent || event.typeOf === factory.eventType.Event) {
115
+ validateEvent({ now, event });
116
+ }
117
+ // 受け入れたオファーIDだけ取得する(2023-01-26~)
118
+ const acceptedOfferIds = [...new Set(acceptedOffers.map((o) => String(o.id)))];
119
+ let ticketOffers;
120
+ let availableOffers;
121
+ // 承認アクションを介した予約取引開始時の冗長なオファー検索処理について最適化(2023-01-27~)
122
+ if (Array.isArray(params.preSearchedTicketOffers) && Array.isArray(params.preSearchedUnitPriceOffers)) {
123
+ ticketOffers = params.preSearchedTicketOffers;
124
+ availableOffers = params.preSearchedUnitPriceOffers;
125
+ }
126
+ else {
127
+ // 興行オファー検索
128
+ const searchEventTicketOffersResult = yield OfferService.event.searchEventTicketOffers({
129
+ ids: acceptedOfferIds,
130
+ event: { id: event.id },
131
+ // 対応アプリケーション条件追加(2023-01-27~)
132
+ store: { id: (_a = params.availableAtOrFrom) === null || _a === void 0 ? void 0 : _a.id },
133
+ priceSpecification: {},
134
+ includedInDataCatalog: { id: '' },
135
+ onlyValid: true,
136
+ addSortIndex: false,
137
+ validateOfferRateLimit: true,
138
+ useIncludeInDataCatalog: false
139
+ })(repos);
140
+ ticketOffers = searchEventTicketOffersResult.ticketOffers;
141
+ availableOffers = searchEventTicketOffersResult.unitPriceOffers;
142
+ }
143
+ const availableSeatOffers = yield searchAvailableSeatOffers({ acceptedOffers, event })(repos);
144
+ return createAcceptedOffers4transactionObject({
145
+ acceptedOffers, ticketOffers, availableOffers, now,
146
+ event, availableSeatOffers, reservationNumber,
147
+ availableAtOrFrom: params.availableAtOrFrom,
148
+ validateAppliesToMovieTicket: params.validateAppliesToMovieTicket
149
+ })(repos);
150
+ });
151
+ }
152
+ /**
153
+ * 予約追加
154
+ */
155
+ function addReservations(params) {
156
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
157
+ const reservationNumber = params.transaction.transactionNumber;
158
+ const { event, reservationFor, objectSubReservations } = params;
159
+ let lockedOfferRateLimitKeys = [];
160
+ try {
161
+ lockedOfferRateLimitKeys = yield processLockOfferRateLimit({
162
+ reservations: objectSubReservations,
163
+ reservationFor,
164
+ reservationNumber
165
+ })(repos);
166
+ // start時保管へ移行(2024-07-06~)
167
+ // // 上書きの必要なし(2024-07-01~)
168
+ // // transaction = await repos.assetTransaction.addReservations({
169
+ // await repos.assetTransaction.addReservations({
170
+ // typeOf: factory.assetTransactionType.Reserve,
171
+ // id: params.transaction.id,
172
+ // object: {
173
+ // acceptedOffer: acceptedOffers4transactionObject,
174
+ // // issuedThroughを追加(2023-06-05~)
175
+ // // issuedThrough, // start時保管へ移行(2024-07-01~)
176
+ // // reservationFor, // start時保管へ移行(2024-07-01~)
177
+ // subReservation: objectSubReservations
178
+ // }
179
+ // });
180
+ }
181
+ catch (error) {
182
+ if (lockedOfferRateLimitKeys.length > 0) {
183
+ yield Promise.all(objectSubReservations.map((reservation) => __awaiter(this, void 0, void 0, function* () {
184
+ yield (0, cancelReservation_1.processUnlockOfferRateLimit)({
185
+ reservation: {
186
+ reservationNumber,
187
+ reservedTicket: reservation.reservedTicket
188
+ },
189
+ reservationFor
190
+ })(repos);
191
+ })));
192
+ }
193
+ throw error;
194
+ }
195
+ // 座席指定でも座席ロック
196
+ // イベントキャパシティ設定のみでも座席ロック
197
+ yield processLockSeats({
198
+ event: event,
199
+ reservations: objectSubReservations,
200
+ transaction: {
201
+ id: params.transaction.id,
202
+ transactionNumber: params.transaction.transactionNumber
203
+ // object: { useHoldStockByTransactionNumber: transaction.object.useHoldStockByTransactionNumber === true }
204
+ },
205
+ stockHoldUntilDaysAfterEventEnd: params.stockHoldUntilDaysAfterEventEnd
206
+ })(repos);
207
+ // ストックホルダー処理(stockHolderで残席数を集計しているので必要)
208
+ yield onReservationsCreated({ event, transaction: { transactionNumber: reservationNumber } })(repos);
209
+ // return { objectSubReservations };
210
+ });
211
+ }
212
+ /**
213
+ * イベントに対する座席オファーを座席コードとセクションコード指定で検索する
214
+ */
215
+ function searchEventSeatOffers(params) {
216
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
217
+ var _a, _b, _c, _d, _e, _f;
218
+ let offers = [];
219
+ // 座席指定利用可能かどうか
220
+ const eventOffers = params.event.offers;
221
+ const reservedSeatsAvailable = ((_b = (_a = eventOffers === null || eventOffers === void 0 ? void 0 : eventOffers.itemOffered.serviceOutput) === null || _a === void 0 ? void 0 : _a.reservedTicket) === null || _b === void 0 ? void 0 : _b.ticketedSeat) !== undefined;
222
+ if (reservedSeatsAvailable) {
223
+ // 座席タイプ価格仕様を検索
224
+ const priceSpecs = yield repos.priceSpecification.search({
225
+ project: { id: { $eq: params.event.project.id } },
226
+ typeOf: factory.priceSpecificationType.CategoryCodeChargeSpecification,
227
+ appliesToCategoryCode: {
228
+ inCodeSet: { identifier: { $eq: factory.categoryCode.CategorySetIdentifier.SeatingType } }
229
+ }
230
+ });
231
+ const roomBranchCode = String((_d = (_c = eventOffers.itemOffered) === null || _c === void 0 ? void 0 : _c.availableChannel) === null || _d === void 0 ? void 0 : _d.serviceLocation.branchCode);
232
+ const movieTheaterBranchCode = String((_f = (_e = eventOffers.itemOffered) === null || _e === void 0 ? void 0 : _e.availableChannel) === null || _f === void 0 ? void 0 : _f.serviceLocation.containedInPlace.branchCode);
233
+ const seats = yield repos.seat.searchSeats({
234
+ project: { id: { $eq: params.event.project.id } },
235
+ branchCode: { $in: params.branchCode.$in },
236
+ containedInPlace: {
237
+ branchCode: {
238
+ $in: params.containedInPlace.branchCode.$in
239
+ },
240
+ containedInPlace: {
241
+ branchCode: { $eq: roomBranchCode },
242
+ containedInPlace: {
243
+ branchCode: { $eq: movieTheaterBranchCode }
244
+ }
245
+ }
246
+ },
247
+ $projection: Object.assign({}, params.$projection)
248
+ });
249
+ if (seats.length > 0) {
250
+ const availabilities = yield repos.stockHolder.searchHolders({
251
+ project: { id: params.event.project.id },
252
+ eventId: params.event.id,
253
+ startDate: moment(params.event.startDate)
254
+ .toDate(),
255
+ hasTicketedSeat: true,
256
+ offers: seats.map((s) => {
257
+ var _a;
258
+ return {
259
+ seatNumber: s.branchCode,
260
+ seatSection: (_a = s.containedInPlace) === null || _a === void 0 ? void 0 : _a.branchCode
261
+ };
262
+ })
263
+ });
264
+ offers = seats.map((seat, index) => {
265
+ return OfferService.addOffers2Seat({
266
+ seat,
267
+ // unavailableOffers: [],
268
+ // availability: availabilities[index].availability,
269
+ availability: (typeof availabilities[index] === 'string')
270
+ ? factory.itemAvailability.OutOfStock // ホルダーが存在すればOutOfStock
271
+ : factory.itemAvailability.InStock,
272
+ priceSpecs
273
+ });
274
+ });
275
+ }
276
+ }
277
+ return offers;
278
+ });
279
+ }
280
+ function searchAvailableSeatOffers(params) {
281
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
282
+ // 座席オファー検索(必要な分だけ)
283
+ const { acceptedSeatNumbers, acceptedSeatSections } = getAcceptedSeatNumbersAndSeatSections({ acceptedOffers: params.acceptedOffers });
284
+ return searchEventSeatOffers({
285
+ branchCode: { $in: acceptedSeatNumbers },
286
+ containedInPlace: { branchCode: { $in: acceptedSeatSections } },
287
+ event: params.event,
288
+ // 試しに冗長な情報を非取得にしてみる
289
+ $projection: {
290
+ 'containedInPlace.containedInPlace': 0
291
+ }
292
+ })(repos);
293
+ });
294
+ }
295
+ function validateEvent(params) {
296
+ // キャンセルステータスであれば予約不可
297
+ if (params.event.eventStatus === factory.eventStatusType.EventCancelled) {
298
+ throw new factory.errors.Argument('Event', `Event status ${params.event.eventStatus}`);
299
+ }
300
+ // 予約取引開始可能なイベント開始日時範囲を明確に制限(2024-03-11~)
301
+ const reservableThrough = moment(params.now)
302
+ .add(settings_1.MAXIMUM_RESERVATION_GRACE_PERIOD_IN_DAYS, 'days');
303
+ const reservableFrom = moment(params.now)
304
+ .add(-ONE_MONTH_IN_DAYS, 'days');
305
+ if (!moment(params.event.startDate)
306
+ .isBetween(reservableFrom, reservableThrough, 'second', '[]')) {
307
+ throw new factory.errors.Argument('Event', `bookingTime must be between ${settings_1.MAXIMUM_RESERVATION_GRACE_PERIOD_IN_DAYS} days before and ${ONE_MONTH_IN_DAYS} days after the event start date`);
308
+ }
309
+ // イベントが一定期間後であれば予約不可
310
+ // if (moment(params.event.startDate)
311
+ // .isAfter(reservableThrough)) {
312
+ // throw new factory.errors.Argument(
313
+ // 'Event',
314
+ // `Maximum reservation grace period is ${MAXIMUM_RESERVATION_GRACE_PERIOD_IN_DAYS} days`
315
+ // );
316
+ // }
317
+ }
318
+ function createAcceptedOffers4transactionObject(params) {
319
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
320
+ // 予約番号
321
+ // const reservationNumber = params.transaction.object.reservationNumber;
322
+ const reservationNumber = params.reservationNumber;
323
+ if (typeof reservationNumber !== 'string') {
324
+ throw new factory.errors.Internal('Reservation number undefined');
325
+ }
326
+ const objectSubReservations = yield (0, createSubReservations_1.createSubReservations)(params)(repos);
327
+ const acceptedOffers4transactionObject = [];
328
+ let reservationIndex = -1;
329
+ for (const acceptedOffer of params.acceptedOffers) {
330
+ reservationIndex += 1;
331
+ const ticketOffer = params.ticketOffers.find((t) => t.id === acceptedOffer.id);
332
+ if (ticketOffer === undefined) {
333
+ throw new factory.errors.NotFound('Ticket Offer');
334
+ }
335
+ const reservationId = `${reservationNumber}-${reservationIndex}`;
336
+ // 入金先検証
337
+ yield validatePointAward({ project: { id: params.event.project.id }, acceptedOffer })(repos);
338
+ const pointAward = (0, createPointAward_1.createPointAward)({
339
+ project: { id: params.event.project.id },
340
+ acceptedOffer: acceptedOffer,
341
+ offer: ticketOffer,
342
+ reservation: { id: reservationId }
343
+ });
344
+ // acceptedOffers4transactionObjectには必要な情報のみ保管する
345
+ acceptedOffers4transactionObject.push({
346
+ id: acceptedOffer.id,
347
+ itemOffered: Object.assign(Object.assign({}, (pointAward !== undefined) ? { pointAward } : undefined), { serviceOutput: { id: reservationId } })
348
+ });
349
+ }
350
+ return { acceptedOffers4transactionObject, objectSubReservations };
351
+ });
352
+ }
353
+ function getAcceptedSeatNumbersAndSeatSections(params) {
354
+ const acceptedSeatNumbers = [];
355
+ const acceptedSeatSections = [];
356
+ params.acceptedOffers.forEach((o) => {
357
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
358
+ const acceptedSeatNumber = (_d = (_c = (_b = (_a = o.itemOffered) === null || _a === void 0 ? void 0 : _a.serviceOutput) === null || _b === void 0 ? void 0 : _b.reservedTicket) === null || _c === void 0 ? void 0 : _c.ticketedSeat) === null || _d === void 0 ? void 0 : _d.seatNumber;
359
+ const acceptedSeatSection = (_h = (_g = (_f = (_e = o.itemOffered) === null || _e === void 0 ? void 0 : _e.serviceOutput) === null || _f === void 0 ? void 0 : _f.reservedTicket) === null || _g === void 0 ? void 0 : _g.ticketedSeat) === null || _h === void 0 ? void 0 : _h.seatSection;
360
+ if (typeof acceptedSeatNumber === 'string' && acceptedSeatNumber.length > 0) {
361
+ acceptedSeatNumbers.push(acceptedSeatNumber);
362
+ }
363
+ if (typeof acceptedSeatSection === 'string' && acceptedSeatSection.length > 0) {
364
+ acceptedSeatSections.push(acceptedSeatSection);
365
+ }
366
+ const subReservation = (_k = (_j = o.itemOffered) === null || _j === void 0 ? void 0 : _j.serviceOutput) === null || _k === void 0 ? void 0 : _k.subReservation;
367
+ if (Array.isArray(subReservation)) {
368
+ subReservation.forEach((s) => {
369
+ var _a, _b, _c, _d;
370
+ const subReservationSeatNumber = (_b = (_a = s.reservedTicket) === null || _a === void 0 ? void 0 : _a.ticketedSeat) === null || _b === void 0 ? void 0 : _b.seatNumber;
371
+ const subReservationSeatSection = (_d = (_c = s.reservedTicket) === null || _c === void 0 ? void 0 : _c.ticketedSeat) === null || _d === void 0 ? void 0 : _d.seatSection;
372
+ if (typeof subReservationSeatNumber === 'string' && subReservationSeatNumber.length > 0) {
373
+ acceptedSeatNumbers.push(subReservationSeatNumber);
374
+ }
375
+ if (typeof subReservationSeatSection === 'string' && subReservationSeatSection.length > 0) {
376
+ acceptedSeatSections.push(subReservationSeatSection);
377
+ }
378
+ });
379
+ }
380
+ });
381
+ return {
382
+ acceptedSeatNumbers,
383
+ acceptedSeatSections
384
+ };
385
+ }
386
+ function createPermitService(params) {
387
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
388
+ var _a, _b, _c, _d, _e, _f, _g;
389
+ // const product = <Pick<factory.product.IProduct, 'availableChannel'>>
390
+ // await repos.product.findProductById({ id: params.issuedThrough.id }, ['availableChannel'], []);
391
+ const product = (yield repos.product.searchProducts({
392
+ limit: 1,
393
+ page: 1,
394
+ id: { $eq: params.issuedThrough.id }
395
+ }, ['availableChannel'], [])).shift();
396
+ if (product === undefined) {
397
+ throw new factory.errors.NotFound('Product');
398
+ }
399
+ const permitServiceEndpoint = (_a = product.availableChannel) === null || _a === void 0 ? void 0 : _a.serviceUrl;
400
+ const permitServiceAuthorizeServerDomain = (_c = (_b = product.availableChannel) === null || _b === void 0 ? void 0 : _b.credentials) === null || _c === void 0 ? void 0 : _c.authorizeServerDomain;
401
+ const permitServiceClientId = (_e = (_d = product.availableChannel) === null || _d === void 0 ? void 0 : _d.credentials) === null || _e === void 0 ? void 0 : _e.clientId;
402
+ const permitServiceClientSecret = (_g = (_f = product.availableChannel) === null || _f === void 0 ? void 0 : _f.credentials) === null || _g === void 0 ? void 0 : _g.clientSecret;
403
+ if (typeof permitServiceEndpoint !== 'string' || permitServiceEndpoint.length === 0
404
+ || typeof permitServiceAuthorizeServerDomain !== 'string' || permitServiceAuthorizeServerDomain.length === 0
405
+ || typeof permitServiceClientId !== 'string' || permitServiceClientId.length === 0
406
+ || typeof permitServiceClientSecret !== 'string' || permitServiceClientSecret.length === 0) {
407
+ throw new factory.errors.Internal('product availableChannel invalid');
408
+ }
409
+ return new (yield pecorinoapi.loadPecorino()).service.Permit({
410
+ endpoint: permitServiceEndpoint,
411
+ auth: yield pecorinoapi.auth.ClientCredentials.createInstance({
412
+ domain: permitServiceAuthorizeServerDomain,
413
+ clientId: permitServiceClientId,
414
+ clientSecret: permitServiceClientSecret,
415
+ scopes: [],
416
+ state: ''
417
+ })
418
+ });
419
+ });
420
+ }
421
+ function validatePointAward(params) {
422
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
423
+ var _a, _b, _c, _d, _e, _f, _g;
424
+ // 口座番号確認ではなく、Permit識別子確認
425
+ const permitIdentifier = (_c = (_b = (_a = params.acceptedOffer.itemOffered) === null || _a === void 0 ? void 0 : _a.pointAward) === null || _b === void 0 ? void 0 : _b.toLocation) === null || _c === void 0 ? void 0 : _c.identifier;
426
+ const issuedThroughId = (_g = (_f = (_e = (_d = params.acceptedOffer.itemOffered) === null || _d === void 0 ? void 0 : _d.pointAward) === null || _e === void 0 ? void 0 : _e.toLocation) === null || _f === void 0 ? void 0 : _f.issuedThrough) === null || _g === void 0 ? void 0 : _g.id;
427
+ if (typeof permitIdentifier === 'string' && permitIdentifier.length > 0) {
428
+ if (typeof issuedThroughId !== 'string' || issuedThroughId.length === 0) {
429
+ throw new factory.errors.ArgumentNull('acceptedOffer.itemOffered.pointAward.toLocation.issuedThrough.id');
430
+ }
431
+ // pointAwardの指定がある場合、Permitの存在確認
432
+ const permitService = yield createPermitService({ issuedThrough: { id: issuedThroughId } })(repos);
433
+ yield permitService.findByIdentifier({
434
+ project: { id: params.project.id },
435
+ identifier: permitIdentifier,
436
+ issuedThrough: { typeOf: factory.product.ProductType.PaymentCard }
437
+ });
438
+ }
439
+ });
440
+ }
441
+ function processLockOfferRateLimit(params) {
442
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
443
+ const rateLimitKeys = [];
444
+ params.reservations.forEach((reservation) => {
445
+ var _a, _b;
446
+ const scope = (_a = reservation.reservedTicket.ticketType.validRateLimit) === null || _a === void 0 ? void 0 : _a.scope;
447
+ const unitInSeconds = (_b = reservation.reservedTicket.ticketType.validRateLimit) === null || _b === void 0 ? void 0 : _b.unitInSeconds;
448
+ if (typeof scope === 'string' && typeof unitInSeconds === 'number') {
449
+ const rateLimitKey = {
450
+ reservedTicket: {
451
+ ticketType: {
452
+ validRateLimit: {
453
+ scope: scope,
454
+ unitInSeconds: unitInSeconds
455
+ }
456
+ }
457
+ },
458
+ reservationFor: {
459
+ startDate: (params.reservationFor.typeOf === factory.eventType.ScreeningEvent)
460
+ ? moment(params.reservationFor.startDate)
461
+ .toDate()
462
+ : moment(params.reservationFor.departureTime)
463
+ .toDate()
464
+ },
465
+ reservationNumber: params.reservationNumber
466
+ };
467
+ rateLimitKeys.push(rateLimitKey);
468
+ }
469
+ });
470
+ yield repos.offerRateLimit.lock(rateLimitKeys);
471
+ return rateLimitKeys;
472
+ });
473
+ }
474
+ /**
475
+ * 座席ロックプロセス
476
+ */
477
+ function processLockSeats(params) {
478
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
479
+ var _a, _b, _c, _d;
480
+ const offers = [];
481
+ params.reservations.forEach((r) => {
482
+ var _a, _b;
483
+ const seatSection = (_a = r.reservedTicket.ticketedSeat) === null || _a === void 0 ? void 0 : _a.seatSection;
484
+ const seatNumber = (_b = r.reservedTicket.ticketedSeat) === null || _b === void 0 ? void 0 : _b.seatNumber;
485
+ // 指定席のみの場合、ticketedSeatの存在は保証されている
486
+ if (typeof seatSection === 'string' && typeof seatNumber === 'string') {
487
+ // subReservationがあれば、そちらもロック
488
+ const subReservations = r.subReservation;
489
+ if (Array.isArray(subReservations)) {
490
+ subReservations.forEach((subReservation) => {
491
+ var _a, _b, _c, _d;
492
+ const seatSection4sub = (_b = (_a = subReservation.reservedTicket) === null || _a === void 0 ? void 0 : _a.ticketedSeat) === null || _b === void 0 ? void 0 : _b.seatSection;
493
+ const seatNumber4sub = (_d = (_c = subReservation.reservedTicket) === null || _c === void 0 ? void 0 : _c.ticketedSeat) === null || _d === void 0 ? void 0 : _d.seatNumber;
494
+ // 指定席のみの場合、ticketedSeatの存在は保証されている
495
+ if (typeof seatSection4sub !== 'string' || typeof seatNumber4sub !== 'string') {
496
+ throw new factory.errors.ArgumentNull('subReservation.reservedTicket.ticketedSeat');
497
+ }
498
+ offers.push({
499
+ seatSection: seatSection4sub,
500
+ seatNumber: seatNumber4sub
501
+ });
502
+ });
503
+ }
504
+ offers.push({
505
+ seatSection: seatSection,
506
+ seatNumber: seatNumber
507
+ });
508
+ }
509
+ else {
510
+ // 指定席でない場合、予約IDでロック
511
+ offers.push({
512
+ itemOffered: { serviceOutput: { id: r.id } },
513
+ seatSection: '',
514
+ seatNumber: ''
515
+ });
516
+ }
517
+ });
518
+ const expires = moment(params.event.endDate)
519
+ // 設定化(2023-06-05~)
520
+ // .add(1, 'month')
521
+ .add(params.stockHoldUntilDaysAfterEventEnd, 'days')
522
+ .toDate();
523
+ // holder:取引番号に対応(2023-06-05~)
524
+ // let holder: string = params.transaction.id;
525
+ // if (params.transaction.object?.useHoldStockByTransactionNumber === true) {
526
+ // holder = params.transaction.transactionNumber;
527
+ // }
528
+ const holder = params.transaction.transactionNumber; // fix as transactionNumber(2024-07-02~)
529
+ const hasTicketedSeat = ((_c = (_b = (_a = params.event.offers.itemOffered.serviceOutput) === null || _a === void 0 ? void 0 : _a.reservedTicket) === null || _b === void 0 ? void 0 : _b.ticketedSeat) === null || _c === void 0 ? void 0 : _c.typeOf) === factory.placeType.Seat;
530
+ const maximumAttendeeCapacity4event = (_d = params.event.location) === null || _d === void 0 ? void 0 : _d.maximumAttendeeCapacity;
531
+ if (typeof maximumAttendeeCapacity4event === 'number') {
532
+ yield repos.stockHolder.lockIfNotLimitExceeded({
533
+ project: { id: params.event.project.id },
534
+ eventId: params.event.id,
535
+ startDate: moment(params.event.startDate)
536
+ .toDate(),
537
+ hasTicketedSeat,
538
+ offers,
539
+ expires,
540
+ holder
541
+ }, maximumAttendeeCapacity4event);
542
+ }
543
+ else {
544
+ yield repos.stockHolder.lock({
545
+ project: { id: params.event.project.id },
546
+ eventId: params.event.id,
547
+ startDate: moment(params.event.startDate)
548
+ .toDate(),
549
+ hasTicketedSeat,
550
+ offers,
551
+ expires,
552
+ holder
553
+ });
554
+ }
555
+ });
556
+ }
557
+ /**
558
+ * 予約作成時イベント
559
+ */
560
+ function onReservationsCreated(params) {
561
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
562
+ // 集計タスク
563
+ yield (0, onEventChanged_1.createAggregateScreeningEventIfNotExist)({
564
+ project: params.event.project,
565
+ reservationFor: [{ id: params.event.id }],
566
+ force: false,
567
+ identifier: `onReservationsCreated:${params.transaction.transactionNumber}`
568
+ })({ task: repos.task });
569
+ });
570
+ }