@chevre/domain 21.27.0-alpha.9 → 21.27.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/{aggregateEventReservation.ts → aggregation/aggregateEventReservation.ts} +2 -3
- package/example/src/chevre/aggregation/aggregateOffersOnEvent.ts +82 -0
- package/example/src/chevre/{aggregateAllEvents.ts → aggregation/createAggregateEventTasks.ts} +26 -13
- package/example/src/chevre/aggregation/searchAggregateReservations.ts +33 -0
- package/example/src/chevre/searchEvents.ts +4 -4
- package/example/src/chevre/transaction/processPlaceOrder.ts +1 -2
- package/example/src/chevre/unsetUnnecessaryFields.ts +4 -4
- package/lib/chevre/credentials.d.ts +7 -0
- package/lib/chevre/credentials.js +10 -6
- package/lib/chevre/repo/action.d.ts +2 -2
- package/lib/chevre/repo/action.js +64 -49
- package/lib/chevre/repo/aggregateReservation.d.ts +68 -0
- package/lib/chevre/repo/aggregateReservation.js +135 -0
- package/lib/chevre/repo/event.d.ts +16 -14
- package/lib/chevre/repo/event.js +62 -20
- package/lib/chevre/repo/mongoose/schemas/action.js +18 -0
- package/lib/chevre/repo/mongoose/schemas/aggregateReservation.d.ts +5 -0
- package/lib/chevre/repo/mongoose/schemas/aggregateReservation.js +84 -0
- package/lib/chevre/repo/mongoose/schemas/event.js +1 -1
- package/lib/chevre/repo/offer.d.ts +5 -0
- package/lib/chevre/repository.d.ts +5 -0
- package/lib/chevre/repository.js +15 -2
- package/lib/chevre/service/aggregation/event/aggregateOffers.d.ts +31 -0
- package/lib/chevre/service/aggregation/event/aggregateOffers.js +290 -0
- package/lib/chevre/service/aggregation/event/aggregateScreeningEvent.d.ts +3 -4
- package/lib/chevre/service/aggregation/event/aggregateScreeningEvent.js +33 -238
- package/lib/chevre/service/aggregation/event/aggregateUseActionsOnEvent.d.ts +2 -0
- package/lib/chevre/service/aggregation/event/aggregateUseActionsOnEvent.js +19 -15
- package/lib/chevre/service/aggregation/event/findEventOffers.d.ts +2 -2
- package/lib/chevre/service/aggregation/event/findEventOffers.js +0 -2
- package/lib/chevre/service/aggregation/event.d.ts +2 -1
- package/lib/chevre/service/aggregation/event.js +3 -1
- package/lib/chevre/service/assetTransaction/pay.d.ts +4 -1
- package/lib/chevre/service/assetTransaction/pay.js +53 -27
- package/lib/chevre/service/assetTransaction/reserve.js +2 -1
- package/lib/chevre/service/event.js +16 -23
- package/lib/chevre/service/notification.js +0 -102
- package/lib/chevre/service/offer/onEventChanged.d.ts +25 -0
- package/lib/chevre/service/offer/onEventChanged.js +232 -0
- package/lib/chevre/service/offer.d.ts +0 -40
- package/lib/chevre/service/offer.js +1 -184
- package/lib/chevre/service/payment/any.d.ts +4 -2
- package/lib/chevre/service/payment/any.js +76 -48
- package/lib/chevre/service/payment/creditCard.js +14 -7
- package/lib/chevre/service/payment/movieTicket/checkByIdentifier.js +1 -9
- package/lib/chevre/service/reserve/potentialActions/onReservationCanceled.js +2 -2
- package/lib/chevre/service/reserve/potentialActions/onReservationCheckedIn.js +2 -2
- package/lib/chevre/service/reserve/potentialActions/onReservationConfirmed.js +2 -2
- package/lib/chevre/service/reserve/potentialActions/onReservationUsed.js +2 -2
- package/lib/chevre/service/task/aggregateOffers.d.ts +7 -0
- package/lib/chevre/service/task/aggregateOffers.js +47 -0
- package/lib/chevre/service/task/aggregateScreeningEvent.js +0 -2
- package/lib/chevre/service/task/aggregateUseActionsOnEvent.js +2 -0
- package/lib/chevre/service/task/onEventChanged.js +2 -2
- package/lib/chevre/service/transaction/returnOrder/preStart.js +0 -18
- package/lib/chevre/settings.d.ts +1 -0
- package/lib/chevre/settings.js +2 -1
- package/package.json +3 -3
|
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.aggregateByEvent = exports.aggregateScreeningEvent = void 0;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* イベントの予約集計サービス
|
|
15
15
|
*/
|
|
16
16
|
const createDebug = require("debug");
|
|
17
17
|
const moment = require("moment-timezone");
|
|
@@ -19,7 +19,7 @@ const event_1 = require("../../../repo/event");
|
|
|
19
19
|
const factory = require("../../../factory");
|
|
20
20
|
const settings_1 = require("../../../settings");
|
|
21
21
|
const findEventOffers_1 = require("./findEventOffers");
|
|
22
|
-
const debug = createDebug('chevre-domain:service');
|
|
22
|
+
const debug = createDebug('chevre-domain:service:aggregation');
|
|
23
23
|
/**
|
|
24
24
|
* イベントデータをID指定で集計する
|
|
25
25
|
*/
|
|
@@ -85,8 +85,7 @@ function aggregateByEvent(params) {
|
|
|
85
85
|
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
86
86
|
var _a;
|
|
87
87
|
const now = new Date();
|
|
88
|
-
|
|
89
|
-
let event = params.event;
|
|
88
|
+
const event = params.event;
|
|
90
89
|
// 施設取得は冗長なので、ルーム検索に変更(2023-01-30~)
|
|
91
90
|
let movieTheaterId;
|
|
92
91
|
if (params.event.typeOf === factory.eventType.ScreeningEvent) {
|
|
@@ -107,25 +106,23 @@ function aggregateByEvent(params) {
|
|
|
107
106
|
screeningRoom
|
|
108
107
|
})(repos);
|
|
109
108
|
// オファーごとの集計
|
|
110
|
-
|
|
111
|
-
aggregateOffer = yield aggregateOfferByEvent({
|
|
109
|
+
const aggregateOffer = yield aggregateOfferByEvent({
|
|
112
110
|
aggregateDate: now,
|
|
113
|
-
event
|
|
114
|
-
|
|
115
|
-
screeningRoom: screeningRoom
|
|
111
|
+
event,
|
|
112
|
+
screeningRoom
|
|
116
113
|
})(repos);
|
|
117
114
|
debug('offers aggregated', aggregateOffer);
|
|
118
115
|
// 値がundefinedの場合に更新しないように注意
|
|
119
116
|
const update = {
|
|
120
|
-
$set: Object.assign(Object.assign(Object.assign(Object.assign(
|
|
121
|
-
aggregateReservation
|
|
122
|
-
|
|
117
|
+
$set: Object.assign(Object.assign(Object.assign(Object.assign({ updatedAt: new Date(), // $setオブジェクトが空だとMongoエラーになるので
|
|
118
|
+
aggregateReservation,
|
|
119
|
+
aggregateOffer }, (maximumAttendeeCapacity !== undefined) ? { maximumAttendeeCapacity: maximumAttendeeCapacity } : undefined), (remainingAttendeeCapacity !== undefined) ? { remainingAttendeeCapacity: remainingAttendeeCapacity } : undefined), (aggregateReservation.checkInCount !== undefined) ? { checkInCount: aggregateReservation.checkInCount } : undefined), (aggregateReservation.attendeeCount !== undefined) ? { attendeeCount: aggregateReservation.attendeeCount } : undefined),
|
|
120
|
+
$unset: Object.assign(Object.assign({ noExistingAttributeName: 1 }, (maximumAttendeeCapacity === undefined) ? { maximumAttendeeCapacity: '' } : undefined), (remainingAttendeeCapacity === undefined) ? { remainingAttendeeCapacity: '' } : undefined)
|
|
123
121
|
};
|
|
124
122
|
debug('update:', update);
|
|
125
123
|
// 保管
|
|
126
|
-
|
|
124
|
+
yield repos.event.updateAggregationById({ id: event.id }, update);
|
|
127
125
|
yield onAggregated({ event })({
|
|
128
|
-
project: repos.project,
|
|
129
126
|
task: repos.task
|
|
130
127
|
});
|
|
131
128
|
});
|
|
@@ -134,9 +131,22 @@ exports.aggregateByEvent = aggregateByEvent;
|
|
|
134
131
|
/**
|
|
135
132
|
* 集計後アクション
|
|
136
133
|
*/
|
|
137
|
-
function onAggregated(
|
|
138
|
-
return (
|
|
139
|
-
|
|
134
|
+
function onAggregated(params) {
|
|
135
|
+
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
136
|
+
if (settings_1.settings.useAggregateOfferProjects.includes(params.event.project.id)) {
|
|
137
|
+
// AggregateOffersタスクへ移行(2024-03-25~)
|
|
138
|
+
const aggregateOffersTaskAttributes = {
|
|
139
|
+
project: params.event.project,
|
|
140
|
+
name: factory.taskName.AggregateOffers,
|
|
141
|
+
status: factory.taskStatus.Ready,
|
|
142
|
+
runsAt: new Date(),
|
|
143
|
+
remainingNumberOfTries: 10,
|
|
144
|
+
numberOfTried: 0,
|
|
145
|
+
executionResults: [],
|
|
146
|
+
data: { typeOf: factory.eventType.ScreeningEvent, id: params.event.id }
|
|
147
|
+
};
|
|
148
|
+
yield repos.task.saveMany([aggregateOffersTaskAttributes], { emitImmediately: true });
|
|
149
|
+
}
|
|
140
150
|
});
|
|
141
151
|
}
|
|
142
152
|
function reservedSeatsAvailable(params) {
|
|
@@ -146,37 +156,12 @@ function reservedSeatsAvailable(params) {
|
|
|
146
156
|
}
|
|
147
157
|
function aggregateOfferByEvent(params) {
|
|
148
158
|
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
for (const o of availableOffers) {
|
|
156
|
-
const { maximumAttendeeCapacity, remainingAttendeeCapacity, aggregateReservation } = yield aggregateReservationByOffer({
|
|
157
|
-
aggregateDate: params.aggregateDate,
|
|
158
|
-
event: params.event,
|
|
159
|
-
screeningRoom: params.screeningRoom,
|
|
160
|
-
offer: o
|
|
161
|
-
})(repos);
|
|
162
|
-
offersWithAggregateReservation.push(Object.assign(Object.assign(Object.assign({ typeOf: o.typeOf, id: o.id, identifier: o.identifier, aggregateReservation: aggregateReservation, name: {
|
|
163
|
-
en: (_a = o.name) === null || _a === void 0 ? void 0 : _a.en,
|
|
164
|
-
ja: (_b = o.name) === null || _b === void 0 ? void 0 : _b.ja
|
|
165
|
-
} }, (typeof maximumAttendeeCapacity === 'number') ? { maximumAttendeeCapacity } : undefined), (typeof remainingAttendeeCapacity === 'number') ? { remainingAttendeeCapacity } : undefined), (typeof ((_c = o.category) === null || _c === void 0 ? void 0 : _c.codeValue) === 'string') ? { category: o.category } : undefined));
|
|
166
|
-
}
|
|
167
|
-
return {
|
|
168
|
-
typeOf: factory.offerType.AggregateOffer,
|
|
169
|
-
offerCount: availableOffers.length,
|
|
170
|
-
offers: offersWithAggregateReservation
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
const { offerCount } = yield calculateOfferCount({ event: params.event })(repos);
|
|
175
|
-
return {
|
|
176
|
-
typeOf: factory.offerType.AggregateOffer,
|
|
177
|
-
offerCount
|
|
178
|
-
};
|
|
179
|
-
}
|
|
159
|
+
const { offerCount } = yield calculateOfferCount({ event: params.event })(repos);
|
|
160
|
+
return {
|
|
161
|
+
typeOf: factory.offerType.AggregateOffer,
|
|
162
|
+
aggregateDate: params.aggregateDate,
|
|
163
|
+
offerCount
|
|
164
|
+
};
|
|
180
165
|
});
|
|
181
166
|
}
|
|
182
167
|
function calculateOfferCount(params) {
|
|
@@ -186,8 +171,6 @@ function calculateOfferCount(params) {
|
|
|
186
171
|
try {
|
|
187
172
|
const eventOffers = params.event.offers;
|
|
188
173
|
if (typeof ((_a = eventOffers === null || eventOffers === void 0 ? void 0 : eventOffers.itemOffered) === null || _a === void 0 ? void 0 : _a.id) === 'string') {
|
|
189
|
-
// const eventService = <Pick<factory.product.IProduct, 'hasOfferCatalog'>>
|
|
190
|
-
// await repos.product.findProductById({ id: eventOffers.itemOffered.id }, ['hasOfferCatalog'], []);
|
|
191
174
|
const eventService = (yield repos.product.searchProducts({
|
|
192
175
|
limit: 1,
|
|
193
176
|
page: 1,
|
|
@@ -215,182 +198,6 @@ function calculateOfferCount(params) {
|
|
|
215
198
|
return { offerCount };
|
|
216
199
|
});
|
|
217
200
|
}
|
|
218
|
-
function aggregateReservationByOffer(params) {
|
|
219
|
-
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
220
|
-
let reservationCount4offer;
|
|
221
|
-
let attendeeCount4offer;
|
|
222
|
-
let checkInCount4offer;
|
|
223
|
-
let reservationType = factory.reservationType.EventReservation;
|
|
224
|
-
if (params.event.typeOf === factory.eventType.Event) {
|
|
225
|
-
reservationType = factory.reservationType.BusReservation;
|
|
226
|
-
}
|
|
227
|
-
reservationCount4offer = yield repos.reservation.count({
|
|
228
|
-
typeOf: reservationType,
|
|
229
|
-
// reservationFor: { ids: [params.event.id] },
|
|
230
|
-
reservationFor: { id: { $eq: params.event.id } },
|
|
231
|
-
reservationStatuses: [factory.reservationStatusType.ReservationConfirmed],
|
|
232
|
-
reservedTicket: { ticketType: { ids: [params.offer.id] } }
|
|
233
|
-
});
|
|
234
|
-
attendeeCount4offer = yield repos.reservation.count({
|
|
235
|
-
typeOf: reservationType,
|
|
236
|
-
// reservationFor: { ids: [params.event.id] },
|
|
237
|
-
reservationFor: { id: { $eq: params.event.id } },
|
|
238
|
-
reservationStatuses: [factory.reservationStatusType.ReservationConfirmed],
|
|
239
|
-
reservedTicket: { ticketType: { ids: [params.offer.id] } },
|
|
240
|
-
attended: true
|
|
241
|
-
});
|
|
242
|
-
checkInCount4offer = yield repos.reservation.count({
|
|
243
|
-
typeOf: reservationType,
|
|
244
|
-
// reservationFor: { ids: [params.event.id] },
|
|
245
|
-
reservationFor: { id: { $eq: params.event.id } },
|
|
246
|
-
reservationStatuses: [factory.reservationStatusType.ReservationConfirmed],
|
|
247
|
-
reservedTicket: { ticketType: { ids: [params.offer.id] } },
|
|
248
|
-
checkedIn: true
|
|
249
|
-
});
|
|
250
|
-
const { maximumAttendeeCapacity, remainingAttendeeCapacity } = yield calculateCapacityByOffer(params)(repos);
|
|
251
|
-
return Object.assign(Object.assign({ aggregateReservation: {
|
|
252
|
-
typeOf: 'AggregateReservation',
|
|
253
|
-
aggregateDate: params.aggregateDate,
|
|
254
|
-
reservationCount: reservationCount4offer,
|
|
255
|
-
attendeeCount: attendeeCount4offer,
|
|
256
|
-
checkInCount: checkInCount4offer
|
|
257
|
-
} }, (typeof maximumAttendeeCapacity === 'number') ? { maximumAttendeeCapacity } : undefined), (typeof remainingAttendeeCapacity === 'number') ? { remainingAttendeeCapacity } : undefined);
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* オファーごとのキャパシティを算出する
|
|
262
|
-
*/
|
|
263
|
-
function calculateCapacityByOffer(params) {
|
|
264
|
-
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
265
|
-
var _a;
|
|
266
|
-
let maximumAttendeeCapacity;
|
|
267
|
-
let remainingAttendeeCapacity;
|
|
268
|
-
if (reservedSeatsAvailable({ event: params.event })) {
|
|
269
|
-
// 基本的にはイベントのキャパシティに同じ
|
|
270
|
-
maximumAttendeeCapacity = params.event.maximumAttendeeCapacity;
|
|
271
|
-
remainingAttendeeCapacity = params.event.remainingAttendeeCapacity;
|
|
272
|
-
// 座席タイプ制約のあるオファーの場合
|
|
273
|
-
const eligibleSeatingTypes = params.offer.eligibleSeatingType;
|
|
274
|
-
if (Array.isArray(eligibleSeatingTypes)) {
|
|
275
|
-
const filterByEligibleSeatingTypeResult = yield filterByEligibleSeatingType({
|
|
276
|
-
event: params.event,
|
|
277
|
-
screeningRoom: params.screeningRoom,
|
|
278
|
-
eligibleSeatingTypes: eligibleSeatingTypes.map((e) => e.codeValue)
|
|
279
|
-
})(repos);
|
|
280
|
-
maximumAttendeeCapacity = filterByEligibleSeatingTypeResult.maximumAttendeeCapacity;
|
|
281
|
-
remainingAttendeeCapacity = filterByEligibleSeatingTypeResult.remainingAttendeeCapacity;
|
|
282
|
-
}
|
|
283
|
-
// 適用サブ予約がある場合
|
|
284
|
-
const eligibleSubReservation = params.offer.eligibleSubReservation;
|
|
285
|
-
if (Array.isArray(eligibleSubReservation)) {
|
|
286
|
-
// 適用サブ予約の座席タイプごとにキャパシティ算出
|
|
287
|
-
const capacities = yield Promise.all(eligibleSubReservation
|
|
288
|
-
.filter((subReservation) => typeof subReservation.amountOfThisGood === 'number' && subReservation.amountOfThisGood > 0)
|
|
289
|
-
.map((subReservation) => __awaiter(this, void 0, void 0, function* () {
|
|
290
|
-
const filterByEligibleSeatingTypeResult = yield filterByEligibleSeatingType({
|
|
291
|
-
event: params.event,
|
|
292
|
-
screeningRoom: params.screeningRoom,
|
|
293
|
-
eligibleSeatingTypes: [subReservation.typeOfGood.seatingType]
|
|
294
|
-
})(repos);
|
|
295
|
-
return {
|
|
296
|
-
maximumAttendeeCapacity: Math.floor(filterByEligibleSeatingTypeResult.maximumAttendeeCapacity / subReservation.amountOfThisGood),
|
|
297
|
-
remainingAttendeeCapacity: Math.floor(filterByEligibleSeatingTypeResult.remainingAttendeeCapacity / subReservation.amountOfThisGood)
|
|
298
|
-
};
|
|
299
|
-
})));
|
|
300
|
-
// 座席タイプごとのキャパシティの中から、最小数を選択する
|
|
301
|
-
maximumAttendeeCapacity = Math.min(...(typeof maximumAttendeeCapacity === 'number') ? [maximumAttendeeCapacity] : [], ...capacities.map((c) => c.maximumAttendeeCapacity));
|
|
302
|
-
remainingAttendeeCapacity = Math.min(...(typeof remainingAttendeeCapacity === 'number') ? [remainingAttendeeCapacity] : [], ...capacities.map((c) => c.remainingAttendeeCapacity));
|
|
303
|
-
}
|
|
304
|
-
// 単価スペックの単位が1より大きい場合
|
|
305
|
-
const referenceQuantityValue = (_a = params.offer.priceSpecification) === null || _a === void 0 ? void 0 : _a.referenceQuantity.value;
|
|
306
|
-
if (typeof referenceQuantityValue === 'number' && referenceQuantityValue > 1) {
|
|
307
|
-
if (typeof maximumAttendeeCapacity === 'number') {
|
|
308
|
-
maximumAttendeeCapacity -= maximumAttendeeCapacity % referenceQuantityValue;
|
|
309
|
-
}
|
|
310
|
-
if (typeof remainingAttendeeCapacity === 'number') {
|
|
311
|
-
remainingAttendeeCapacity -= remainingAttendeeCapacity % referenceQuantityValue;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
// レート制限がある場合、考慮する
|
|
316
|
-
if (yield isHoldByRateLimit(params)({ offerRateLimit: repos.offerRateLimit })) {
|
|
317
|
-
remainingAttendeeCapacity = 0;
|
|
318
|
-
}
|
|
319
|
-
return { maximumAttendeeCapacity, remainingAttendeeCapacity };
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
function isHoldByRateLimit(params) {
|
|
323
|
-
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
324
|
-
var _a, _b;
|
|
325
|
-
let isHold = false;
|
|
326
|
-
const scope = (_a = params.offer.validRateLimit) === null || _a === void 0 ? void 0 : _a.scope;
|
|
327
|
-
const unitInSeconds = (_b = params.offer.validRateLimit) === null || _b === void 0 ? void 0 : _b.unitInSeconds;
|
|
328
|
-
if (typeof scope === 'string' && typeof unitInSeconds === 'number') {
|
|
329
|
-
const rateLimitKey = {
|
|
330
|
-
reservedTicket: {
|
|
331
|
-
ticketType: {
|
|
332
|
-
validRateLimit: { scope: scope, unitInSeconds: unitInSeconds }
|
|
333
|
-
}
|
|
334
|
-
},
|
|
335
|
-
reservationFor: {
|
|
336
|
-
startDate: moment(params.event.startDate)
|
|
337
|
-
.toDate()
|
|
338
|
-
},
|
|
339
|
-
reservationNumber: ''
|
|
340
|
-
};
|
|
341
|
-
const holder = yield repos.offerRateLimit.getHolder(rateLimitKey);
|
|
342
|
-
// ロックされていれば在庫0
|
|
343
|
-
if (typeof holder === 'string' && holder.length > 0) {
|
|
344
|
-
isHold = true;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
return isHold;
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
function filterByEligibleSeatingType(params) {
|
|
351
|
-
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
352
|
-
// 適用座席タイプに絞る
|
|
353
|
-
const eligibleSeatOffers = (Array.isArray(params.screeningRoom.containsPlace))
|
|
354
|
-
? params.screeningRoom.containsPlace.reduce((a, b) => {
|
|
355
|
-
return [
|
|
356
|
-
...a,
|
|
357
|
-
...(Array.isArray(b.containsPlace))
|
|
358
|
-
? b.containsPlace.filter((place) => {
|
|
359
|
-
const seatingTypes = (Array.isArray(place.seatingType)) ? place.seatingType
|
|
360
|
-
: (typeof place.seatingType === 'string') ? [place.seatingType]
|
|
361
|
-
: [];
|
|
362
|
-
return seatingTypes.some((seatingTypeCodeValue) => params.eligibleSeatingTypes.some((eligibleSeatingType) => eligibleSeatingType === seatingTypeCodeValue));
|
|
363
|
-
})
|
|
364
|
-
.map((place) => {
|
|
365
|
-
return {
|
|
366
|
-
seatSection: b.branchCode,
|
|
367
|
-
seatNumber: place.branchCode
|
|
368
|
-
};
|
|
369
|
-
})
|
|
370
|
-
: []
|
|
371
|
-
];
|
|
372
|
-
}, [])
|
|
373
|
-
: [];
|
|
374
|
-
const maximumAttendeeCapacity = eligibleSeatOffers.length;
|
|
375
|
-
let remainingAttendeeCapacity;
|
|
376
|
-
if (maximumAttendeeCapacity > 0) {
|
|
377
|
-
const availabilities = yield repos.stockHolder.searchHolders({
|
|
378
|
-
project: { id: params.event.project.id },
|
|
379
|
-
eventId: params.event.id,
|
|
380
|
-
startDate: moment(params.event.startDate)
|
|
381
|
-
.toDate(),
|
|
382
|
-
hasTicketedSeat: true,
|
|
383
|
-
offers: eligibleSeatOffers
|
|
384
|
-
});
|
|
385
|
-
// remainingAttendeeCapacity = availabilities.filter((a) => a.availability === factory.itemAvailability.InStock).length;
|
|
386
|
-
remainingAttendeeCapacity = availabilities.filter((holder) => typeof holder !== 'string').length;
|
|
387
|
-
}
|
|
388
|
-
else {
|
|
389
|
-
remainingAttendeeCapacity = 0;
|
|
390
|
-
}
|
|
391
|
-
return { maximumAttendeeCapacity, remainingAttendeeCapacity };
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
201
|
function aggregateReservationByEvent(params) {
|
|
395
202
|
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
396
203
|
// 収容人数を集計
|
|
@@ -405,7 +212,6 @@ function aggregateReservationByEvent(params) {
|
|
|
405
212
|
}
|
|
406
213
|
reservationCount = yield repos.reservation.count({
|
|
407
214
|
typeOf: reservationType,
|
|
408
|
-
// reservationFor: { ids: [params.event.id] },
|
|
409
215
|
reservationFor: { id: { $eq: params.event.id } },
|
|
410
216
|
reservationStatuses: [factory.reservationStatusType.ReservationConfirmed]
|
|
411
217
|
});
|
|
@@ -418,13 +224,6 @@ function aggregateReservationByEvent(params) {
|
|
|
418
224
|
if (hasTicketedSeat) {
|
|
419
225
|
// seatCountを利用する(2023-06-24~)
|
|
420
226
|
const screeningRoomSeatCount = (typeof params.screeningRoom.seatCount === 'number') ? params.screeningRoom.seatCount : 0;
|
|
421
|
-
// const screeningRoomSeatCount = (Array.isArray(params.screeningRoom.containsPlace))
|
|
422
|
-
// // b.containsPlaceがundefinedの場合があるので注意(座席未登録)
|
|
423
|
-
// ? params.screeningRoom.containsPlace.reduce(
|
|
424
|
-
// (a, b) => a + ((Array.isArray(b.containsPlace)) ? b.containsPlace.length : 0),
|
|
425
|
-
// 0
|
|
426
|
-
// )
|
|
427
|
-
// : 0;
|
|
428
227
|
maximumAttendeeCapacity = screeningRoomSeatCount;
|
|
429
228
|
// イベントのキャパシティ設定がスクリーン座席数より小さければmaximumAttendeeCapacityを上書き
|
|
430
229
|
if (typeof eventLocationMaximumAttendeeCapacity === 'number' && eventLocationMaximumAttendeeCapacity < screeningRoomSeatCount) {
|
|
@@ -449,16 +248,12 @@ function aggregateReservationByEvent(params) {
|
|
|
449
248
|
}
|
|
450
249
|
attendeeCount = yield repos.reservation.count({
|
|
451
250
|
typeOf: reservationType,
|
|
452
|
-
// reservationFor: { ids: [params.event.id] },
|
|
453
251
|
reservationFor: { id: { $eq: params.event.id } },
|
|
454
|
-
// reservationStatuses: [factory.reservationStatusType.ReservationConfirmed],
|
|
455
252
|
attended: true
|
|
456
253
|
});
|
|
457
254
|
checkInCount = yield repos.reservation.count({
|
|
458
255
|
typeOf: reservationType,
|
|
459
|
-
// reservationFor: { ids: [params.event.id] },
|
|
460
256
|
reservationFor: { id: { $eq: params.event.id } },
|
|
461
|
-
// reservationStatuses: [factory.reservationStatusType.ReservationConfirmed],
|
|
462
257
|
checkedIn: true
|
|
463
258
|
});
|
|
464
259
|
return {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MongoRepository as ActionRepo } from '../../../repo/action';
|
|
2
|
+
import type { MongoRepository as AggregateReservationRepo } from '../../../repo/aggregateReservation';
|
|
2
3
|
import type { MongoRepository as EventRepo } from '../../../repo/event';
|
|
3
4
|
import type { MongoRepository as OfferRepo } from '../../../repo/offer';
|
|
4
5
|
import type { MongoRepository as OfferCatalogRepo } from '../../../repo/offerCatalog';
|
|
@@ -6,6 +7,7 @@ import type { MongoRepository as PlaceRepo } from '../../../repo/place';
|
|
|
6
7
|
import type { MongoRepository as ProductRepo } from '../../../repo/product';
|
|
7
8
|
export type IAggregateOperation<T> = (repos: {
|
|
8
9
|
action: ActionRepo;
|
|
10
|
+
aggregateReservation: AggregateReservationRepo;
|
|
9
11
|
event: EventRepo;
|
|
10
12
|
offer: OfferRepo;
|
|
11
13
|
offerCatalog: OfferCatalogRepo;
|
|
@@ -14,6 +14,7 @@ exports.aggregateUseActionsOnEvent = void 0;
|
|
|
14
14
|
* イベント入場集計サービス
|
|
15
15
|
*/
|
|
16
16
|
const createDebug = require("debug");
|
|
17
|
+
const moment = require("moment-timezone");
|
|
17
18
|
const factory = require("../../../factory");
|
|
18
19
|
const findEventOffers_1 = require("./findEventOffers");
|
|
19
20
|
const debug = createDebug('chevre-domain:service');
|
|
@@ -22,7 +23,6 @@ function aggregateUseActionsOnEvent(params) {
|
|
|
22
23
|
const now = new Date();
|
|
23
24
|
// 集計対象イベント検索
|
|
24
25
|
// イベント取得属性最適化(2023-01-23~)
|
|
25
|
-
// const event = await repos.event.findById<factory.eventType.ScreeningEvent>(params);
|
|
26
26
|
const event = yield repos.event.findMinimizedIndividualEventById(params);
|
|
27
27
|
// 入場ゲート検索
|
|
28
28
|
const entranceGates = yield findEntranceGates({ event })(repos);
|
|
@@ -33,19 +33,28 @@ function aggregateUseActionsOnEvent(params) {
|
|
|
33
33
|
entranceGates
|
|
34
34
|
})(repos);
|
|
35
35
|
debug('entrances aggregated', aggregateEntranceGate);
|
|
36
|
-
// 値がundefinedの場合に更新しないように注意
|
|
37
36
|
const update = {
|
|
38
37
|
$set: {
|
|
39
|
-
updatedAt: new Date(),
|
|
38
|
+
// updatedAt: new Date(), // $setオブジェクトが空だとMongoエラーになるので
|
|
40
39
|
aggregateEntranceGate
|
|
41
|
-
},
|
|
42
|
-
$unset: {
|
|
43
|
-
noExistingAttributeName: 1 // $unsetは空だとエラーになるので
|
|
44
40
|
}
|
|
41
|
+
// $unset: {
|
|
42
|
+
// noExistingAttributeName: 1 // $unsetは空だとエラーになるので
|
|
43
|
+
// }
|
|
45
44
|
};
|
|
46
45
|
debug('update:', update);
|
|
47
|
-
//
|
|
48
|
-
|
|
46
|
+
// 廃止(2024-03-28~)
|
|
47
|
+
// await repos.event.updateAggregationById({ id: event.id }, update);
|
|
48
|
+
// aggregateReservationsにも保管(2024-03-25~)
|
|
49
|
+
yield repos.aggregateReservation.save({
|
|
50
|
+
project: event.project,
|
|
51
|
+
reservationFor: {
|
|
52
|
+
id: event.id,
|
|
53
|
+
typeOf: event.typeOf,
|
|
54
|
+
startDate: moment(event.startDate)
|
|
55
|
+
.toDate()
|
|
56
|
+
}
|
|
57
|
+
}, { $set: { aggregateEntranceGate } });
|
|
49
58
|
});
|
|
50
59
|
}
|
|
51
60
|
exports.aggregateUseActionsOnEvent = aggregateUseActionsOnEvent;
|
|
@@ -63,12 +72,6 @@ function findEntranceGates(params) {
|
|
|
63
72
|
id: { $eq: params.event.superEvent.location.id }
|
|
64
73
|
}, ['hasEntranceGate'], []);
|
|
65
74
|
movieTheater = searchMovieTheatersResult.shift();
|
|
66
|
-
// movieTheater = await repos.place.findById(
|
|
67
|
-
// { id: params.event.superEvent.location.id },
|
|
68
|
-
// // 不要な属性を取得しない
|
|
69
|
-
// ['hasEntranceGate'],
|
|
70
|
-
// []
|
|
71
|
-
// );
|
|
72
75
|
}
|
|
73
76
|
catch (error) {
|
|
74
77
|
let throwsError = true;
|
|
@@ -112,7 +115,7 @@ function aggregateEntranceGateByEvent(params) {
|
|
|
112
115
|
debug('useActionCount:', useActionCount, entranceGateIdentifier, offer.id);
|
|
113
116
|
return Object.assign(Object.assign({ typeOf: offer.typeOf, id: offer.id, identifier: offer.identifier }, (typeof ((_b = offer.category) === null || _b === void 0 ? void 0 : _b.codeValue) === 'string') ? { category: offer.category } : undefined), { aggregateReservation: {
|
|
114
117
|
typeOf: 'AggregateReservation',
|
|
115
|
-
aggregateDate: params.aggregateDate,
|
|
118
|
+
// aggregateDate: params.aggregateDate, // 最適化につき廃止(2024-03-26~)
|
|
116
119
|
useActionCount
|
|
117
120
|
} });
|
|
118
121
|
})));
|
|
@@ -129,6 +132,7 @@ function aggregateEntranceGateByEvent(params) {
|
|
|
129
132
|
debug('AggregatePlace created,', places);
|
|
130
133
|
return {
|
|
131
134
|
typeOf: factory.placeType.AggregatePlace,
|
|
135
|
+
aggregateDate: params.aggregateDate,
|
|
132
136
|
places: places
|
|
133
137
|
};
|
|
134
138
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IMinimizedIndividualEvent } from '../../../repo/event';
|
|
2
|
-
import type { MongoRepository as OfferRepo } from '../../../repo/offer';
|
|
2
|
+
import type { IUnitPriceOfferFromAggregateOffer, MongoRepository as OfferRepo } from '../../../repo/offer';
|
|
3
3
|
import type { MongoRepository as OfferCatalogRepo } from '../../../repo/offerCatalog';
|
|
4
4
|
import type { MongoRepository as ProductRepo } from '../../../repo/product';
|
|
5
5
|
import * as factory from '../../../factory';
|
|
@@ -13,4 +13,4 @@ export declare function findEventOffers(params: {
|
|
|
13
13
|
offer: OfferRepo;
|
|
14
14
|
offerCatalog: OfferCatalogRepo;
|
|
15
15
|
product: ProductRepo;
|
|
16
|
-
}) => Promise<
|
|
16
|
+
}) => Promise<IUnitPriceOfferFromAggregateOffer[]>;
|
|
@@ -23,8 +23,6 @@ function findEventOffers(params) {
|
|
|
23
23
|
// 興行設定があれば興行のカタログを参照する
|
|
24
24
|
const eventOffers = params.event.offers;
|
|
25
25
|
if (typeof ((_a = eventOffers === null || eventOffers === void 0 ? void 0 : eventOffers.itemOffered) === null || _a === void 0 ? void 0 : _a.id) === 'string') {
|
|
26
|
-
// const eventService = <Pick<factory.product.IProduct, 'hasOfferCatalog'>>
|
|
27
|
-
// await repos.product.findProductById({ id: eventOffers.itemOffered.id }, ['hasOfferCatalog'], []);
|
|
28
26
|
const eventService = (yield repos.product.searchProducts({
|
|
29
27
|
limit: 1,
|
|
30
28
|
page: 1,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* イベント集計サービス
|
|
3
3
|
*/
|
|
4
|
+
import { aggregateOffers } from './event/aggregateOffers';
|
|
4
5
|
import { aggregateScreeningEvent } from './event/aggregateScreeningEvent';
|
|
5
6
|
import { aggregateUseActionsOnEvent } from './event/aggregateUseActionsOnEvent';
|
|
6
7
|
import { importFromCOA } from './event/importFromCOA';
|
|
7
|
-
export { aggregateScreeningEvent, aggregateUseActionsOnEvent, importFromCOA };
|
|
8
|
+
export { aggregateOffers, aggregateScreeningEvent, aggregateUseActionsOnEvent, importFromCOA };
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.importFromCOA = exports.aggregateUseActionsOnEvent = exports.aggregateScreeningEvent = void 0;
|
|
3
|
+
exports.importFromCOA = exports.aggregateUseActionsOnEvent = exports.aggregateScreeningEvent = exports.aggregateOffers = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* イベント集計サービス
|
|
6
6
|
*/
|
|
7
|
+
const aggregateOffers_1 = require("./event/aggregateOffers");
|
|
8
|
+
Object.defineProperty(exports, "aggregateOffers", { enumerable: true, get: function () { return aggregateOffers_1.aggregateOffers; } });
|
|
7
9
|
const aggregateScreeningEvent_1 = require("./event/aggregateScreeningEvent");
|
|
8
10
|
Object.defineProperty(exports, "aggregateScreeningEvent", { enumerable: true, get: function () { return aggregateScreeningEvent_1.aggregateScreeningEvent; } });
|
|
9
11
|
const aggregateUseActionsOnEvent_1 = require("./event/aggregateUseActionsOnEvent");
|
|
@@ -55,6 +55,7 @@ export type ICheckOperation<T> = (repos: {
|
|
|
55
55
|
paymentServiceProvider: PaymentServiceProviderRepo;
|
|
56
56
|
}) => Promise<T>;
|
|
57
57
|
export type IPublishPaymentUrlOperation<T> = (repos: {
|
|
58
|
+
action: ActionRepo;
|
|
58
59
|
paymentAccepted: PaymentAcceptedRepo;
|
|
59
60
|
paymentService: PaymentServiceRepo;
|
|
60
61
|
paymentServiceProvider: PaymentServiceProviderRepo;
|
|
@@ -75,7 +76,9 @@ export type IPublishPaymentUrlResult = CreditCardPayment.IPaymentAgencyTransacti
|
|
|
75
76
|
/**
|
|
76
77
|
* 外部決済ロケーション発行
|
|
77
78
|
*/
|
|
78
|
-
export declare function publishPaymentUrl(params: factory.assetTransaction.pay.IStartParamsWithoutDetail
|
|
79
|
+
export declare function publishPaymentUrl(params: factory.assetTransaction.pay.IStartParamsWithoutDetail, purposeAsTransaction?: {
|
|
80
|
+
id: string;
|
|
81
|
+
}): IPublishPaymentUrlOperation<IPublishPaymentUrlResult>;
|
|
79
82
|
/**
|
|
80
83
|
* 決済ロケーションを無効化する
|
|
81
84
|
* 実質、外部で実行された決済に対する返金処理
|
|
@@ -22,7 +22,8 @@ const debug = createDebug('chevre-domain:service:assetTransaction');
|
|
|
22
22
|
/**
|
|
23
23
|
* 外部決済ロケーション発行
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
// tslint:disable-next-line:max-func-body-length
|
|
26
|
+
function publishPaymentUrl(params, purposeAsTransaction) {
|
|
26
27
|
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
27
28
|
var _a, _b, _c;
|
|
28
29
|
const paymentServiceType = (_a = params.object) === null || _a === void 0 ? void 0 : _a.typeOf;
|
|
@@ -38,34 +39,59 @@ function publishPaymentUrl(params) {
|
|
|
38
39
|
yield validateSeller(params)(repos);
|
|
39
40
|
// 決済サービス確認
|
|
40
41
|
const paymentServiceId = getPaymentServiceId(params);
|
|
42
|
+
// 決済受入アクション生成(2024-03-28~)
|
|
43
|
+
const actionAttributes = Object.assign({ project: params.project, typeOf: factory.actionType.AcceptAction, agent: params.agent, object: {
|
|
44
|
+
object: params.object,
|
|
45
|
+
transactionNumber,
|
|
46
|
+
typeOf: params.typeOf
|
|
47
|
+
} }, (typeof (purposeAsTransaction === null || purposeAsTransaction === void 0 ? void 0 : purposeAsTransaction.id) === 'string')
|
|
48
|
+
? { purpose: { typeOf: factory.transactionType.PlaceOrder, id: purposeAsTransaction.id } }
|
|
49
|
+
: undefined);
|
|
50
|
+
const action = yield repos.action.start(actionAttributes);
|
|
41
51
|
let result;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
52
|
+
try {
|
|
53
|
+
switch (paymentServiceType) {
|
|
54
|
+
case factory.service.paymentService.PaymentServiceType.CreditCard:
|
|
55
|
+
const authorizeResult = yield CreditCardPayment.authorize(params, paymentServiceId, { processPublishPaymentUrl: true })(repos);
|
|
56
|
+
let paymentUrl;
|
|
57
|
+
// 3DS拡張(2024-01-02~)
|
|
58
|
+
const retUrl = (_c = params.object.paymentMethod.creditCard) === null || _c === void 0 ? void 0 : _c.retUrl;
|
|
59
|
+
if (typeof retUrl === 'string' && retUrl.length > 0) {
|
|
60
|
+
paymentUrl = authorizeResult.execTranResult.redirectUrl;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
paymentUrl = authorizeResult.execTranResult.acsUrl;
|
|
64
|
+
}
|
|
65
|
+
if (typeof paymentUrl !== 'string' || paymentUrl.length === 0) {
|
|
66
|
+
throw new factory.errors.ServiceUnavailable(`Payment URL unable to publish. [retUrl: ${retUrl}]`);
|
|
67
|
+
}
|
|
68
|
+
result = {
|
|
69
|
+
paymentMethodId: transactionNumber,
|
|
70
|
+
paymentUrl,
|
|
71
|
+
entryTranArgs: authorizeResult.entryTranArgs,
|
|
72
|
+
entryTranResult: authorizeResult.entryTranResult,
|
|
73
|
+
execTranArgs: authorizeResult.execTranArgs,
|
|
74
|
+
execTranResult: authorizeResult.execTranResult
|
|
75
|
+
};
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
throw new factory.errors.NotImplemented(`Payment service '${paymentServiceType}' not implemented`);
|
|
79
|
+
}
|
|
68
80
|
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
try {
|
|
83
|
+
yield repos.action.giveUp({ typeOf: actionAttributes.typeOf, id: action.id, error });
|
|
84
|
+
}
|
|
85
|
+
catch (__) {
|
|
86
|
+
// 失敗したら仕方ない
|
|
87
|
+
}
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
const actionResult = {
|
|
91
|
+
paymentMethodId: result.paymentMethodId,
|
|
92
|
+
paymentUrl: result.paymentUrl
|
|
93
|
+
};
|
|
94
|
+
yield repos.action.completeWithVoid({ typeOf: actionAttributes.typeOf, id: action.id, result: actionResult });
|
|
69
95
|
return result;
|
|
70
96
|
});
|
|
71
97
|
}
|
|
@@ -17,6 +17,7 @@ const moment = require("moment");
|
|
|
17
17
|
const pecorinoapi = require("../../pecorinoapi");
|
|
18
18
|
const factory = require("../../factory");
|
|
19
19
|
const OfferService = require("../offer");
|
|
20
|
+
const onEventChanged_1 = require("../offer/onEventChanged");
|
|
20
21
|
const cancelReservation_1 = require("../reserve/cancelReservation");
|
|
21
22
|
const confirmReservation_1 = require("../reserve/confirmReservation");
|
|
22
23
|
const settings_1 = require("../../settings");
|
|
@@ -838,7 +839,7 @@ function processLockSeats(params) {
|
|
|
838
839
|
function onReservationsCreated(params) {
|
|
839
840
|
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
840
841
|
// 集計タスク
|
|
841
|
-
yield
|
|
842
|
+
yield (0, onEventChanged_1.createAggregateScreeningEventIfNotExist)({
|
|
842
843
|
project: params.event.project,
|
|
843
844
|
reservationFor: [{ id: params.event.id }],
|
|
844
845
|
force: false,
|