UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

197 lines (196 loc) 11.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.confirmReservation = confirmReservation; const createDebug = require("debug"); const factory = require("../../factory"); const factory_1 = require("./factory"); const onReservationConfirmed_1 = require("./potentialActions/onReservationConfirmed"); const debug = createDebug('chevre-domain:service:reserve:confirmReservation'); /** * 予約を確定する */ function confirmReservation(params) { return (repos // settings: Settings ) => __awaiter(this, void 0, void 0, function* () { // await Promise.all(params.actionAttributesList.map(async (potentialReserveAction) => { // const actionAttributes = await reserveIfNotYet(potentialReserveAction, { byTask: params.byTask })(repos); // if (params.useOnReservationConfirmed) { // await onReservationConfirmedByAction(actionAttributes)({ task: repos.task }); // } // })); const actionAttributes = yield reserveIfNotYet(params.potentialReserveAction, { byTask: params.byTask })(repos); if (params.useOnReservationConfirmed) { yield (0, onReservationConfirmed_1.onReservationConfirmedByAction)(actionAttributes)({ task: repos.task }); } if (params.useOnReservationConfirmed) { let confirmedReservations = []; // 確定予約通知タスクを予約番号単位で作成する(2022-12-21~) const reservationNumber = params.potentialReserveAction.object.reservationNumber; if (typeof reservationNumber === 'string' && reservationNumber.length > 0) { // 最新のconfirmedReservationsを検索 confirmedReservations = yield repos.reservation.projectFields({ reservationNumber: { $eq: reservationNumber }, typeOf: factory.reservationType.EventReservation } // project all fields // {} ); confirmedReservations = confirmedReservations.map((r) => { // _idは不要であり、存在すると予期せぬ影響を及ぼす可能性がある delete r._id; return r; }); } yield (0, onReservationConfirmed_1.onReservationConfirmed)(confirmedReservations, actionAttributes)(repos); } }); } function reserveTransaction2action(params) { var _a; const transaction = params.transaction; const reservationFor = transaction.object.reservationFor; if (reservationFor === undefined) { throw new factory.errors.NotFound('transaction.object.reservationFor'); } let underName; if (typeof ((_a = transaction.object.underName) === null || _a === void 0 ? void 0 : _a.typeOf) === 'string') { underName = transaction.object.underName; } const moneyTransferActions = []; const pendingReservations = (Array.isArray(transaction.object.subReservation)) ? transaction.object.subReservation : []; pendingReservations.forEach((reservation) => { var _a; const acceptedOffer4reservation = (_a = transaction.object.acceptedOffer) === null || _a === void 0 ? void 0 : _a.find((o) => { var _a, _b; return ((_b = (_a = o.itemOffered) === null || _a === void 0 ? void 0 : _a.serviceOutput) === null || _b === void 0 ? void 0 : _b.id) === reservation.id; }); moneyTransferActions.push(...(0, factory_1.createMoneyTransferActions)({ acceptedOffer: acceptedOffer4reservation, reservation, transaction: params.transaction, underName })); }); const reservationPackage = { reservationFor: { id: String(reservationFor.id), typeOf: reservationFor.typeOf, optimized: true }, reservationNumber: transaction.object.reservationNumber, reservationStatus: (typeof params.transaction.object.reservationStatus === 'string') ? params.transaction.object.reservationStatus : factory.reservationStatusType.ReservationPending, typeOf: factory.reservationType.ReservationPackage }; return Object.assign({ project: transaction.project, typeOf: factory.actionType.ReserveAction, object: reservationPackage, agent: transaction.project, potentialActions: { moneyTransfer: moneyTransferActions }, purpose: { typeOf: transaction.typeOf, id: transaction.id } }, (Array.isArray(transaction.instrument)) ? { instrument: transaction.instrument } : undefined // add(2025-02-17~) ); } function reserveIfNotYet( // params: factory.action.reserve.IAttributes, params, options) { // tslint:disable-next-line:max-func-body-length return (repos) => __awaiter(this, void 0, void 0, function* () { var _a, _b; const reservationPackage = params.object; const reserveTransaction = (yield repos.assetTransaction.search({ limit: 1, page: 1, typeOf: factory.assetTransactionType.Reserve, transactionNumber: { $eq: reservationPackage.reservationNumber } })).shift(); if (reserveTransaction === undefined) { throw new factory.errors.NotFound(factory.assetTransactionType.Reserve); } const actionAttributes = reserveTransaction2action({ transaction: reserveTransaction }); // 冪等性を担保(2023-05-31~) debug('searching completed reserveAction... byTask:', options === null || options === void 0 ? void 0 : options.byTask, 'reservationNumber:', reservationPackage.reservationNumber); const completedActions = yield repos.action.search({ limit: 1, page: 1, actionStatus: { $in: [factory.actionStatusType.CompletedActionStatus] }, typeOf: { $eq: actionAttributes.typeOf }, object: { typeOf: { $eq: actionAttributes.object.typeOf } // reservationNumber: { $eq: params.object.reservationNumber } }, purpose: { id: { $in: [actionAttributes.purpose.id] }, typeOf: { $in: [actionAttributes.purpose.typeOf] } } }, ['id']); debug(completedActions.length, 'completed reserveAction found. byTask:', options === null || options === void 0 ? void 0 : options.byTask, 'reservationNumber:', reservationPackage.reservationNumber); if (completedActions.length === 0) { const action = yield repos.action.start(actionAttributes); try { let underName; // 予約取引に保管されたunderNameを使用する(2023-05-30~) if (typeof ((_a = reserveTransaction.object.underName) === null || _a === void 0 ? void 0 : _a.typeOf) === 'string') { underName = reserveTransaction.object.underName; // 廃止(2023-05-31~)→予約取引から取得に変更 // } else if (typeof reservationPackage.underName?.typeOf === 'string') { // underName = reservationPackage.underName; } // ReservationPackageに対応(2022-12-22~) if (actionAttributes.object.typeOf === factory.reservationType.ReservationPackage) { // Pendingの予約が存在しないバージョンに対応する(2023-05-29~) if (reserveTransaction.object.disablePendingReservations === true) { const reservationFor = reserveTransaction.object.reservationFor; const subReservations = reserveTransaction.object.subReservation; const issuedThrough = reserveTransaction.object.issuedThrough; if (Array.isArray(subReservations) && typeof (reservationFor === null || reservationFor === void 0 ? void 0 : reservationFor.typeOf) === 'string' && typeof (issuedThrough === null || issuedThrough === void 0 ? void 0 : issuedThrough.typeOf) === 'string') { // confirmManyに変更(2023-06-13~) const confirmManyIfNotExistResult = yield repos.reservation.confirmManyIfNotExist({ bookingTime: reserveTransaction.startDate, // startDateに設定(2024-04-08~) project: { id: reserveTransaction.project.id }, provider: (typeof ((_b = reserveTransaction.object.provider) === null || _b === void 0 ? void 0 : _b.id) === 'string') ? reserveTransaction.object.provider : { id: reserveTransaction.agent.id, typeOf: factory.organizationType.Corporation }, subReservation: subReservations, issuedThrough, reservationFor, reservationNumber: reserveTransaction.object.reservationNumber, underName, broker: reserveTransaction.object.broker }); debug('confirmManyIfNotExistResult:', confirmManyIfNotExistResult, 'reservationNumber:', reservationPackage.reservationNumber); } } else { // 旧予約取引に対して本処理が走る可能性がなくはないが、 // それらについては実質Confirmedの予約はすでに存在するはずなので、何もしない // 完全廃止(2023-07-19~) // throw new factory.errors.NotImplemented('disablePendingReservations must be true'); } } else { // 廃止(2023-01-18) throw new factory.errors.Forbidden(`${actionAttributes.object.typeOf} not acceptable`); } } catch (error) { try { yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error }); } catch (__) { // 失敗したら仕方ない } throw error; } const actionResult = {}; yield repos.action.completeWithVoid({ typeOf: action.typeOf, id: action.id, result: actionResult }); } return actionAttributes; }); }