@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.
- package/example/src/chevre/processOrder.ts +87 -0
- package/example/src/chevre/transaction/processPlaceOrder.ts +17 -143
- package/lib/chevre/factory/reservedAgentIdentifireNames.js +2 -1
- package/lib/chevre/factory/transaction.d.ts +1 -4
- package/lib/chevre/repo/passport.d.ts +39 -0
- package/lib/chevre/repo/passport.js +134 -0
- package/lib/chevre/repo/task.d.ts +9 -0
- package/lib/chevre/repo/task.js +23 -2
- package/lib/chevre/repository.d.ts +5 -0
- package/lib/chevre/repository.js +15 -2
- package/lib/chevre/service/accountTransaction/deposit.js +0 -1
- package/lib/chevre/service/accountTransaction/transfer.js +0 -1
- package/lib/chevre/service/accountTransaction/withdraw.js +0 -1
- package/lib/chevre/service/assetTransaction/reserve/cancel.d.ts +22 -0
- package/lib/chevre/service/assetTransaction/reserve/cancel.js +41 -0
- package/lib/chevre/service/assetTransaction/reserve/confirm/factory.d.ts +8 -0
- package/lib/chevre/service/assetTransaction/reserve/confirm/factory.js +94 -0
- package/lib/chevre/service/assetTransaction/reserve/confirm.d.ts +19 -0
- package/lib/chevre/service/assetTransaction/reserve/confirm.js +93 -0
- package/lib/chevre/service/assetTransaction/reserve/exportTasksById.d.ts +15 -0
- package/lib/chevre/service/assetTransaction/reserve/exportTasksById.js +99 -0
- package/lib/chevre/service/assetTransaction/reserve/start/createSubReservations.d.ts +28 -0
- package/lib/chevre/service/assetTransaction/reserve/start/createSubReservations.js +405 -0
- package/lib/chevre/service/assetTransaction/reserve/start/factory/createPointAward.d.ts +15 -0
- package/lib/chevre/service/assetTransaction/reserve/start/factory/createPointAward.js +40 -0
- package/lib/chevre/service/assetTransaction/reserve/start/factory/createReservation.d.ts +54 -0
- package/lib/chevre/service/assetTransaction/reserve/{factory.js → start/factory/createReservation.js} +3 -222
- package/lib/chevre/service/assetTransaction/reserve/start/factory/createStartParams.d.ts +22 -0
- package/lib/chevre/service/assetTransaction/reserve/start/factory/createStartParams.js +90 -0
- package/lib/chevre/service/assetTransaction/reserve/{factory → start/factory}/price.d.ts +1 -1
- package/lib/chevre/service/assetTransaction/reserve/{factory → start/factory}/price.js +1 -1
- package/lib/chevre/service/assetTransaction/reserve/start.d.ts +74 -0
- package/lib/chevre/service/assetTransaction/reserve/start.js +570 -0
- package/lib/chevre/service/assetTransaction/reserve.d.ts +6 -128
- package/lib/chevre/service/assetTransaction/reserve.js +9 -1047
- package/lib/chevre/service/offer/event/{defaultOffer.d.ts → authorize/defaultOffer.d.ts} +1 -1
- package/lib/chevre/service/offer/event/{defaultOffer.js → authorize/defaultOffer.js} +1 -1
- package/lib/chevre/service/offer/event/{factory.d.ts → authorize/factory.d.ts} +13 -20
- package/lib/chevre/service/offer/event/{factory.js → authorize/factory.js} +72 -146
- package/lib/chevre/service/offer/event/{processStartReserve4chevre.d.ts → authorize/processStartReserve4chevre.d.ts} +19 -19
- package/lib/chevre/service/offer/event/{processStartReserve4chevre.js → authorize/processStartReserve4chevre.js} +8 -13
- package/lib/chevre/service/offer/event/authorize.d.ts +1 -1
- package/lib/chevre/service/offer/event/authorize.js +104 -128
- package/lib/chevre/service/offer/event/importFromCOA/factory.d.ts +9 -0
- package/lib/chevre/service/offer/event/importFromCOA/factory.js +67 -0
- package/lib/chevre/service/offer/event/importFromCOA.js +1 -1
- package/lib/chevre/service/offer/eventServiceByCOA/authorize.js +0 -3
- package/lib/chevre/service/offer/eventServiceByCOA/factory.d.ts +3 -3
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/factory.d.ts +4 -4
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/processOrder.d.ts +16 -0
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/processOrder.js +168 -0
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing.d.ts +4 -5
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing.js +4 -135
- package/lib/chevre/service/order/onOrderStatusChanged.d.ts +2 -2
- package/lib/chevre/service/order/onOrderStatusChanged.js +2 -1
- package/lib/chevre/service/order.d.ts +2 -2
- package/lib/chevre/service/order.js +2 -1
- package/lib/chevre/service/transaction/moneyTransfer.d.ts +3 -2
- package/lib/chevre/service/transaction/moneyTransfer.js +1 -2
- package/lib/chevre/service/transaction/placeOrderInProgress/start/factory.d.ts +10 -0
- package/lib/chevre/service/transaction/placeOrderInProgress/start/factory.js +36 -0
- package/lib/chevre/service/transaction/placeOrderInProgress/start.d.ts +6 -1
- package/lib/chevre/service/transaction/placeOrderInProgress/start.js +26 -12
- package/lib/chevre/service/validation/validateOrder.js +1 -1
- package/lib/chevre/settings.d.ts +1 -0
- package/lib/chevre/settings.js +5 -1
- package/package.json +3 -3
- package/example/src/chevre/migrateAuthorizeEventServiceOfferResult.ts +0 -163
- package/lib/chevre/service/assetTransaction/reserve/factory.d.ts +0 -96
- package/lib/chevre/service/transaction/placeOrderInProgress/factory.d.ts +0 -2
- package/lib/chevre/service/transaction/placeOrderInProgress/factory.js +0 -29
- package/lib/chevre/service/transaction/validation.d.ts +0 -14
- 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
|
+
}
|