UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

239 lines (238 loc) 12.6 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.searchOffersByIds = searchOffersByIds; const createDebug = require("debug"); const factory = require("../../../factory"); const factory_1 = require("../factory"); const checkAvailability_1 = require("./checkAvailability"); const searchPriceSpecs4event_1 = require("./searchPriceSpecs4event"); const debug = createDebug('chevre-domain:service:offer'); // 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; 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; } // id指定必須(2023-09-13~) if (!Array.isArray(params.ids)) { throw new factory.errors.ArgumentNull('ids', 'ids must be specified'); } /** * オファーの含まれるカタログIDリスト */ let includedInDataCatalogIds = [subOfferCatalogId]; if (isOfferCatalogItem) { // 複数カタログ対応(2023-09-27~) const offerCatalogItems = yield repos.offerCatalog.findItemListElementById({ id: firstCatalogIdOfProduct, project: { id: eventService.project.id } }); includedInDataCatalogIds = offerCatalogItems.itemListElement.map((element) => element.id); } // includedInDataCatalogIdsを明示的に指定可能にする(2024-10-01~) let includedInDataCatalogIdsSpecified = (_c = params.options.includedInDataCatalog) === null || _c === void 0 ? void 0 : _c.id; if (Array.isArray(includedInDataCatalogIdsSpecified)) { includedInDataCatalogIdsSpecified = [...new Set(includedInDataCatalogIdsSpecified)]; // unique if (isOfferCatalogItem) { // プロダクトのカタログに含まれるサブカタログにフィルター const includedInDataCatalogIdsSpecifiedInOfferCatalog = yield repos.offerCatalog.searchItemListElement({ id: { $in: catalogIdsOfProduct }, itemListElement: { id: { $in: includedInDataCatalogIdsSpecified } } }); if (includedInDataCatalogIdsSpecifiedInOfferCatalog.length !== includedInDataCatalogIdsSpecified.length) { throw new factory.errors.Argument('includedInDataCatalog.id', 'specified sub catalog not found in product.hasOfferCatalog'); } includedInDataCatalogIds = includedInDataCatalogIdsSpecified; } else { // サブカタログでない場合は全てプロダクトのひとつめのカタログIDに一致するはず(現状プロダクトのカタログ数が1の前提なので) const everySpecifiedCatalogIdsValid = includedInDataCatalogIdsSpecified.every((id) => id === subOfferCatalogId); if (!everySpecifiedCatalogIdsValid) { throw new factory.errors.Argument('includedInDataCatalog.id', 'invalid offerCatalog'); } } } debug('searchOffersByIds:', 'searchAllByIdsAndOfferCatalogId processing...', eventService.project.id, params.ids.join(','), includedInDataCatalogIds.join(',')); const availableOffers = yield repos.offer.searchAllByIdsAndOfferCatalogId({ ids: params.ids, includedInDataCatalog: { id: includedInDataCatalogIds, isOfferCatalogItem }, availableAtOrFrom: { id: (_d = params.store) === null || _d === void 0 ? void 0 : _d.id }, unacceptedPaymentMethod: params.unacceptedPaymentMethod, excludeAppliesToMovieTicket: params.excludeAppliesToMovieTicket, onlyValid: true }); return { availableOffers }; }); } /** * イベントから興行(旅客)オファーを検索する */ 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 } = 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, options: params.options // priceSpecification: params.priceSpecification // withSortIndex: params.addSortIndex, // 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) { 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 : [], includePotentialPriceComponent: false // sortIndex // ソートindex不要 })); } 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; } /** * 興行オファー承認時にオファーID指定で利用可能オファーを検索する * パラメータ最適化(2024-09-30~) */ function searchOffersByIds(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({ ids: params.ids, event, store: params.store, // priceSpecification: params.priceSpecification, // includedInDataCatalog: params.includedInDataCatalog, // limit: params.limit, // page: params.page, validateOfferRateLimit: true, options: params.options // onlyValid: params.onlyValid === true, // useIncludeInDataCatalog: params.useIncludeInDataCatalog })(repos); offers = searchOffersResult.ticketOffers; unitPriceOffers = searchOffersResult.unitPriceOffers; } return { ticketOffers: offers, unitPriceOffers }; }); }