@chevre/domain
Version:
Chevre Domain Library for Node.js
254 lines (253 loc) • 13.4 kB
JavaScript
"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 };
});
}