@chevre/domain
Version:
Chevre Domain Library for Node.js
234 lines (233 loc) • 10.7 kB
JavaScript
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.authorize = authorize;
const moment = require("moment");
const factory = require("../../../factory");
const MoneyTransferAssetTransactionService = require("../../assetTransaction/moneyTransfer");
const publishOrderNumberIfNotExist_1 = require("../../transaction/placeOrder/publishOrderNumberIfNotExist");
const any_1 = require("../any");
function authorize(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const transaction = yield repos.transaction.projectFieldsInProgressById({
typeOf: params.purpose.typeOf,
id: params.purpose.id
}, ['seller', 'project', 'agent', 'typeOf']);
if (transaction.agent.id !== params.agent.id) {
throw new factory.errors.Forbidden('Transaction not yours');
}
const now = new Date();
const orderNumber = yield (0, publishOrderNumberIfNotExist_1.publishOrderNumberIfNotExist)({
project: { id: params.project.id },
id: transaction.id,
object: { orderDate: now }
})(repos);
// まず取引番号発行
const { transactionNumber } = yield repos.transactionNumber.publishByTimestamp({ startDate: now });
let requestBody;
let responseBody;
let acceptedOffers4result = [];
// 承認アクションを開始
const actionAttributes = createAuthorizeMoneyTransferOfferActionattributes({
transaction,
object: params.object,
transactionNumber
});
const action = yield repos.action.start(actionAttributes);
// priceを確定する
let price = 0;
try {
const startDepositTransactionResult = yield processStartDepositTransaction({
project: params.project,
transaction: transaction,
object: params.object,
transactionNumber
})(repos);
requestBody = startDepositTransactionResult.requestBody;
responseBody = startDepositTransactionResult.responseBody;
// 通貨がJPYであればpriceに反映
if (responseBody.object.amount.currency === factory.priceCurrency.JPY) {
price = Number(responseBody.object.amount.value);
}
acceptedOffers4result = responseBody2resultAcceptedOffer({ responseBody, object: actionAttributes.object });
yield (0, any_1.acceptOffer)({
orderNumber,
project: transaction.project,
acceptedOffers: acceptedOffers4result
})(repos);
}
catch (error) {
try {
yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error });
}
catch (__) {
// 失敗したら仕方ない
}
throw error;
}
const result = {
price,
priceCurrency: factory.priceCurrency.JPY,
requestBody,
responseBody
// acceptedOffers: acceptedOffers4result // discontinue(2024-06-17~)
};
yield repos.action.completeWithVoid({ typeOf: action.typeOf, id: action.id, result: result });
return { id: action.id };
});
}
function responseBody2resultAcceptedOffer(params) {
var _a;
const acceptedOffers = [];
const { typeOf, transactionNumber } = params.responseBody;
const amountValue = params.responseBody.object.amount.value;
const currency = params.responseBody.object.amount.currency;
const itemOffered = {
typeOf: factory.actionType.MoneyTransfer,
amount: {
typeOf: 'MonetaryAmount',
value: amountValue,
currency
},
toLocation: {
typeOf: params.object.itemOffered.toLocation.typeOf,
// いったんマスク
identifier: 'xxx',
issuedThrough: { id: (_a = params.object.itemOffered.toLocation.issuedThrough) === null || _a === void 0 ? void 0 : _a.id }
},
object: {
// MonetaryAmountの識別子として、MoneyTransfer取引番号をセットする
pendingTransaction: { typeOf, transactionNumber }
},
name: `${amountValue} ${currency}`
};
acceptedOffers.push({
typeOf: factory.offerType.Offer,
itemOffered,
serialNumber: transactionNumber
});
return acceptedOffers;
}
function createAuthorizeMoneyTransferOfferActionattributes(params) {
var _a, _b;
const transaction = params.transaction;
const seller = transaction.seller;
return {
project: transaction.project,
typeOf: factory.actionType.AuthorizeAction,
instrument: {
typeOf: factory.assetTransactionType.MoneyTransfer,
transactionNumber: params.transactionNumber
},
object: {
project: { typeOf: transaction.project.typeOf, id: transaction.project.id },
typeOf: factory.offerType.Offer,
itemOffered: Object.assign(Object.assign({ typeOf: factory.actionType.MoneyTransfer, amount: params.object.itemOffered.amount, toLocation: params.object.itemOffered.toLocation, object: {
pendingTransaction: {
typeOf: factory.assetTransactionType.MoneyTransfer,
transactionNumber: params.transactionNumber
}
} }, (typeof params.object.itemOffered.description === 'string')
? { description: params.object.itemOffered.description }
: undefined), (typeof params.object.itemOffered.name === 'string')
? { name: params.object.itemOffered.name }
: undefined),
seller: {
// ...transaction.seller,
// project: transaction.project,
id: transaction.seller.id,
typeOf: transaction.seller.typeOf,
name: (typeof transaction.seller.name === 'string')
? transaction.seller.name
: String((_a = transaction.seller.name) === null || _a === void 0 ? void 0 : _a.ja)
},
priceCurrency: factory.priceCurrency.JPY
},
agent: {
id: seller.id,
typeOf: seller.typeOf,
name: (typeof seller.name === 'string')
? seller.name
: String((_b = seller.name) === null || _b === void 0 ? void 0 : _b.ja)
},
recipient: {
id: transaction.agent.id,
typeOf: transaction.agent.typeOf
},
purpose: { typeOf: transaction.typeOf, id: transaction.id }
};
}
function processStartDepositTransaction(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
let requestBody;
let responseBody;
try {
const description = `for ${params.transaction.typeOf} Transaction ${params.transaction.id}`;
// 最大1ヵ月のオーソリ
const expires = moment()
.add(1, 'month')
.toDate();
const toLocation = {
typeOf: factory.permit.PermitType.Permit,
identifier: params.object.itemOffered.toLocation.identifier,
issuedThrough: { id: (_a = params.object.itemOffered.toLocation.issuedThrough) === null || _a === void 0 ? void 0 : _a.id }
};
// 販売者が取引人に入金
requestBody = {
typeOf: factory.assetTransactionType.MoneyTransfer,
project: { typeOf: factory.organizationType.Project, id: params.project.id },
transactionNumber: params.transactionNumber,
agent: {
// project: params.transaction.project,
typeOf: params.transaction.seller.typeOf,
id: String(params.transaction.seller.id),
name: (typeof params.transaction.seller.name === 'string')
? params.transaction.seller.name
: String((_b = params.transaction.seller.name) === null || _b === void 0 ? void 0 : _b.ja)
},
object: {
amount: {
typeOf: 'MonetaryAmount',
value: Number(params.object.itemOffered.amount.value),
currency: ''
},
fromLocation: {
typeOf: params.transaction.agent.typeOf,
id: params.transaction.agent.id,
name: (typeof params.transaction.agent.name === 'string')
? params.transaction.agent.name
: `${params.transaction.typeOf} Transaction ${params.transaction.id}`
},
toLocation,
description: description,
pendingTransaction: {
typeOf: factory.account.transactionType.Deposit,
transactionNumber: params.transactionNumber
}
},
recipient: {
typeOf: params.transaction.agent.typeOf,
id: params.transaction.agent.id,
name: (typeof params.transaction.agent.name === 'string')
? params.transaction.agent.name
: `${params.transaction.typeOf} Transaction ${params.transaction.id}`
},
expires: expires
};
responseBody = yield MoneyTransferAssetTransactionService.start(requestBody)(repos);
}
catch (error) {
throw error;
}
return { requestBody, responseBody };
});
}
;