UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

593 lines (592 loc) 32.8 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.start = start; const createDebug = require("debug"); const moment = require("moment"); const factory = require("../../../factory"); const pecorinoapi = require("../../../pecorinoapi"); const seat_1 = require("../../../repo/place/seat"); const OfferService = require("../../offer"); const searchOffersByIds_1 = require("../../offer/event/searchOffersByIds"); const cancelReservation_1 = require("../../reserve/cancelReservation"); const onReservationsCreated_1 = require("../../reserve/potentialActions/onReservationsCreated"); const createSubReservations_1 = require("./start/createSubReservations"); const createPointAward_1 = require("./start/factory/createPointAward"); const createStartParams_1 = require("./start/factory/createStartParams"); const validateStartRequest_1 = require("./validateStartRequest"); const debug = createDebug('chevre-domain:service:assetTransaction:reserve'); const ONE_MONTH_IN_DAYS = 31; /** * 取引開始 */ function start(params, options) { return (repos) => __awaiter(this, void 0, void 0, function* () { var _a, _b; const now = new Date(); const reservationNumber = params.transactionNumber; if (typeof reservationNumber !== 'string' || reservationNumber.length === 0) { throw new factory.errors.ArgumentNull('transactionNumber'); // 自動発行廃止(2022-05-17~) } // eventをfix const event = yield fixEvent(params)(repos); // validationを承認アクション開始前から移行(2023-01-27~) yield (0, validateStartRequest_1.validateStartRequest)({ object: params.object, event, validateEventOfferPeriod: params.validateEventOfferPeriod, validateEvent: params.validateEvent, now, store: { id: (_a = params.availableAtOrFrom) === null || _a === void 0 ? void 0 : _a.id } })({ eventOffer: repos.eventOffer, issuer: repos.issuer, memberProgram: repos.memberProgram }); // objectに必要な情報をそろえる const { acceptedOffers4transactionObject, objectSubReservations } = yield createObjectAttributes({ // reservationFor: startParams.object.reservationFor, transaction: { transactionNumber: reservationNumber }, now, object: params.object, event, preSearchedTicketOffers: params.preSearchedTicketOffers, preSearchedUnitPriceOffers: params.preSearchedUnitPriceOffers, availableAtOrFrom: { id: (_b = params.availableAtOrFrom) === null || _b === void 0 ? void 0 : _b.id }, validateAppliesToMovieTicket: params.validateAppliesToMovieTicket // stockHoldUntilDaysAfterEventEnd: params.stockHoldUntilDaysAfterEventEnd }, options)(repos); const startParams = (0, createStartParams_1.createStartParams)(Object.assign(Object.assign({}, params), { provider: { id: event.organizer.id }, reservationNumber, event, acceptedOffers4transactionObject, objectSubReservations })); // reimplement using startWithMinimalResponse(2024-07-02~) // const transaction = await repos.assetTransaction.start<factory.assetTransactionType.Reserve>(startParams); const { id, startDate } = yield repos.assetTransaction.startWithMinimalResponse(startParams); yield addReservations({ reservationFor: startParams.object.reservationFor, transaction: { id, transactionNumber: reservationNumber, instrument: (Array.isArray(startParams.instrument)) ? startParams.instrument : [], startDate }, event, // stockHoldUntilDaysAfterEventEnd: params.stockHoldUntilDaysAfterEventEnd, objectSubReservations })(repos); return { transaction: { id }, objectSubReservations, issuedThrough: startParams.object.issuedThrough, reservationFor: startParams.object.reservationFor }; }); } function fixEvent(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { var _a, _b; const reservationForId = (_a = params.object.reservationFor) === null || _a === void 0 ? void 0 : _a.id; if (typeof reservationForId !== 'string' || reservationForId.length === 0) { throw new factory.errors.ArgumentNull('object.reservationFor.id'); } const event = yield repos.event.projectEventFieldsById({ id: reservationForId }, [ 'project', 'organizer', 'typeOf', // additionalProperty, // discontinue(2024-07-20~) 'name', 'doorTime', 'endDate', 'eventStatus', 'location', 'startDate', 'superEvent', 'offers' // 'coaInfo', // discontinue(2024-07-24~) // 'identifier' // discontinue(2024-07-24~) ]); const offeredThroughIdentifier = (_b = event.offers.offeredThrough) === null || _b === void 0 ? void 0 : _b.identifier; if (offeredThroughIdentifier === factory.service.webAPI.Identifier.COA) { throw new factory.errors.NotImplemented(`${offeredThroughIdentifier} not implemented`); } return event; }); } function createObjectAttributes(params, options) { return (repos) => __awaiter(this, void 0, void 0, function* () { var _a; const { event, now } = params; const reservationNumber = params.transaction.transactionNumber; const acceptedOffers = (Array.isArray(params.object.acceptedOffer)) ? params.object.acceptedOffer : []; if (event.typeOf !== factory.eventType.ScreeningEvent && event.typeOf !== factory.eventType.Event) { throw new factory.errors.Argument('object.reservationFor.id', `invalid event type ${event.typeOf}`); } if (event.typeOf === factory.eventType.ScreeningEvent || event.typeOf === factory.eventType.Event) { validateEvent({ now, event }, options); } // 受け入れたオファーIDだけ取得する(2023-01-26~) const acceptedOfferIds = [...new Set(acceptedOffers.map((o) => String(o.id)))]; let ticketOffers; let availableOffers; // 承認アクションを介した予約取引開始時の冗長なオファー検索処理について最適化(2023-01-27~) if (Array.isArray(params.preSearchedTicketOffers) && Array.isArray(params.preSearchedUnitPriceOffers)) { ticketOffers = params.preSearchedTicketOffers; availableOffers = params.preSearchedUnitPriceOffers; } else { // 興行オファー検索 const searchEventTicketOffersResult = yield (0, searchOffersByIds_1.searchOffersByIds)({ ids: acceptedOfferIds, event: { id: event.id, typeOf: event.typeOf }, store: { id: (_a = params.availableAtOrFrom) === null || _a === void 0 ? void 0 : _a.id }, options: {} // 明示的なサブカタログ指定には未対応(2024-10-01~) // priceSpecification: {}, // 絞る必要なし // includedInDataCatalog: { id: '' }, // 承認時はカタログ指定の必要なし // onlyValid: true, // addSortIndex: false, // validateOfferRateLimit: true // useIncludeInDataCatalog: false })(repos); ticketOffers = searchEventTicketOffersResult.ticketOffers; availableOffers = searchEventTicketOffersResult.unitPriceOffers; } const availableSeatOffers = yield searchAvailableSeatOffers({ acceptedOffers, event })(repos); return createAcceptedOffers4transactionObject({ acceptedOffers, ticketOffers, availableOffers, now, event, availableSeatOffers, reservationNumber, availableAtOrFrom: params.availableAtOrFrom, validateAppliesToMovieTicket: params.validateAppliesToMovieTicket })(repos); }); } /** * 予約追加 */ function addReservations(params) { return (repos // settings: Settings ) => __awaiter(this, void 0, void 0, function* () { const reservationNumber = params.transaction.transactionNumber; const { event, reservationFor, objectSubReservations } = params; let lockedOfferRateLimitKeys = []; try { lockedOfferRateLimitKeys = yield processLockOfferRateLimit({ project: { id: params.event.project.id }, reservations: objectSubReservations, reservationFor, reservationNumber })(repos); } catch (error) { if (lockedOfferRateLimitKeys.length > 0) { yield Promise.all(objectSubReservations.map((reservation) => __awaiter(this, void 0, void 0, function* () { yield (0, cancelReservation_1.processUnlockOfferRateLimit)({ project: { id: params.event.project.id }, reservation: { reservationNumber, reservedTicket: reservation.reservedTicket }, reservationFor })(repos); }))); } throw error; } // 座席指定でも座席ロック // イベントキャパシティ設定のみでも座席ロック yield processLockSeats({ event: event, reservations: objectSubReservations, transaction: { id: params.transaction.id, transactionNumber: params.transaction.transactionNumber, startDate: params.transaction.startDate } // stockHoldUntilDaysAfterEventEnd: params.stockHoldUntilDaysAfterEventEnd })(repos); // ストックホルダー処理(stockHolderで残席数を集計しているので必要) yield (0, onReservationsCreated_1.onReservationsCreated)({ project: { id: event.project.id }, event: { id: event.id }, transaction: params.transaction })(repos); }); } /** * イベントに対する座席オファーを座席コードとセクションコード指定で検索する */ // tslint:disable-next-line:max-func-body-length function searchEventSeatOffers(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f; let offers = []; // 座席指定利用可能かどうか const eventOffers = params.event.offers; 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; if (reservedSeatsAvailable) { const roomBranchCode = String((_d = (_c = eventOffers.itemOffered) === null || _c === void 0 ? void 0 : _c.availableChannel) === null || _d === void 0 ? void 0 : _d.serviceLocation.branchCode); 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); // reimplement using projectSeatsByScreeningRoom const seats = yield repos.seat.projectSeatsByScreeningRoom({ project: { id: { $eq: params.event.project.id } }, screeningRoom: { branchCode: { $eq: roomBranchCode }, containedInPlace: { branchCode: { $eq: movieTheaterBranchCode } } }, branchCode: { $in: params.branchCode.$in }, containedInPlace: { branchCode: { $in: params.containedInPlace.branchCode.$in } }, $projection: Object.assign({}, params.$projection) }); if (seats.length > 0) { const availabilities = yield repos.stockHolder.searchHolders({ project: { id: params.event.project.id }, eventId: params.event.id, startDate: moment(params.event.startDate) .toDate(), hasTicketedSeat: true, offers: seats.map((s) => { var _a; return { seatNumber: s.branchCode, seatSection: (_a = s.containedInPlace) === null || _a === void 0 ? void 0 : _a.branchCode }; }) }); // ルームに含まれる座席区分のみ加算料金を検索(2024-08-06~) const uniqueSeatingTypes = yield repos.seat.aggregateSeatingTypes({ project: { id: { $eq: params.event.project.id } }, branchCode: { $in: params.branchCode.$in }, containedInPlace: { branchCode: { $in: params.containedInPlace.branchCode.$in }, containedInPlace: { branchCode: { $eq: roomBranchCode }, containedInPlace: { branchCode: { $eq: movieTheaterBranchCode } } } } }); debug('searchEventSeatOffers: uniqueSeatingTypes:', uniqueSeatingTypes, params.event.project.id, params.branchCode.$in, params.containedInPlace.branchCode.$in, roomBranchCode, movieTheaterBranchCode); // 座席タイプ価格仕様を検索 let priceSpecs = []; if (Array.isArray(uniqueSeatingTypes) && uniqueSeatingTypes.length > 0) { priceSpecs = yield repos.priceSpecification.search({ project: { id: { $eq: params.event.project.id } }, typeOf: factory.priceSpecificationType.CategoryCodeChargeSpecification, appliesToCategoryCode: { inCodeSet: { identifier: { $eq: factory.categoryCode.CategorySetIdentifier.SeatingType } }, codeValue: { $in: uniqueSeatingTypes } // ルームに含まれる座席区分のみ加算料金を検索(2024-08-06~) } }); } offers = seats.map((seat, index) => { return OfferService.addOffers2Seat({ seat, // unavailableOffers: [], // availability: availabilities[index].availability, availability: (typeof availabilities[index] === 'string') ? factory.itemAvailability.OutOfStock // ホルダーが存在すればOutOfStock : factory.itemAvailability.InStock, priceSpecs }); }); } } return offers; }); } function searchAvailableSeatOffers(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { // 座席オファー検索(必要な分だけ) const { acceptedSeatNumbers, acceptedSeatSections } = getAcceptedSeatNumbersAndSeatSections({ acceptedOffers: params.acceptedOffers }); return searchEventSeatOffers({ branchCode: { $in: acceptedSeatNumbers }, containedInPlace: { branchCode: { $in: acceptedSeatSections } }, event: params.event, // 試しに冗長な情報を非取得にしてみる $projection: { 'containedInPlace.containedInPlace': 0 } })(repos); }); } function validateEvent(params, options) { const { maxReservationGracePeriodInDays } = options; // キャンセルステータスであれば予約不可 if (params.event.eventStatus === factory.eventStatusType.EventCancelled) { throw new factory.errors.Argument('Event', `Event status ${params.event.eventStatus}`); } // 予約取引開始可能なイベント開始日時範囲を明確に制限(2024-03-11~) const reservableThrough = moment(params.now) .add(maxReservationGracePeriodInDays, 'days'); const reservableFrom = moment(params.now) .add(-ONE_MONTH_IN_DAYS, 'days'); if (!moment(params.event.startDate) .isBetween(reservableFrom, reservableThrough, 'second', '[]')) { throw new factory.errors.Argument('Event', `bookingTime must be between ${maxReservationGracePeriodInDays} days before and ${ONE_MONTH_IN_DAYS} days after the event start date`); } // イベントが一定期間後であれば予約不可 // if (moment(params.event.startDate) // .isAfter(reservableThrough)) { // throw new factory.errors.Argument( // 'Event', // `Maximum reservation grace period is ${MAXIMUM_RESERVATION_GRACE_PERIOD_IN_DAYS} days` // ); // } } function createAcceptedOffers4transactionObject(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { // 予約番号 // const reservationNumber = params.transaction.object.reservationNumber; const reservationNumber = params.reservationNumber; if (typeof reservationNumber !== 'string') { throw new factory.errors.Internal('Reservation number undefined'); } const objectSubReservations = yield (0, createSubReservations_1.createSubReservations)(params)(repos); const acceptedOffers4transactionObject = []; let reservationIndex = -1; for (const acceptedOffer of params.acceptedOffers) { reservationIndex += 1; const ticketOffer = params.ticketOffers.find((t) => t.id === acceptedOffer.id); if (ticketOffer === undefined) { throw new factory.errors.NotFound('Ticket Offer'); } const reservationId = `${reservationNumber}-${reservationIndex}`; // 入金先検証 yield validatePointAward({ project: { id: params.event.project.id }, acceptedOffer })(repos); const pointAward = (0, createPointAward_1.createPointAward)({ project: { id: params.event.project.id }, acceptedOffer: acceptedOffer, offer: ticketOffer, reservation: { id: reservationId } }); // acceptedOffers4transactionObjectには必要な情報のみ保管する acceptedOffers4transactionObject.push({ id: acceptedOffer.id, itemOffered: Object.assign(Object.assign({}, (pointAward !== undefined) ? { pointAward } : undefined), { serviceOutput: { id: reservationId } }) }); } return { acceptedOffers4transactionObject, objectSubReservations }; }); } function getAcceptedSeatNumbersAndSeatSections(params) { const acceptedSeatNumbers = []; const acceptedSeatSections = []; params.acceptedOffers.forEach((o) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; 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; 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; if (typeof acceptedSeatNumber === 'string' && acceptedSeatNumber.length > 0) { acceptedSeatNumbers.push(acceptedSeatNumber); } if (typeof acceptedSeatSection === 'string' && acceptedSeatSection.length > 0) { acceptedSeatSections.push(acceptedSeatSection); } const subReservation = (_k = (_j = o.itemOffered) === null || _j === void 0 ? void 0 : _j.serviceOutput) === null || _k === void 0 ? void 0 : _k.subReservation; if (Array.isArray(subReservation)) { subReservation.forEach((s) => { var _a, _b, _c, _d; const subReservationSeatNumber = (_b = (_a = s.reservedTicket) === null || _a === void 0 ? void 0 : _a.ticketedSeat) === null || _b === void 0 ? void 0 : _b.seatNumber; const subReservationSeatSection = (_d = (_c = s.reservedTicket) === null || _c === void 0 ? void 0 : _c.ticketedSeat) === null || _d === void 0 ? void 0 : _d.seatSection; if (typeof subReservationSeatNumber === 'string' && subReservationSeatNumber.length > 0) { acceptedSeatNumbers.push(subReservationSeatNumber); } if (typeof subReservationSeatSection === 'string' && subReservationSeatSection.length > 0) { acceptedSeatSections.push(subReservationSeatSection); } }); } }); return { acceptedSeatNumbers, acceptedSeatSections }; } function createPermitService(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f, _g; const product = (yield repos.product.projectFields({ limit: 1, page: 1, id: { $eq: params.issuedThrough.id } }, ['availableChannel'] // [] )).shift(); if (product === undefined) { throw new factory.errors.NotFound('Product'); } const permitServiceEndpoint = (_a = product.availableChannel) === null || _a === void 0 ? void 0 : _a.serviceUrl; const permitServiceAuthorizeServerDomain = (_c = (_b = product.availableChannel) === null || _b === void 0 ? void 0 : _b.credentials) === null || _c === void 0 ? void 0 : _c.authorizeServerDomain; const permitServiceClientId = (_e = (_d = product.availableChannel) === null || _d === void 0 ? void 0 : _d.credentials) === null || _e === void 0 ? void 0 : _e.clientId; const permitServiceClientSecret = (_g = (_f = product.availableChannel) === null || _f === void 0 ? void 0 : _f.credentials) === null || _g === void 0 ? void 0 : _g.clientSecret; if (typeof permitServiceEndpoint !== 'string' || permitServiceEndpoint.length === 0 || typeof permitServiceAuthorizeServerDomain !== 'string' || permitServiceAuthorizeServerDomain.length === 0 || typeof permitServiceClientId !== 'string' || permitServiceClientId.length === 0 || typeof permitServiceClientSecret !== 'string' || permitServiceClientSecret.length === 0) { throw new factory.errors.Internal('product availableChannel invalid'); } return new (yield pecorinoapi.loadPecorino()).service.Permit({ endpoint: permitServiceEndpoint, auth: yield pecorinoapi.auth.ClientCredentials.createInstance({ domain: permitServiceAuthorizeServerDomain, clientId: permitServiceClientId, clientSecret: permitServiceClientSecret, scopes: [], state: '' }) }); }); } function validatePointAward(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f, _g; // 口座番号確認ではなく、Permit識別子確認 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; 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; if (typeof permitIdentifier === 'string' && permitIdentifier.length > 0) { if (typeof issuedThroughId !== 'string' || issuedThroughId.length === 0) { throw new factory.errors.ArgumentNull('acceptedOffer.itemOffered.pointAward.toLocation.issuedThrough.id'); } // pointAwardの指定がある場合、Permitの存在確認 const permitService = yield createPermitService({ issuedThrough: { id: issuedThroughId } })(repos); yield permitService.findByIdentifier({ project: { id: params.project.id }, identifier: permitIdentifier, issuedThrough: { typeOf: factory.product.ProductType.PaymentCard } }); } }); } function processLockOfferRateLimit(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { const rateLimitKeys = []; params.reservations.forEach((reservation) => { var _a, _b; const scope = (_a = reservation.reservedTicket.ticketType.validRateLimit) === null || _a === void 0 ? void 0 : _a.scope; const unitInSeconds = (_b = reservation.reservedTicket.ticketType.validRateLimit) === null || _b === void 0 ? void 0 : _b.unitInSeconds; if (typeof scope === 'string' && typeof unitInSeconds === 'number') { const rateLimitKey = { project: { id: params.project.id }, reservedTicket: { ticketType: { validRateLimit: { scope: scope, unitInSeconds: unitInSeconds } } }, reservationFor: { startDate: (params.reservationFor.typeOf === factory.eventType.ScreeningEvent) ? moment(params.reservationFor.startDate) .toDate() : moment(params.reservationFor.departureTime) .toDate() }, reservationNumber: params.reservationNumber }; rateLimitKeys.push(rateLimitKey); } }); if (rateLimitKeys.length > 0) { if (rateLimitKeys.length > 1) { throw new factory.errors.Argument('acceptedOffers', `Number of offers with rateLimit must be less than or equal to 1`); } yield repos.offerRateLimit.lock(rateLimitKeys[0]); } return rateLimitKeys; }); } /** * 座席ロックプロセス */ function processLockSeats(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e; const setting = yield repos.setting.findOne({ project: { id: { $eq: '*' } } }, ['storage']); const stockHoldAfterEventEndInDays = (_a = setting === null || setting === void 0 ? void 0 : setting.storage) === null || _a === void 0 ? void 0 : _a.stockHoldAfterEventEndInDays; if (typeof stockHoldAfterEventEndInDays !== 'number') { throw new factory.errors.NotFound('setting.storage.stockHoldAfterEventEndInDays'); } if (stockHoldAfterEventEndInDays <= 0) { throw new factory.errors.Argument('setting.storage.stockHoldAfterEventEndInDays', 'must be > 0'); } const offers = []; params.reservations.forEach((r) => { var _a, _b; const seatSection = (_a = r.reservedTicket.ticketedSeat) === null || _a === void 0 ? void 0 : _a.seatSection; const seatNumber = (_b = r.reservedTicket.ticketedSeat) === null || _b === void 0 ? void 0 : _b.seatNumber; // 指定席のみの場合、ticketedSeatの存在は保証されている if (typeof seatSection === 'string' && typeof seatNumber === 'string') { // subReservationがあれば、そちらもロック const subReservations = r.subReservation; if (Array.isArray(subReservations)) { subReservations.forEach((subReservation) => { var _a, _b, _c, _d; const seatSection4sub = (_b = (_a = subReservation.reservedTicket) === null || _a === void 0 ? void 0 : _a.ticketedSeat) === null || _b === void 0 ? void 0 : _b.seatSection; const seatNumber4sub = (_d = (_c = subReservation.reservedTicket) === null || _c === void 0 ? void 0 : _c.ticketedSeat) === null || _d === void 0 ? void 0 : _d.seatNumber; // 指定席のみの場合、ticketedSeatの存在は保証されている if (typeof seatSection4sub !== 'string' || typeof seatNumber4sub !== 'string') { throw new factory.errors.ArgumentNull('subReservation.reservedTicket.ticketedSeat'); } offers.push({ seatSection: seatSection4sub, seatNumber: seatNumber4sub }); }); } offers.push({ seatSection: seatSection, seatNumber: seatNumber }); } else { // 指定席でない場合、予約IDでロック offers.push({ itemOffered: { serviceOutput: { id: r.id } }, seatSection: '', seatNumber: '' }); } }); const expires = moment(params.event.endDate) .add(stockHoldAfterEventEndInDays, 'days') .toDate(); const holder = params.transaction.transactionNumber; // fix as transactionNumber(2024-07-02~) const bookingTime = params.transaction.startDate; // fix as transactionNumber(2024-07-02~) const hasTicketedSeat = ((_d = (_c = (_b = params.event.offers.itemOffered.serviceOutput) === null || _b === void 0 ? void 0 : _b.reservedTicket) === null || _c === void 0 ? void 0 : _c.ticketedSeat) === null || _d === void 0 ? void 0 : _d.typeOf) === factory.placeType.Seat; let maximumAttendeeCapacity4event = (_e = params.event.location) === null || _e === void 0 ? void 0 : _e.maximumAttendeeCapacity; // 座席無の場合デフォルトmaximumAttendeeCapacityを適用(2025-04-20~) if (!hasTicketedSeat) { if (typeof maximumAttendeeCapacity4event !== 'number') { maximumAttendeeCapacity4event = seat_1.DEFAULT_ROOM_MAXIMUM_CAPACITY; } } if (typeof maximumAttendeeCapacity4event === 'number') { yield repos.stockHolder.lockIfNotLimitExceeded({ project: { id: params.event.project.id }, provider: { id: params.event.organizer.id }, eventId: params.event.id, startDate: moment(params.event.startDate) .toDate(), hasTicketedSeat, offers, expires, holder, bookingTime }, maximumAttendeeCapacity4event); } else { yield repos.stockHolder.lock({ project: { id: params.event.project.id }, provider: { id: params.event.organizer.id }, eventId: params.event.id, startDate: moment(params.event.startDate) .toDate(), hasTicketedSeat, offers, expires, holder, bookingTime }); } }); }