UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

490 lines (489 loc) 34.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.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: '' }) }); }); }