UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

254 lines (253 loc) 13.4 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.searchEventTicketOffers = searchEventTicketOffers; const factory = require("../../../factory"); const factory_1 = require("../factory"); const checkAvailability_1 = require("./checkAvailability"); const searchPriceSpecs4event_1 = require("./searchPriceSpecs4event"); // tslint:disable-next-line:max-func-body-length function searchTicketOffersByItemOffered(params) { // tslint:disable-next-line:max-func-body-length return (repos) => __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f; const eventService = (yield repos.product.projectFields({ limit: 1, page: 1, id: { $eq: String((_a = params.itemOffered) === null || _a === void 0 ? void 0 : _a.id) } }, ['hasOfferCatalog', 'project'] // [] )).shift(); if (eventService === undefined) { throw new factory.errors.NotFound(factory.product.ProductType.EventService); } const offerCatalogItemsOfProduct = (_b = eventService.hasOfferCatalog) === null || _b === void 0 ? void 0 : _b.itemListElement; /** * プロダクトのカタログIDリスト */ const catalogIdsOfProduct = (Array.isArray(offerCatalogItemsOfProduct)) ? offerCatalogItemsOfProduct.map(({ id }) => id) : []; /** * プロダクトのひとつめのカタログID */ const firstCatalogIdOfProduct = catalogIdsOfProduct.at(0); if (typeof firstCatalogIdOfProduct !== 'string') { throw new factory.errors.NotFound('itemOffered.hasOfferCatalog'); } /** * カタログID or サブカタログID */ let subOfferCatalogId = firstCatalogIdOfProduct; let isOfferCatalogItem = false; const offerCatalogFirstElement = yield repos.offerCatalog.findFirstItemListElementById({ id: firstCatalogIdOfProduct }); if (offerCatalogFirstElement.typeOf === 'OfferCatalog') { subOfferCatalogId = offerCatalogFirstElement.id; isOfferCatalogItem = true; } if (params.withSortIndex) { // 明示的にカタログ指定可能にする if (typeof ((_c = params.includedInDataCatalog) === null || _c === void 0 ? void 0 : _c.id) === 'string' && params.includedInDataCatalog.id.length > 0) { if (isOfferCatalogItem) { // カタログに含まれるサブカタログか検証(2024-09-30~) const offerCatalogIncludingSpecifiedElement = yield repos.offerCatalog.projectFields({ limit: 1, page: 1, id: { $in: catalogIdsOfProduct }, itemListElement: { id: { $in: [params.includedInDataCatalog.id] } } }, ['id']); if (offerCatalogIncludingSpecifiedElement.length === 0) { throw new factory.errors.Argument('includedInDataCatalog.id', 'specified sub catalog not found in product.hasOfferCatalog'); } } else { if (subOfferCatalogId !== params.includedInDataCatalog.id) { throw new factory.errors.Argument('includedInDataCatalog.id', 'invalid offerCatalog'); } } subOfferCatalogId = params.includedInDataCatalog.id; } let priceSpecificationCondition = params.priceSpecification; // サブカタログの適用決済カード条件を考慮 if (isOfferCatalogItem) { // サブカタログ参照 const offerCatalogItem = (yield repos.offerCatalogItem.projectFields({ id: { $in: [subOfferCatalogId] } }, ['relatedOffer'] // { relatedOffer: 1 } )).shift(); if (offerCatalogItem === undefined) { throw new factory.errors.NotFound('OfferCatalogItem'); } // 強制的にサブカタログの適用決済カード条件に変更 const appliesToMovieTicketBySubCatalog = (_e = (_d = offerCatalogItem.relatedOffer) === null || _d === void 0 ? void 0 : _d.priceSpecification) === null || _e === void 0 ? void 0 : _e.appliesToMovieTicket; if (Array.isArray(appliesToMovieTicketBySubCatalog)) { priceSpecificationCondition = { appliesToMovieTicket: { serviceOutput: { typeOf: { $all: appliesToMovieTicketBySubCatalog.map((movieTicket) => movieTicket.serviceOutput.typeOf) // 複数条件対応 } }, serviceType: { $exists: true } } }; } else { priceSpecificationCondition = { appliesToMovieTicket: { serviceType: { $exists: false } } }; } } const { offers, sortedOfferIds } = yield repos.offer.searchByOfferCatalogIdWithSortIndex({ offerCatalog: { id: subOfferCatalogId, isOfferCatalogItem }, availableAtOrFrom: { id: (_f = params.store) === null || _f === void 0 ? void 0 : _f.id }, unacceptedPaymentMethod: params.unacceptedPaymentMethod, excludeAppliesToMovieTicket: params.excludeAppliesToMovieTicket, priceSpecification: priceSpecificationCondition, onlyValid: params.onlyValid === true, useIncludeInDataCatalog: params.useIncludeInDataCatalog, limit: params.limit, page: params.page }); return { availableOffers: offers, sortedOfferIds }; } else { throw new factory.errors.NotImplemented('only withSortIndex: true implemented'); // ID指定での検索はモジュール分離(2024-09-30~) } }); } /** * イベントから興行(旅客)オファーを検索する */ function searchEventTicketOffersByEvent(params) { // tslint:disable-next-line:max-func-body-length return (repos) => __awaiter(this, void 0, void 0, function* () { var _a; const event = params.event; let soundFormatTypes = []; let videoFormatTypes = []; if (event.typeOf === factory.eventType.ScreeningEvent) { const superEvents = yield repos.eventSeries.projectEventSeriesFields({ limit: 1, page: 1, id: { $eq: event.superEvent.id } // typeOf: factory.eventType.ScreeningEventSeries }, ['soundFormat', 'videoFormat']); const superEvent = superEvents.shift(); if (superEvent === undefined) { throw new factory.errors.NotFound(factory.eventType.ScreeningEventSeries); } soundFormatTypes = (Array.isArray(superEvent.soundFormat)) ? superEvent.soundFormat.map((f) => f.typeOf) : []; videoFormatTypes = (Array.isArray(superEvent.videoFormat)) ? superEvent.videoFormat.map((f) => f.typeOf) : []; } const unacceptedPaymentMethod = getUnacceptedPaymentMethodByEvent({ event }); // 上映方式がなければMovieTicket除外(2023-02-21~) const excludeAppliesToMovieTicket = videoFormatTypes.length === 0; // 興行設定があれば興行のカタログを参照する(2022-08-31~) const eventOffers = event.offers; const { availableOffers, sortedOfferIds } = yield searchTicketOffersByItemOffered({ itemOffered: { id: String((_a = eventOffers === null || eventOffers === void 0 ? void 0 : eventOffers.itemOffered) === null || _a === void 0 ? void 0 : _a.id) }, // ids: params.ids, store: params.store, limit: params.limit, page: params.page, onlyValid: params.onlyValid, includedInDataCatalog: params.includedInDataCatalog, unacceptedPaymentMethod, excludeAppliesToMovieTicket, priceSpecification: params.priceSpecification, withSortIndex: true, useIncludeInDataCatalog: params.useIncludeInDataCatalog })(repos); const { soundFormatChargeSpecs, videoFormatChargeSpecs, movieTicketTypeChargeSpecs } = yield (0, searchPriceSpecs4event_1.searchPriceSpecs4event)({ project: { id: event.project.id }, soundFormatTypes, videoFormatTypes, availableOffers })(repos); const offers4event = []; // 単価オファーから興行オファーを生成(順に処理) for (const availableOffer of availableOffers) { const sortIndex = sortedOfferIds === null || sortedOfferIds === void 0 ? void 0 : sortedOfferIds.indexOf(String(availableOffer.id)); let availability; if (params.validateOfferRateLimit) { // レート制限を確認 availability = yield (0, checkAvailability_1.checkAvailability)({ event, unitPriceOffer: availableOffer })(repos); } offers4event.push((0, factory_1.createCompoundPriceSpec4event)({ eligibleQuantity: eventOffers.eligibleQuantity, offer: availableOffer, videoFormatChargeSpecs, soundFormatChargeSpecs, movieTicketTypeChargeSpecs, videoFormatTypes, availability, addOn: (Array.isArray(availableOffer.addOn)) ? availableOffer.addOn : [], sortIndex, includePotentialPriceComponent: params.includePotentialPriceComponent })); } return { ticketOffers: offers4event, unitPriceOffers: availableOffers }; }); } function getUnacceptedPaymentMethodByEvent(params) { var _a; let unacceptedPaymentMethod = []; const unacceptedPaymentMethodByEvent = (_a = params.event.offers) === null || _a === void 0 ? void 0 : _a.unacceptedPaymentMethod; // 施設コンテンツを参照する必要はない(2022-10-31~) if (Array.isArray(unacceptedPaymentMethodByEvent)) { unacceptedPaymentMethod = unacceptedPaymentMethodByEvent; } return unacceptedPaymentMethod; } /** * 興行オファー検索 */ function searchEventTicketOffers(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { const eventType = params.event.typeOf; // optimize projection(2024-07-17~) const event = yield repos.event.projectEventFieldsById({ id: params.event.id }, [ 'project', 'typeOf', 'startDate', 'superEvent.id', 'offers.itemOffered.id', 'offers.offeredThrough', 'offers.unacceptedPaymentMethod', 'offers.eligibleQuantity' ]); let offers; let unitPriceOffers; const eventOffers = event.offers; if (eventOffers === undefined) { throw new factory.errors.NotFound('EventOffers', 'Event offers undefined'); } if (eventOffers.offeredThrough === undefined) { eventOffers.offeredThrough = { typeOf: 'WebAPI', identifier: factory.service.webAPI.Identifier.Chevre }; } switch (eventOffers.offeredThrough.identifier) { case factory.service.webAPI.Identifier.COA: throw new factory.errors.NotImplemented(`booking service '${eventOffers.offeredThrough.identifier}' not implemented`); default: const searchOffersResult = yield searchEventTicketOffersByEvent({ event, store: params.store, priceSpecification: params.priceSpecification, includedInDataCatalog: params.includedInDataCatalog, limit: params.limit, page: params.page, validateOfferRateLimit: params.validateOfferRateLimit, onlyValid: params.onlyValid === true, useIncludeInDataCatalog: params.useIncludeInDataCatalog, includePotentialPriceComponent: params.includePotentialPriceComponent })(repos); offers = searchOffersResult.ticketOffers; unitPriceOffers = searchOffersResult.unitPriceOffers; } return { ticketOffers: offers, unitPriceOffers }; }); }