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