@chevre/domain
Version:
Chevre Domain Library for Node.js
490 lines (489 loc) • 34.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.createSubReservations = createSubReservations;
const createDebug = require("debug");
const moment = require("moment");
const factory = require("../../../../factory");
const pecorinoapi = require("../../../../pecorinoapi");
const OfferService = require("../../../offer");
const createReservation_1 = require("./factory/createReservation");
const debug = createDebug('chevre-domain:service:assetTransaction:reserve');
function createSubReservations(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, _g, _h, _j, _k;
// 予約番号
// const reservationNumber = params.transaction.object.reservationNumber;
const reservationNumber = params.reservationNumber;
if (typeof reservationNumber !== 'string') {
throw new factory.errors.Internal('Reservation number undefined');
}
// 指定席のみかどうか
const eventOffers = params.event.offers;
const reservedSeatsOnly = ((_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;
// オファーIDごとにオファー適用条件を確認(興行オファー承認アクションから処理を移行)(2024-07-03~)
validateQuantityRequirement({ acceptedOffers: params.acceptedOffers, ticketOffers: params.ticketOffers, reservationNumber });
// 事前予約要件参照
let advanceBookingRequirements = [];
const advanceBookingRequirementIds = [...new Set(params.availableOffers.reduce((a, b) => { var _a; return (typeof ((_a = b.advanceBookingRequirement) === null || _a === void 0 ? void 0 : _a.id) === 'string') ? [...a, b.advanceBookingRequirement.id] : a; }, []))];
if (advanceBookingRequirementIds.length > 0) {
advanceBookingRequirements = yield repos.advanceBookingRequirement.projectFields({ id: { $in: advanceBookingRequirementIds } }, ['identifier', 'maxValue', 'minValue', 'unitCode', 'valueReference']);
debug('createSubReservations:', advanceBookingRequirements.length, 'advanceBookingRequirements found', JSON.stringify(advanceBookingRequirements));
}
const reservations = [];
let reservationIndex = -1;
for (const acceptedOffer of params.acceptedOffers) {
reservationIndex += 1;
const reservationId = `${reservationNumber}-${reservationIndex}`;
const ticketOffer = params.ticketOffers.find((t) => t.id === acceptedOffer.id);
if (ticketOffer === undefined) {
throw new factory.errors.NotFound('Ticket Offer');
}
const ticketType = params.availableOffers.find((o) => o.id === acceptedOffer.id);
if (ticketType === undefined) {
throw new factory.errors.NotFound(ticketOffer.typeOf);
}
// 事前予約要件検証(2023-08-10~)
validateAdvanceBookingRequirement({
advanceBookingRequirements,
unitPriceOffer: ticketType,
now: params.now,
reservationFor: params.event
});
const programMembershipUsed = yield validateProgramMembershipUsed({
acceptedOffer,
availableOffer: ticketType,
project: { id: params.event.project.id }
})(repos);
// チケット作成
const reservedTicket = (0, createReservation_1.createReservedTicket)({
id: reservationId,
acceptedOffer: acceptedOffer,
availableOffer: ticketType,
dateIssued: params.now,
reservationFor: { id: params.event.id },
reservedSeatsOnly,
availableSeatOffers: params.availableSeatOffers,
ticketOffer: ticketOffer
});
const additionalTicketText = (0, createReservation_1.createAdditionalTicketText)({ acceptedOffer, reservedTicket });
const additionalProperty = (0, createReservation_1.createAdditionalProperty)({ acceptedOffer });
// 座席指定であれば、座席タイプチャージを検索する
const seatPriceComponent = [];
// 区分加算料金を適用しないオプションを追加(2023-01-26~)
const ignoreCategoryCodeChargeSpec = ((_c = ticketType.settings) === null || _c === void 0 ? void 0 : _c.ignoreCategoryCodeChargeSpec) === true;
if (!ignoreCategoryCodeChargeSpec) {
const seatSection = (_d = reservedTicket.ticketedSeat) === null || _d === void 0 ? void 0 : _d.seatSection;
const seatNumber = (_e = reservedTicket.ticketedSeat) === null || _e === void 0 ? void 0 : _e.seatNumber;
if (typeof seatSection === 'string' && typeof seatNumber === 'string') {
const offersOnSeat = (_f = params.availableSeatOffers.find((o) => {
var _a;
return o.branchCode === seatNumber && ((_a = o.containedInPlace) === null || _a === void 0 ? void 0 : _a.branchCode) === seatSection;
})) === null || _f === void 0 ? void 0 : _f.offers;
if (Array.isArray(offersOnSeat)) {
const availableSeatOffer = offersOnSeat[0];
const seatPriceSpecs = (_g = availableSeatOffer === null || availableSeatOffer === void 0 ? void 0 : availableSeatOffer.priceSpecification) === null || _g === void 0 ? void 0 : _g.priceComponent;
if (Array.isArray(seatPriceSpecs)) {
seatPriceComponent.push(...seatPriceSpecs);
}
}
}
}
// 指定されたアドオンがオファーに存在すれば、アドオンの単価仕様作成
const acceptedAddOns = [];
let availableAddOns;
const acceptedAddOnsParams = acceptedOffer.addOn;
if (Array.isArray(acceptedAddOnsParams) && acceptedAddOnsParams.length > 0) {
// アドオンオファー検索(2023-03-02~)
availableAddOns = yield searchAvailableAddOns({
ids: acceptedAddOnsParams.map((acceptedAddOn) => String(acceptedAddOn.id)),
project: { id: params.event.project.id },
ticketOffer,
availableAtOrFrom: params.availableAtOrFrom
})(repos);
}
if (Array.isArray(availableAddOns) && Array.isArray(acceptedAddOnsParams)) {
acceptedAddOnsParams.forEach((acceptedAddOnParams) => {
var _a, _b, _c;
const availableAddOn = availableAddOns === null || availableAddOns === void 0 ? void 0 : availableAddOns.find((addOn) => addOn.id === acceptedAddOnParams.id);
if (availableAddOn !== undefined) {
// acceptedAddOnsの重複を避ける(単価オファーIDに対して)
if (!acceptedAddOns.some((addOn) => addOn.id === availableAddOn.id)) {
const availableAddOnReferenceQuantityValue = availableAddOn.priceSpecification.referenceQuantity.value;
if (typeof availableAddOnReferenceQuantityValue !== 'number') {
throw new factory.errors.NotImplemented('addOn.priceSpecification.referenceQuantity.value must be number');
}
// 受入数量はデフォルトで単価オファーの基準数量
let referenceQuantityValueAccepted = availableAddOnReferenceQuantityValue;
// 数量指定を検証(2023-08-31~)
const specifiedReferencedQuantityValue = (_b = (_a = acceptedAddOnParams.priceSpecification) === null || _a === void 0 ? void 0 : _a.referenceQuantity) === null || _b === void 0 ? void 0 : _b.value;
if (typeof specifiedReferencedQuantityValue === 'number') {
if (specifiedReferencedQuantityValue < 1) {
throw new factory.errors.Argument('addOn.priceSpecification.referenceQuantity.value must be > 0');
}
// 数量が適用単位要件を満たしていなければエラー
if (specifiedReferencedQuantityValue % availableAddOnReferenceQuantityValue !== 0) {
throw new factory.errors.Argument('addOn.priceSpecification.referenceQuantity.value', `Offer ${availableAddOn.id} requires reference quantity value ${specifiedReferencedQuantityValue}`);
}
// 基準数量上書き
referenceQuantityValueAccepted = specifiedReferencedQuantityValue;
}
const priceAccepted = availableAddOn.priceSpecification.price *
(referenceQuantityValueAccepted / availableAddOnReferenceQuantityValue);
const accountsReceivableAccepted = (typeof ((_c = availableAddOn.priceSpecification.accounting) === null || _c === void 0 ? void 0 : _c.accountsReceivable) === 'number')
? availableAddOn.priceSpecification.accounting.accountsReceivable *
(referenceQuantityValueAccepted / availableAddOnReferenceQuantityValue)
: undefined;
const acceptedAddOn = Object.assign(Object.assign({}, availableAddOn), { priceSpecification: Object.assign(Object.assign(Object.assign({}, availableAddOn.priceSpecification), (typeof accountsReceivableAccepted === 'number')
? {
accounting: Object.assign(Object.assign({}, availableAddOn.priceSpecification.accounting), { accountsReceivable: accountsReceivableAccepted, typeOf: 'Accounting' })
}
: undefined), { price: priceAccepted, referenceQuantity: Object.assign(Object.assign({}, availableAddOn.priceSpecification.referenceQuantity), { value: referenceQuantityValueAccepted }) }) });
acceptedAddOns.push(acceptedAddOn);
}
}
});
// acceptedAddOns = availableAddOns.filter(
// (availableAddOn) => acceptedAddOnsParams.some((acceptedAddOn) => availableAddOn.id === acceptedAddOn.id)
// );
}
const subReservation = (_j = (_h = acceptedOffer.itemOffered) === null || _h === void 0 ? void 0 : _h.serviceOutput) === null || _j === void 0 ? void 0 : _j.subReservation;
reservations.push((0, createReservation_1.createReservation)({
project: { id: params.event.project.id, typeOf: factory.organizationType.Project },
id: reservationId,
reservationFor: params.event,
reservedTicket: reservedTicket,
additionalProperty: additionalProperty,
additionalTicketText: additionalTicketText,
ticketOffer: ticketOffer,
seatPriceComponent: seatPriceComponent,
acceptedAddOns: acceptedAddOns,
subReservation: subReservation,
programMembershipUsed,
availableOffer: ticketType,
appliesToMovieTicket: (_k = acceptedOffer.priceSpecification) === null || _k === void 0 ? void 0 : _k.appliesToMovieTicket,
validateAppliesToMovieTicket: params.validateAppliesToMovieTicket
}));
}
return reservations;
});
}
function searchAvailableAddOns(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a;
const availableAddOns = [];
if (Array.isArray(params.ticketOffer.addOn)) {
const addOnProductIds = [...new Set(params.ticketOffer.addOn.map((o) => String(o.itemOffered.id)))];
for (const addOnProductId of addOnProductIds) {
const { offers, product } = yield OfferService.product.search(Object.assign({ ids: params.ids, project: { id: params.project.id }, itemOffered: { id: addOnProductId }, onlyValid: true, addSortIndex: false, includedInDataCatalog: { id: '' }, useIncludeInDataCatalog: false }, (typeof ((_a = params.availableAtOrFrom) === null || _a === void 0 ? void 0 : _a.id) === 'string')
? { availableAt: { id: params.availableAtOrFrom.id } }
: undefined))(repos);
availableAddOns.push(...offers.map((o) => {
const itemOffered4addOn = {
description: product.description,
id: product.id,
name: product.name,
productID: product.productID,
typeOf: product.typeOf
};
const unitPriceSpec = o.priceSpecification.priceComponent.find((component) => {
return component.typeOf === factory.priceSpecificationType.UnitPriceSpecification;
});
if ((unitPriceSpec === null || unitPriceSpec === void 0 ? void 0 : unitPriceSpec.typeOf) !== factory.priceSpecificationType.UnitPriceSpecification) {
throw new factory.errors.NotFound('UnitPriceSpecification of an addOn');
}
return Object.assign(Object.assign({ alternateName: o.alternateName, availability: o.availability, description: o.description, id: String(o.id), identifier: o.identifier, itemOffered: itemOffered4addOn, name: o.name, priceCurrency: o.priceCurrency, priceSpecification: unitPriceSpec, typeOf: o.typeOf }, (o.validFrom instanceof Date) ? { validFrom: o.validFrom } : undefined), (o.validThrough instanceof Date) ? { validThrough: o.validThrough } : undefined);
}));
}
}
return availableAddOns;
});
}
function validateQuantityRequirement(params) {
const { acceptedOffers, ticketOffers, reservationNumber } = params;
const offerIds = (Array.isArray(acceptedOffers))
? [...new Set(params.acceptedOffers.map(({ id }) => id))]
: [];
debug('validating quantity requirement... reservationNumber:', reservationNumber, offerIds);
// オファーIDごとにオファー適用条件を確認
offerIds.forEach((offerId) => {
var _a, _b, _c;
const numAcceptedOffersByOfferId = params.acceptedOffers.filter(({ id }) => id === offerId).length;
const ticketOffer = ticketOffers.find(({ id }) => id === offerId);
if (ticketOffer === undefined) {
throw new factory.errors.NotFound('Ticket Offer');
}
let referenceQuantityValue = 1;
// 単価仕様を取り出す
const unitPriceSpec = ticketOffer.priceSpecification.priceComponent.find((spec) => spec.typeOf === factory.priceSpecificationType.UnitPriceSpecification && (!Array.isArray(spec.appliesToAddOn)));
// 単価仕様は必ず存在するはず
if ((unitPriceSpec === null || unitPriceSpec === void 0 ? void 0 : unitPriceSpec.typeOf) !== factory.priceSpecificationType.UnitPriceSpecification) {
throw new factory.errors.Internal(`unitPriceSpec of the offer '${offerId}' not found`);
}
const unitPriceSpecReferenceQuantityValue = (_a = unitPriceSpec.referenceQuantity) === null || _a === void 0 ? void 0 : _a.value;
if (typeof unitPriceSpecReferenceQuantityValue === 'number') {
referenceQuantityValue = unitPriceSpecReferenceQuantityValue;
}
// アイテム数が適用単位要件を満たしていなければエラー
debug('validating referenceQuantity... reservationNumber:', reservationNumber, offerId, 'numAcceptedOffersByOfferId:', numAcceptedOffersByOfferId, 'referenceQuantityValue:', referenceQuantityValue);
if (numAcceptedOffersByOfferId % referenceQuantityValue !== 0) {
throw new factory.errors.Argument('acceptedOffers', `Offer ${offerId} requires reference quantity value ${referenceQuantityValue}`);
}
// 適用数量要件を満たしていなければエラー
const maxValue = (_b = unitPriceSpec.eligibleQuantity) === null || _b === void 0 ? void 0 : _b.maxValue;
if (typeof maxValue === 'number') {
debug('validating eligibleQuantity.maxValue... reservationNumber:', reservationNumber, offerId, 'numAcceptedOffersByOfferId:', numAcceptedOffersByOfferId, 'maxValue:', maxValue);
if (numAcceptedOffersByOfferId > maxValue) {
throw new factory.errors.Argument('acceptedOffers', `Number of offer:${offerId} must be less than or equal to ${maxValue}`);
}
}
const minValue = (_c = unitPriceSpec.eligibleQuantity) === null || _c === void 0 ? void 0 : _c.minValue;
if (typeof minValue === 'number') {
debug('validating eligibleQuantity.minValue... reservationNumber:', reservationNumber, offerId, 'numAcceptedOffersByOfferId:', numAcceptedOffersByOfferId, 'minValue:', minValue);
if (numAcceptedOffersByOfferId < minValue) {
throw new factory.errors.Argument('acceptedOffers', `Number of offer:${offerId} must be more than or equal to ${minValue}`);
}
}
});
}
/**
* 事前予約要件を検証する
*/
function validateAdvanceBookingRequirement(params) {
var _a, _b;
let requirementSatisfied = true;
// reimplement using advanceBookingRequirementRepo(2025-04-08~)
const advanceBookingRequirementId = (_a = params.unitPriceOffer.advanceBookingRequirement) === null || _a === void 0 ? void 0 : _a.id;
if (typeof advanceBookingRequirementId === 'string') {
const advanceBookingRequirement = params.advanceBookingRequirements.find(({ id }) => id === advanceBookingRequirementId);
if (advanceBookingRequirement === undefined) {
throw new factory.errors.NotFound('advanceBookingRequirement');
}
const advanceBookingRequirementMaxValue = advanceBookingRequirement.maxValue;
const advanceBookingRequirementMinValue = advanceBookingRequirement.minValue;
const advanceBookingRequirementUnitCode = advanceBookingRequirement.unitCode;
const valueReferenceOpens = (_b = advanceBookingRequirement.valueReference) === null || _b === void 0 ? void 0 : _b.opens;
let usageDate = moment(params.reservationFor.startDate, true);
if (typeof valueReferenceOpens === 'string') {
// support valueReference(2025-04-10~)
// tslint:disable-next-line:no-magic-numbers
const opensOffset = valueReferenceOpens.slice(8); // format: HH:mm:ssZ
// tslint:disable-next-line:no-console
debug('opensOffset:', opensOffset);
usageDate = usageDate.utcOffset(opensOffset);
usageDate = moment(`${usageDate.format('YYYY-MM-DD')}T${valueReferenceOpens}`, true);
}
debug('usageDate:', usageDate);
if (typeof advanceBookingRequirementMaxValue === 'number' && typeof advanceBookingRequirementUnitCode === 'string') {
if (advanceBookingRequirementMaxValue < 0) {
throw new factory.errors.NotImplemented('negative value as advanceBookingRequirement.maxValue not implemented');
}
if (advanceBookingRequirementUnitCode !== factory.unitCode.Day) {
throw new factory.errors.NotImplemented(`only ${factory.unitCode.Day} implemented`);
}
const usageDateMustBeBefore = moment(params.now)
.add(advanceBookingRequirementMaxValue, 'days');
if (!usageDate.isSameOrBefore(usageDateMustBeBefore)) {
requirementSatisfied = false;
}
}
if (typeof advanceBookingRequirementMinValue === 'number' && typeof advanceBookingRequirementUnitCode === 'string') {
if (advanceBookingRequirementMinValue < 0) {
throw new factory.errors.NotImplemented('negative value as advanceBookingRequirement.minValue not implemented');
}
if (advanceBookingRequirementUnitCode !== factory.unitCode.Day) {
throw new factory.errors.NotImplemented(`only ${factory.unitCode.Day} implemented`);
}
const usageDateMustBeAfter = moment(params.now)
.add(advanceBookingRequirementMinValue, 'days');
if (!usageDate.isSameOrAfter(usageDateMustBeAfter)) {
requirementSatisfied = false;
}
}
}
if (!requirementSatisfied) {
throw new factory.errors.Argument('acceptedOffer.id', 'advanceBookingRequirement not satisfied');
}
}
function validateProgramMembershipUsed(params) {
// tslint:disable-next-line:cyclomatic-complexity max-func-body-length
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f, _g, _h;
const now = new Date();
let programMembershipUsed;
const requestedProgramMembershipUsed = (_b = (_a = params.acceptedOffer.itemOffered) === null || _a === void 0 ? void 0 : _a.serviceOutput) === null || _b === void 0 ? void 0 : _b.programMembershipUsed;
if (typeof requestedProgramMembershipUsed === 'string') {
throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', 'must be permit');
}
if ((requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.typeOf) === 'Ticket') {
throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', 'must be permit');
}
const programMembershipUsedIdentifier = requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.identifier;
const issuedThroughTypeOf = (_c = requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.issuedThrough) === null || _c === void 0 ? void 0 : _c.typeOf;
if (typeof programMembershipUsedIdentifier === 'string') {
let permitIssuedThrough;
// まずメンバーシップを検索して、存在しなければCreditCardを検索(どちらが発行元サービスか不明なので)
if (issuedThroughTypeOf === factory.product.ProductType.MembershipService) {
const issuedThroughId = (_d = requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.issuedThrough) === null || _d === void 0 ? void 0 : _d.id;
if (typeof issuedThroughId !== 'string' || issuedThroughId === '') {
throw new factory.errors.ArgumentNull('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed.issuedThrough.id');
}
permitIssuedThrough = (yield repos.product.projectFields({
limit: 1,
page: 1,
id: { $eq: issuedThroughId },
typeOf: { $eq: factory.product.ProductType.MembershipService }
}, ['typeOf', 'project', 'serviceType', 'serviceOutput']
// []
)).shift();
if (permitIssuedThrough === undefined) {
throw new factory.errors.NotFound(factory.product.ProductType.MembershipService);
}
}
else if (issuedThroughTypeOf === factory.service.paymentService.PaymentServiceType.CreditCard) {
const issuedThroughId = (_e = requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.issuedThrough) === null || _e === void 0 ? void 0 : _e.id;
if (typeof issuedThroughId !== 'string' || issuedThroughId === '') {
throw new factory.errors.ArgumentNull('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed.issuedThrough.id');
}
permitIssuedThrough = (yield repos.paymentService.projectFields({
limit: 1,
page: 1,
id: { $eq: issuedThroughId },
typeOf: { $eq: factory.service.paymentService.PaymentServiceType.CreditCard }
}, ['typeOf', 'project', 'serviceType', 'serviceOutput'])).shift();
if (permitIssuedThrough === undefined) {
throw new factory.errors.NotFound(factory.service.paymentService.PaymentServiceType.CreditCard);
}
}
else if (issuedThroughTypeOf === factory.service.paymentService.PaymentServiceType.FaceToFace) {
// プロダクトは存在しないので特に検証なし
permitIssuedThrough = {
typeOf: factory.service.paymentService.PaymentServiceType.FaceToFace
};
}
else {
throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', `invalid issuedThrough.typeOf: ${issuedThroughTypeOf}`);
}
switch (permitIssuedThrough.typeOf) {
case factory.service.paymentService.PaymentServiceType.FaceToFace:
// 適用メンバーシップ条件有のオファーであれば、問答無用に受け入れる
const eligibleMembershipType = (_g = (_f = params.availableOffer.eligibleMembershipType) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.codeValue;
if (typeof eligibleMembershipType === 'string') {
programMembershipUsed = {
typeOf: factory.programMembership.ProgramMembershipType.ProgramMembership,
identifier: programMembershipUsedIdentifier,
issuedThrough: {
serviceType: { codeValue: eligibleMembershipType },
typeOf: permitIssuedThrough.typeOf
}
};
}
break;
// 発行サービスがCreditCardのケースに対応(2023-09-01~)
case factory.service.paymentService.PaymentServiceType.CreditCard:
// 決済サービスのserviceOutputにPermitが存在すれば、設定されたメンバーシップ区分のPermitをprogramMembershipUsedとして適用する
let issuedThroughServiceType;
if (Array.isArray(permitIssuedThrough.serviceOutput)) {
const serviceOutputAsPermit = permitIssuedThrough.serviceOutput.find((output) => (output === null || output === void 0 ? void 0 : output.typeOf) === factory.permit.PermitType.Permit);
if ((serviceOutputAsPermit === null || serviceOutputAsPermit === void 0 ? void 0 : serviceOutputAsPermit.typeOf) === factory.permit.PermitType.Permit) {
issuedThroughServiceType = serviceOutputAsPermit.issuedThrough.serviceType;
}
}
if (typeof (issuedThroughServiceType === null || issuedThroughServiceType === void 0 ? void 0 : issuedThroughServiceType.codeValue) === 'string') {
programMembershipUsed = {
typeOf: factory.programMembership.ProgramMembershipType.ProgramMembership,
identifier: programMembershipUsedIdentifier,
issuedThrough: {
id: permitIssuedThrough.id,
serviceType: { codeValue: issuedThroughServiceType.codeValue },
typeOf: permitIssuedThrough.typeOf
}
};
}
else {
throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', 'issuedThrough has no serviceOutput as Permit');
}
break;
case factory.product.ProductType.MembershipService:
// requestedProgramMembershipUsedの発行サービスIDから外部連携設定を取得する
const permitService = yield createPermitService({ issuedThrough: { id: permitIssuedThrough.id } })(repos);
// メンバーシップの存在確認
const serviceOutput = yield permitService.findByIdentifier({
project: { id: params.project.id },
identifier: programMembershipUsedIdentifier,
issuedThrough: { typeOf: factory.product.ProductType.MembershipService }
});
// 有効期間のチェック
if (serviceOutput.validFrom === undefined || serviceOutput.validFrom === null
|| serviceOutput.validUntil === undefined || serviceOutput.validUntil === null) {
throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', 'not valid programMembership');
}
if (moment(serviceOutput.validFrom)
.isAfter(moment(now))
|| moment(serviceOutput.validUntil)
.isBefore(moment(now))) {
throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', 'unavailable programMembership');
}
if (((_h = permitIssuedThrough.serviceType) === null || _h === void 0 ? void 0 : _h.typeOf) === 'CategoryCode') {
programMembershipUsed = {
typeOf: factory.programMembership.ProgramMembershipType.ProgramMembership,
identifier: programMembershipUsedIdentifier,
issuedThrough: {
id: permitIssuedThrough.id,
serviceType: { codeValue: permitIssuedThrough.serviceType.codeValue },
typeOf: permitIssuedThrough.typeOf
}
};
}
break;
default:
throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', `${permitIssuedThrough.typeOf} not implemented`);
}
}
return programMembershipUsed;
});
}
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: ''
})
});
});
}