UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

384 lines (383 loc) 23.3 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.deleteTransaction = deleteTransaction; const factory = require("../../factory"); const deleteOrder_1 = require("../order/deleteOrder"); /** * 取引に関わるリソースを削除する * 冪等性を確保すること */ function deleteTransaction(params) { // tslint:disable-next-line:max-func-body-length return (repos) => __awaiter(this, void 0, void 0, function* () { if (params.object.specifyingMethod === factory.task.deleteTransaction.SpecifyingMethod.AgentId) { // transaction.agent.id指定による取引削除に対応(2023-06-30~) yield createDeleteTransactionTasksByAgentId(params)(repos); } else { yield deleteTransactionById(params)(repos); } }); } function createDeleteTransactionTasksByAgentId(params) { // tslint:disable-next-line:max-func-body-length return (repos) => __awaiter(this, void 0, void 0, function* () { if (params.object.specifyingMethod !== factory.task.deleteTransaction.SpecifyingMethod.AgentId) { throw new factory.errors.Argument('object.specifyingMethod', `must be ${factory.task.deleteTransaction.SpecifyingMethod.Id}`); } const agentIdSpecified = params.object.agent.id; // agentIdによる全取引についてDeleteTransactionタスクを作成する if (typeof agentIdSpecified === 'string' && agentIdSpecified.length > 0) { const transactionTypeOf = params.object.typeOf; const transactions = yield repos.transaction.projectFields({ project: { id: { $eq: params.object.project.id } }, agent: { ids: [agentIdSpecified], typeOf: factory.personType.Person }, typeOf: transactionTypeOf, inclusion: ['typeOf', 'startDate', 'endDate', 'object', 'project'] }); const deleteAt = new Date(); let deleteTransactionTasks = []; switch (transactionTypeOf) { case factory.transactionType.PlaceOrder: deleteTransactionTasks = transactions.map((transaction) => { return { project: transaction.project, name: factory.taskName.DeleteTransaction, status: factory.taskStatus.Ready, runsAt: deleteAt, remainingNumberOfTries: 3, numberOfTried: 0, executionResults: [], data: { object: Object.assign({ specifyingMethod: factory.task.deleteTransaction.SpecifyingMethod.Id, id: transaction.id, object: Object.assign(Object.assign({}, (typeof transaction.object.confirmationNumber === 'string') ? { confirmationNumber: transaction.object.confirmationNumber } : undefined), (typeof transaction.object.orderNumber === 'string') ? { orderNumber: transaction.object.orderNumber } : undefined), project: transaction.project, startDate: transaction.startDate, typeOf: transaction.typeOf }, (transaction.endDate !== undefined) ? { endDate: transaction.endDate } : undefined) } }; }); break; case factory.transactionType.ReturnOrder: deleteTransactionTasks = transactions.map((transaction) => { return { project: transaction.project, name: factory.taskName.DeleteTransaction, status: factory.taskStatus.Ready, runsAt: deleteAt, remainingNumberOfTries: 3, numberOfTried: 0, executionResults: [], data: { object: Object.assign({ specifyingMethod: factory.task.deleteTransaction.SpecifyingMethod.Id, id: transaction.id, object: { order: transaction.object.order }, project: transaction.project, startDate: transaction.startDate, typeOf: transaction.typeOf }, (transaction.endDate !== undefined) ? { endDate: transaction.endDate } : undefined) } }; }); break; case factory.transactionType.MoneyTransfer: deleteTransactionTasks = transactions.map((transaction) => { return { project: transaction.project, name: factory.taskName.DeleteTransaction, status: factory.taskStatus.Ready, runsAt: deleteAt, remainingNumberOfTries: 3, numberOfTried: 0, executionResults: [], data: { object: Object.assign({ specifyingMethod: factory.task.deleteTransaction.SpecifyingMethod.Id, id: transaction.id, object: Object.assign({}, (transaction.object.pendingTransaction !== undefined) ? { pendingTransaction: transaction.object.pendingTransaction } : undefined), project: transaction.project, startDate: transaction.startDate, typeOf: transaction.typeOf }, (transaction.endDate !== undefined) ? { endDate: transaction.endDate } : undefined) } }; }); break; default: throw new factory.errors.NotImplemented(`${transactionTypeOf} not implemented`); } if (deleteTransactionTasks.length > 0) { yield repos.task.saveMany(deleteTransactionTasks, { emitImmediately: true }); } } }); } function deleteTransactionById(params) { // tslint:disable-next-line:max-func-body-length return (repos) => __awaiter(this, void 0, void 0, function* () { var _a; if (typeof params.object.specifyingMethod === 'string' && params.object.specifyingMethod !== factory.task.deleteTransaction.SpecifyingMethod.Id) { throw new factory.errors.Argument('object.specifyingMethod', `must be ${factory.task.deleteTransaction.SpecifyingMethod.Id}`); } const deletingTransactionId = params.object.id; if (typeof deletingTransactionId !== 'string' || deletingTransactionId.length === 0) { throw new factory.errors.ArgumentNull('object.id'); } const transaction = (yield repos.transaction.projectFields({ ids: [deletingTransactionId], typeOf: params.object.typeOf, inclusion: ['typeOf', 'project', 'status', 'result'] })).shift(); if (transaction === undefined) { // すでに削除済 return; } // アクション開始 const actionAttributes = { typeOf: factory.actionType.DeleteAction, project: transaction.project, object: params.object, agent: transaction.project }; let deletePayTransactionResult; let deleteRefundResult; let payTransactionNumbers = []; let deleteReservationsResult; let deleteReserveTransactionResult; let deleteCancelReservationTransactionResult; let deletedReservationNumbers = []; let deleteActionResult; let deleteMessagessResult; const action = yield repos.action.start(actionAttributes); try { const transactionTypeOf = transaction.typeOf; switch (transactionTypeOf) { case factory.transactionType.PlaceOrder: // 取引に対する全ての承認アクションを検索 const authorizeActions = yield repos.action.searchByPurpose({ typeOf: factory.actionType.AuthorizeAction, purpose: { typeOf: transactionTypeOf, id: transaction.id } }); switch (transaction.status) { case factory.transactionStatusType.Canceled: case factory.transactionStatusType.Expired: break; case factory.transactionStatusType.Confirmed: const deletingOrder = (_a = transaction.result) === null || _a === void 0 ? void 0 : _a.order; if (typeof (deletingOrder === null || deletingOrder === void 0 ? void 0 : deletingOrder.orderNumber) === 'string') { yield (0, deleteOrder_1.deleteOrder)({ object: deletingOrder })(repos); } break; default: throw new factory.errors.NotImplemented(`${transaction.status} not implemented`); } // tslint:disable-next-line:no-suspicious-comment // TODO サービス登録取引を削除 // 決済取引を削除 const deletePayTransactionsByPlaceOrderResult = yield deletePayTransactionsByPlaceOrder({ authorizeActions, transaction })(repos); deletePayTransactionResult = deletePayTransactionsByPlaceOrderResult.deletePayTransactionResult; deleteRefundResult = deletePayTransactionsByPlaceOrderResult.deleteRefundResult; payTransactionNumbers = deletePayTransactionsByPlaceOrderResult.payTransactionNumbers; // 取引上での予約を削除 const deleteReservationsByPlaceOrderResult = yield deleteReservationsByPlaceOrder({ authorizeActions, transaction })(repos); deleteReservationsResult = deleteReservationsByPlaceOrderResult.deleteResult; deleteReserveTransactionResult = deleteReservationsByPlaceOrderResult.deleteReserveTransactionResult; deleteCancelReservationTransactionResult = deleteReservationsByPlaceOrderResult.deleteCancelReservationTransactionResult; deletedReservationNumbers = deleteReservationsByPlaceOrderResult.reserveTransactionNumbers; // アクション削除(2023-05-19~) deleteActionResult = yield repos.action.deleteByPurpose({ project: { id: transaction.project.id }, purpose: { id: transaction.id, typeOf: transactionTypeOf }, typeOf: { $in: [ factory.actionType.AuthorizeAction, factory.actionType.CheckAction, factory.actionType.InformAction, factory.actionType.OrderAction ] } }); // messages削除(2024-05-01~) const deleteMessagesByPlaceOrderResult = yield deleteMessagesByPlaceOrder({ transaction: params.object })(repos); deleteMessagessResult = deleteMessagesByPlaceOrderResult.deleteResult; // 取引削除 yield repos.transaction.findByIdAndDelete({ id: transaction.id }); break; // implemented(2022-06-09~) case factory.transactionType.ReturnOrder: // 取引削除 yield repos.transaction.findByIdAndDelete({ id: transaction.id }); break; // implemented(2022-06-09~) case factory.transactionType.MoneyTransfer: // 取引削除 yield repos.transaction.findByIdAndDelete({ id: transaction.id }); break; default: throw new factory.errors.NotImplemented(`${transactionTypeOf} not implemented`); } } catch (error) { try { yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error }); } catch (__) { // 失敗したら仕方ない } throw error; } // アクション完了 const actionResult = Object.assign({ deletePayTransactionResult, deleteRefundResult, payTransactionNumbers, deleteReservationsResult, deleteReserveTransactionResult, deleteCancelReservationTransactionResult, deletedReservationNumbers, deleteActionResult }, (deleteMessagessResult !== undefined) ? { deleteMessagessResult } : undefined); yield repos.action.completeWithVoid({ typeOf: action.typeOf, id: action.id, result: actionResult }); }); } function deleteReservationsByPlaceOrder(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { let deleteResult; let deleteReserveTransactionResult; let deleteCancelReservationTransactionResult; const authorizeActions = params.authorizeActions; // 予約取引番号を抽出 const authorizeReservationOfferActions = authorizeActions .filter((a) => { var _a; const pendingTransactionNumber = (_a = a.instrument) === null || _a === void 0 ? void 0 : _a.transactionNumber; return a.object.typeOf === factory.action.authorize.offer.eventService.ObjectType.SeatReservation && typeof pendingTransactionNumber === 'string' && pendingTransactionNumber.length > 0; }); const reserveTransactionNumbers = authorizeReservationOfferActions .map((a) => { var _a; return String((_a = a.instrument) === null || _a === void 0 ? void 0 : _a.transactionNumber); }); if (reserveTransactionNumbers.length > 0) { // 該当予約番号の予約を削除する(プロジェクトでも絞ること) const deleteReservationsResult = yield repos.reservation.deleteByReservationNumbers({ project: { id: params.transaction.project.id }, reservationNumbers: reserveTransactionNumbers }); deleteResult = { n: deleteReservationsResult === null || deleteReservationsResult === void 0 ? void 0 : deleteReservationsResult.n, ok: deleteReservationsResult === null || deleteReservationsResult === void 0 ? void 0 : deleteReservationsResult.ok, deletedCount: deleteReservationsResult === null || deleteReservationsResult === void 0 ? void 0 : deleteReservationsResult.deletedCount }; // 予約取引を削除(プロジェクトでも絞ること)(2022-06-07~) const deleteAssetTransactionsResult = yield repos.assetTransaction.deleteByTransactionNumber({ project: { id: params.transaction.project.id }, transactionNumbers: reserveTransactionNumbers, typeOf: factory.assetTransactionType.Reserve }); deleteReserveTransactionResult = { n: deleteAssetTransactionsResult === null || deleteAssetTransactionsResult === void 0 ? void 0 : deleteAssetTransactionsResult.n, ok: deleteAssetTransactionsResult === null || deleteAssetTransactionsResult === void 0 ? void 0 : deleteAssetTransactionsResult.ok, deletedCount: deleteAssetTransactionsResult === null || deleteAssetTransactionsResult === void 0 ? void 0 : deleteAssetTransactionsResult.deletedCount }; // 予約番号で予約取消取引を検索 const deletingCancelReservationTransactions = yield repos.assetTransaction.search({ project: { id: { $eq: params.transaction.project.id } }, object: { reservationNumber: { $in: reserveTransactionNumbers } }, typeOf: factory.assetTransactionType.CancelReservation }, ['transactionNumber'], []); if (deletingCancelReservationTransactions.length > 0) { // 予約取消取引も削除(2024-04-18~) const deleteCancelReservationResult = yield repos.assetTransaction.deleteByTransactionNumber({ project: { id: params.transaction.project.id }, transactionNumbers: deletingCancelReservationTransactions.map(({ transactionNumber }) => String(transactionNumber)), typeOf: factory.assetTransactionType.CancelReservation }); deleteCancelReservationTransactionResult = { n: deleteCancelReservationResult === null || deleteCancelReservationResult === void 0 ? void 0 : deleteCancelReservationResult.n, ok: deleteCancelReservationResult === null || deleteCancelReservationResult === void 0 ? void 0 : deleteCancelReservationResult.ok, deletedCount: deleteCancelReservationResult === null || deleteCancelReservationResult === void 0 ? void 0 : deleteCancelReservationResult.deletedCount }; } } return { deleteResult, deleteReserveTransactionResult, deleteCancelReservationTransactionResult, reserveTransactionNumbers }; }); } function deletePayTransactionsByPlaceOrder(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { let deletePayTransactionResult; let deleteRefundResult; const authorizeActions = params.authorizeActions; // 決済取引番号を抽出 const authorizePaymentActions = authorizeActions .filter((a) => { var _a; const pendingTransactionNumber = (_a = a.object) === null || _a === void 0 ? void 0 : _a.paymentMethodId; return a.object.typeOf === factory.action.authorize.paymentMethod.any.ResultType.Payment && typeof pendingTransactionNumber === 'string' && pendingTransactionNumber.length > 0; }); const payTransactionNumbers = authorizePaymentActions.map((a) => String(a.object.paymentMethodId)); if (payTransactionNumbers.length > 0) { // 決済取引を削除(プロジェクトでも絞ること)(2022-06-07~) const deleteAssetTransactionsResult = yield repos.assetTransaction.deleteByTransactionNumber({ project: { id: params.transaction.project.id }, transactionNumbers: payTransactionNumbers, typeOf: factory.assetTransactionType.Pay }); deletePayTransactionResult = { n: deleteAssetTransactionsResult === null || deleteAssetTransactionsResult === void 0 ? void 0 : deleteAssetTransactionsResult.n, ok: deleteAssetTransactionsResult === null || deleteAssetTransactionsResult === void 0 ? void 0 : deleteAssetTransactionsResult.ok, deletedCount: deleteAssetTransactionsResult === null || deleteAssetTransactionsResult === void 0 ? void 0 : deleteAssetTransactionsResult.deletedCount }; // 返金取引も削除(2023-05-19~) const refundTransactions = yield repos.assetTransaction.search({ typeOf: factory.assetTransactionType.Refund, object: { paymentMethodId: { $in: payTransactionNumbers } } }, ['transactionNumber'], []); if (refundTransactions.length > 0) { const deleteRefundAssetTransactionsResult = yield repos.assetTransaction.deleteByTransactionNumber({ project: { id: params.transaction.project.id }, transactionNumbers: refundTransactions.map(({ transactionNumber }) => transactionNumber), typeOf: factory.assetTransactionType.Refund }); deleteRefundResult = { n: deleteRefundAssetTransactionsResult === null || deleteRefundAssetTransactionsResult === void 0 ? void 0 : deleteRefundAssetTransactionsResult.n, ok: deleteRefundAssetTransactionsResult === null || deleteRefundAssetTransactionsResult === void 0 ? void 0 : deleteRefundAssetTransactionsResult.ok, deletedCount: deleteRefundAssetTransactionsResult === null || deleteRefundAssetTransactionsResult === void 0 ? void 0 : deleteRefundAssetTransactionsResult.deletedCount }; } } return { deletePayTransactionResult, deleteRefundResult, payTransactionNumbers }; }); } function deleteMessagesByPlaceOrder(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { let deleteResult; if (params.transaction.typeOf === factory.transactionType.PlaceOrder && params.transaction.specifyingMethod === factory.task.deleteTransaction.SpecifyingMethod.Id) { const orderNumber = params.transaction.object.orderNumber; if (typeof orderNumber === 'string' && orderNumber.length > 0) { const deleteReservationsResult = yield repos.message.deleteByMainEntityOrderNumber({ project: { id: params.transaction.project.id }, mainEntity: { orderNumber } }); deleteResult = { n: deleteReservationsResult === null || deleteReservationsResult === void 0 ? void 0 : deleteReservationsResult.n, ok: deleteReservationsResult === null || deleteReservationsResult === void 0 ? void 0 : deleteReservationsResult.ok, deletedCount: deleteReservationsResult === null || deleteReservationsResult === void 0 ? void 0 : deleteReservationsResult.deletedCount }; } } return { deleteResult }; }); }