@chevre/domain
Version:
Chevre Domain Library for Node.js
187 lines (186 loc) • 9.32 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.preStart = void 0;
exports.start = start;
exports.confirm = confirm;
exports.exportTasksById = exportTasksById;
/**
* 返品取引サービス
*/
const moment = require("moment-timezone");
const factory = require("../../factory");
const factory_1 = require("./returnOrder/exportTasks/factory");
const potentialActions_1 = require("./returnOrder/potentialActions");
const preStart_1 = require("./returnOrder/preStart");
Object.defineProperty(exports, "preStart", { enumerable: true, get: function () { return preStart_1.preStart; } });
const errorHandler_1 = require("../../errorHandler");
/**
* 返品取引開始
*/
function start(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const { transactionObject, expiresInSeconds, seller } = yield (0, preStart_1.preStart)(params)(repos);
const returnOrderAttributes = {
project: params.project,
typeOf: factory.transactionType.ReturnOrder,
agent: params.agent,
seller: {
id: String(seller.id),
typeOf: seller.typeOf,
name: seller.name
},
object: transactionObject,
expiresInSeconds
};
let returnOrderTransaction;
try {
returnOrderTransaction = yield repos.transaction.start(returnOrderAttributes);
}
catch (error) {
if (yield (0, errorHandler_1.isMongoError)(error)) {
// 同一取引に対して返品取引を作成しようとすると、MongoDBでE11000 duplicate key errorが発生する
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (error.code === errorHandler_1.MongoErrorCode.DuplicateKey) {
throw new factory.errors.Argument('orderNumber', 'Already returned');
}
}
throw error;
}
return returnOrderTransaction;
});
}
function saveMessagesIfNeeded(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const { project, order, emailMessages, seller } = params;
if (emailMessages.length > 0) {
const { orderNumber } = order;
// const saveMessageResult = await repos.message.upsertByIdentifier(
// emailMessages.map(({ identifier, name, about, text, toRecipient, sender }) => {
// return {
// identifier, name, about, text, toRecipient, sender,
// project: { id: project.id, typeOf: factory.organizationType.Project },
// provider: { id: seller.id, typeOf: factory.organizationType.Corporation },
// mainEntity: { orderNumber, typeOf: factory.order.OrderType.Order }
// };
// })
// );
for (const { identifier, name, about, text, toRecipient, sender } of emailMessages) {
yield repos.message.upsertOneByIdentifier({
identifier, name, about, text, toRecipient, sender,
project: { id: project.id, typeOf: factory.organizationType.Project },
provider: { id: seller.id, typeOf: factory.organizationType.Corporation },
mainEntity: { orderNumber, typeOf: factory.order.OrderType.Order }
});
}
}
});
}
/**
* 取引確定
*/
function confirm(params) {
return (repos
// settings: Settings
) => __awaiter(this, void 0, void 0, function* () {
var _a;
const transaction = yield repos.transaction.projectFieldsById({ typeOf: factory.transactionType.ReturnOrder, id: params.id }, ['typeOf', 'status', 'project', 'agent', 'object', 'result']);
if (transaction.status === factory.transactionStatusType.Confirmed) {
// すでに確定済の場合
return transaction.result;
}
else if (transaction.status === factory.transactionStatusType.Expired) {
throw new factory.errors.Argument('transaction', 'Transaction already expired');
}
else if (transaction.status === factory.transactionStatusType.Canceled) {
throw new factory.errors.Argument('transaction', 'Transaction already canceled');
}
if (typeof ((_a = params.agent) === null || _a === void 0 ? void 0 : _a.id) === 'string' && transaction.agent.id !== params.agent.id) {
throw new factory.errors.Forbidden('Transaction not yours');
}
// ひとまず同時返品可能な注文数を1に限定(2022-04-28~)
if (transaction.object.order.length !== 1) {
throw new factory.errors.Argument('object.order', 'number of orders must be 1');
}
const returningOrders = yield repos.order.projectFields({
limit: 1,
page: 1,
project: { id: { $eq: transaction.project.id } },
confirmationNumbers: [transaction.object.order[0].confirmationNumber],
orderNumbers: [transaction.object.order[0].orderNumber]
}, {
inclusion: [
'confirmationNumber', 'customer', 'identifier', 'orderDate', 'orderNumber', 'orderStatus',
'orderedItem', 'paymentMethods', 'price', 'priceCurrency', 'project', 'seller', 'typeOf'
]
});
// デフォルトEメールメッセージを検索
let emailMessageOnOrderReturned;
if (repos.emailMessage !== undefined) {
const searchEmailMessagesResult = yield repos.emailMessage.search({
limit: 1,
page: 1,
project: { id: { $eq: transaction.project.id } },
about: { identifier: { $eq: factory.creativeWork.message.email.AboutIdentifier.OnOrderReturned } }
});
emailMessageOnOrderReturned = searchEmailMessagesResult.shift();
}
const setting = yield repos.setting.findOne({ project: { id: { $eq: '*' } } }, ['defaultSenderEmail']);
if (typeof (setting === null || setting === void 0 ? void 0 : setting.defaultSenderEmail) !== 'string') {
throw new factory.errors.NotFound('setting.defaultSenderEmail');
}
const result = {};
const { emailMessages, potentialActions } = yield (0, potentialActions_1.createPotentialActions)(Object.assign(Object.assign({ dateReturned: params.object.order.dateReturned, orders: returningOrders, transaction: transaction }, (params.potentialActions !== undefined) ? { potentialActions: params.potentialActions } : undefined), (emailMessageOnOrderReturned !== undefined) ? { emailMessageOnOrderReturned } : undefined),
// settings
setting);
// save messages(2024-06-27~)
yield saveMessagesIfNeeded({
project: { id: transaction.project.id },
order: { orderNumber: returningOrders[0].orderNumber }, seller: { id: returningOrders[0].seller.id }, emailMessages
})(repos);
// ステータス変更
yield repos.transaction.confirm({
typeOf: transaction.typeOf,
id: transaction.id,
result, potentialActions
});
return result;
});
}
/**
* 取引のタスクを出力します
* 複数タスクが生成されます
* この関数では、取引のタスクエクスポートステータスは見ません
*/
function exportTasksById(params) {
return (repos
// settings: Settings
) => __awaiter(this, void 0, void 0, function* () {
const transaction = yield repos.transaction.projectFieldsById({ typeOf: factory.transactionType.ReturnOrder, id: params.id }, ['typeOf', 'status', 'project', 'endDate', 'startDate', 'object', 'potentialActions']);
// タスク実行日時バッファの指定があれば調整
let taskRunsAt = new Date();
if (typeof params.runsTasksAfterInSeconds === 'number') {
taskRunsAt = moment(taskRunsAt)
.add(params.runsTasksAfterInSeconds, 'seconds')
.toDate();
}
// search settings
const setting = yield repos.setting.findOne({ project: { id: { $eq: '*' } } }, ['storage']);
const taskAttributes = (0, factory_1.createTasks)({
transaction,
runsAt: taskRunsAt
}, setting
// settings
);
yield repos.task.saveMany(taskAttributes, { emitImmediately: true });
});
}