@chevre/domain
Version:
Chevre Domain Library for Node.js
197 lines (196 loc) • 11.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.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;
});
}