UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

283 lines (282 loc) 14.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.AccountTransactionRepo = void 0; const moment = require("moment"); const accountTransaction_1 = require("./mongoose/schemas/accountTransaction"); const factory = require("../factory"); const settings_1 = require("../settings"); /** * 口座取引リポジトリ */ class AccountTransactionRepo { constructor(connection) { this.transactionModel = connection.model(accountTransaction_1.modelName, (0, accountTransaction_1.createSchema)()); } static CREATE_MONGO_CONDITIONS(params) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s; const andConditions = []; const projectIdEq = (_b = (_a = params.project) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.$eq; if (typeof projectIdEq === 'string') { andConditions.push({ 'project.id': { $eq: projectIdEq } }); } const typeOfEq = (_c = params.typeOf) === null || _c === void 0 ? void 0 : _c.$eq; if (typeof typeOfEq === 'string') { andConditions.push({ typeOf: { $eq: typeOfEq } }); } const startDateGte = (_d = params.startDate) === null || _d === void 0 ? void 0 : _d.$gte; if (startDateGte instanceof Date) { andConditions.push({ startDate: { $gte: startDateGte } }); } const startDateLte = (_e = params.startDate) === null || _e === void 0 ? void 0 : _e.$lte; if (startDateLte instanceof Date) { andConditions.push({ startDate: { $lte: startDateLte } }); } const statusIn = (_f = params.status) === null || _f === void 0 ? void 0 : _f.$in; if (Array.isArray(statusIn)) { andConditions.push({ status: { $in: statusIn } }); } const identifierEq = (_g = params.identifier) === null || _g === void 0 ? void 0 : _g.$eq; if (typeof identifierEq === 'string') { andConditions.push({ identifier: { $exists: true, $eq: identifierEq } }); } const transactionNumberEq = (_h = params.transactionNumber) === null || _h === void 0 ? void 0 : _h.$eq; if (typeof transactionNumberEq === 'string') { andConditions.push({ transactionNumber: { $eq: transactionNumberEq } }); } const fromLocationAccountNumberEq = (_l = (_k = (_j = params.object) === null || _j === void 0 ? void 0 : _j.fromLocation) === null || _k === void 0 ? void 0 : _k.accountNumber) === null || _l === void 0 ? void 0 : _l.$eq; if (typeof fromLocationAccountNumberEq === 'string') { andConditions.push({ 'object.fromLocation.accountNumber': { $exists: true, $eq: fromLocationAccountNumberEq } }); } const toLocationAccountNumberEq = (_p = (_o = (_m = params.object) === null || _m === void 0 ? void 0 : _m.toLocation) === null || _o === void 0 ? void 0 : _o.accountNumber) === null || _p === void 0 ? void 0 : _p.$eq; if (typeof toLocationAccountNumberEq === 'string') { andConditions.push({ 'object.toLocation.accountNumber': { $exists: true, $eq: toLocationAccountNumberEq } }); } const locationAccountNumberEq = (_s = (_r = (_q = params.object) === null || _q === void 0 ? void 0 : _q.location) === null || _r === void 0 ? void 0 : _r.accountNumber) === null || _s === void 0 ? void 0 : _s.$eq; if (typeof locationAccountNumberEq === 'string') { andConditions.push({ $or: [ { 'object.fromLocation.accountNumber': { $exists: true, $eq: locationAccountNumberEq } }, { 'object.toLocation.accountNumber': { $exists: true, $eq: locationAccountNumberEq } } ] }); } return andConditions; } /** * 取引を開始する */ start(params) { return __awaiter(this, void 0, void 0, function* () { return this.transactionModel.create(Object.assign(Object.assign({}, params), { status: factory.transactionStatusType.InProgress, startDate: new Date(), endDate: undefined })) .then((doc) => doc.toObject()); }); } startByIdentifier(params) { return __awaiter(this, void 0, void 0, function* () { const startDate = new Date(); if (typeof params.identifier === 'string' && params.identifier.length > 0) { return this.transactionModel.findOneAndUpdate({ identifier: { $exists: true, $eq: params.identifier }, status: { // InProgress,Confirmedについては、identifierで取引のユニークネスが保証されるように $in: [factory.transactionStatusType.InProgress, factory.transactionStatusType.Confirmed] } }, { $setOnInsert: Object.assign(Object.assign({}, params), { status: factory.transactionStatusType.InProgress, startDate: startDate, endDate: undefined }) }, { new: true, upsert: true }) .exec() .then((doc) => { if (doc === null) { throw new factory.errors.NotFound(this.transactionModel.modelName); } // 以前に開始した取引であればエラー const transaction = doc.toObject(); if (transaction.status === factory.transactionStatusType.Confirmed) { throw new factory.errors.Argument('identifier', 'already confirmed'); } if (!moment(transaction.startDate) .isSame(startDate)) { throw new factory.errors.Argument('identifier', 'another transaction in progress'); } return doc.toObject(); }); } else { return this.start(params); } }); } /** * 取引検索 */ findById(params) { return __awaiter(this, void 0, void 0, function* () { const doc = yield this.transactionModel.findOne(Object.assign({ _id: params.id }, (typeof params.typeOf === 'string') ? { typeOf: params.typeOf } : undefined)) .exec(); if (doc === null) { throw new factory.errors.NotFound('Transaction'); } return doc.toObject(); }); } // tslint:disable-next-line:no-single-line-block-comment /* istanbul ignore next */ findByTransactionNumber(params) { return __awaiter(this, void 0, void 0, function* () { const doc = yield this.transactionModel.findOne(Object.assign({ transactionNumber: { $exists: true, $eq: params.transactionNumber } }, (typeof params.typeOf === 'string') ? { typeOf: params.typeOf } : undefined)) .exec(); if (doc === null) { throw new factory.errors.NotFound('Transaction'); } return doc.toObject(); }); } /** * 取引を確定する */ confirm(params) { return __awaiter(this, void 0, void 0, function* () { const doc = yield this.transactionModel.findOneAndUpdate(Object.assign({ _id: params.id, status: factory.transactionStatusType.InProgress }, (typeof params.typeOf === 'string') ? { typeOf: params.typeOf } : undefined), { status: factory.transactionStatusType.Confirmed, endDate: new Date(), // result: params.result, // resultを更新 potentialActions: params.potentialActions }, { new: true }) .exec(); // NotFoundであれば取引状態確認 if (doc === null) { const transaction = yield this.findById({ typeOf: params.typeOf, id: params.id }); if (transaction.status === factory.transactionStatusType.Confirmed) { return transaction; } else { throw new factory.errors.Argument('transactionId', `Transaction ${transaction.status}`); } } return doc.toObject(); }); } /** * 取引を中止する */ cancel(params) { return __awaiter(this, void 0, void 0, function* () { if (typeof params.id !== 'string' && typeof params.transactionNumber !== 'string') { // tslint:disable-next-line:no-single-line-block-comment /* istanbul ignore next */ throw new factory.errors.ArgumentNull('Transaction ID or Transaction Number'); } // 進行中ステータスの取引を中止する const doc = yield this.transactionModel.findOneAndUpdate(Object.assign(Object.assign(Object.assign({ status: factory.transactionStatusType.InProgress }, (typeof params.id === 'string') ? { _id: params.id } : /* istanbul ignore next */ undefined), (typeof params.transactionNumber === 'string') // tslint:disable-next-line:no-single-line-block-comment /* istanbul ignore next */ ? { transactionNumber: { $exists: true, $eq: params.transactionNumber } } : undefined), (typeof params.typeOf === 'string') ? { typeOf: params.typeOf } : undefined), { status: factory.transactionStatusType.Canceled, endDate: new Date() }, { new: true }) .exec(); // NotFoundであれば取引状態確認 if (doc === null) { let transaction; // tslint:disable-next-line:no-single-line-block-comment /* istanbul ignore else */ if (typeof params.id === 'string') { transaction = yield this.findById({ typeOf: params.typeOf, id: params.id }); } else if (typeof params.transactionNumber === 'string') { // tslint:disable-next-line:no-single-line-block-comment /* istanbul ignore next */ transaction = yield this.findByTransactionNumber({ typeOf: params.typeOf, transactionNumber: params.transactionNumber }); } else { // tslint:disable-next-line:no-single-line-block-comment /* istanbul ignore next */ throw new factory.errors.ArgumentNull('Transaction ID or Transaction Number'); } if (transaction.status === factory.transactionStatusType.Canceled) { return transaction; } else { throw new factory.errors.Argument('transactionId', `Transaction ${transaction.status}`); } } return doc.toObject(); }); } /** * 取引を期限切れにする */ makeExpired(params) { return __awaiter(this, void 0, void 0, function* () { // ステータスと期限を見て更新 yield this.transactionModel.updateMany({ status: factory.transactionStatusType.InProgress, expires: { $lt: params.expires.$lt } }, { status: factory.transactionStatusType.Expired, endDate: new Date() }) .exec(); }); } /** * 取引を検索する */ search(params) { return __awaiter(this, void 0, void 0, function* () { var _a; const conditions = AccountTransactionRepo.CREATE_MONGO_CONDITIONS(params); const query = this.transactionModel.find((conditions.length > 0) ? { $and: conditions } : {}) .select({ __v: 0, createdAt: 0, updatedAt: 0 }); if (typeof params.limit === 'number' && params.limit > 0) { const page = (typeof params.page === 'number' && params.page > 0) ? params.page : 1; query.limit(params.limit) .skip(params.limit * (page - 1)); } // tslint:disable-next-line:no-single-line-block-comment /* istanbul ignore else */ if (((_a = params.sort) === null || _a === void 0 ? void 0 : _a.startDate) !== undefined) { query.sort({ startDate: params.sort.startDate }); } return query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS }) .exec() .then((docs) => docs.map((doc) => doc.toObject())); }); } clean(params) { return __awaiter(this, void 0, void 0, function* () { var _a; yield this.transactionModel.deleteMany(Object.assign({ // 終了日時を一定期間過ぎたもの endDate: { $exists: true, $lt: params.endDate.$lt } }, (typeof ((_a = params.project) === null || _a === void 0 ? void 0 : _a.id) === 'string') ? { 'project.id': { $eq: params.project.id } } : undefined)) .exec(); }); } } exports.AccountTransactionRepo = AccountTransactionRepo;