@chevre/domain
Version:
Chevre Domain Library for Node.js
263 lines (262 loc) • 13.9 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.call = call;
exports.confirmReserveTransaction = confirmReserveTransaction;
const COA = require("@motionpicture/coa-service");
const google_libphonenumber_1 = require("google-libphonenumber");
const util_1 = require("util");
const factory = require("../../factory");
const confirm_1 = require("../assetTransaction/reserve/confirm");
const reserveCOA_1 = require("../assetTransaction/reserveCOA");
const factory_1 = require("../assetTransaction/reserveCOA/factory");
const acceptedOffer_1 = require("../../repo/acceptedOffer");
const action_1 = require("../../repo/action");
const assetTransaction_1 = require("../../repo/assetTransaction");
const authorization_1 = require("../../repo/authorization");
const order_1 = require("../../repo/order");
const reservation_1 = require("../../repo/reservation");
const reserveInterface_1 = require("../../repo/reserveInterface");
const setting_1 = require("../../repo/setting");
const task_1 = require("../../repo/task");
let coaAuthClientCreated = false;
let coaAuthClient = new COA.auth.RefreshToken({
endpoint: '', // 使用されないので空文字でok
refreshToken: '', // 使用されないので空文字でok
useFetch: true
});
/**
* タスク実行関数
*/
function call(params) {
return (_a) => __awaiter(this, [_a], void 0, function* ({ connection, settings }) {
var _b;
if (!coaAuthClientCreated) {
const reserveInterfaceRepo = new reserveInterface_1.ReserveInterfaceRepo(connection);
const coaAPI = yield reserveInterfaceRepo.findOne({ project: { id: { $eq: params.project.id } } });
const credentials = (_b = coaAPI === null || coaAPI === void 0 ? void 0 : coaAPI.availableChannel) === null || _b === void 0 ? void 0 : _b.credentials;
if (typeof (credentials === null || credentials === void 0 ? void 0 : credentials.refreshToken) === 'string') {
coaAuthClient = new COA.auth.RefreshToken(credentials);
coaAuthClientCreated = true;
}
}
const reserveService = new COA.service.Reserve({
endpoint: coaAuthClient.options.endpoint, // same as authClient(2024-07-17~)
auth: coaAuthClient
}, { timeout: settings.coa.timeout });
yield confirmReserveTransaction(Object.assign(Object.assign({}, params.data), { sameAs: { id: params.id } }), {
sendOrder: true,
useOnOrderStatusChanged: true
})({
acceptedOffer: new acceptedOffer_1.AcceptedOfferRepo(connection),
action: new action_1.ActionRepo(connection),
assetTransaction: new assetTransaction_1.AssetTransactionRepo(connection),
code: new authorization_1.AuthorizationRepo(connection),
order: new order_1.OrderRepo(connection),
reservation: new reservation_1.ReservationRepo(connection),
setting: new setting_1.SettingRepo(connection),
task: new task_1.TaskRepo(connection),
reserveService
}, settings);
});
}
function createConfirmObject4COAByOrder(params) {
// COA予約のみ
const coaReservationOffers = params.order.acceptedOffers.filter((o) => {
var _a;
return o.itemOffered.typeOf === factory.reservationType.EventReservation
&& ((_a = o.offeredThrough) === null || _a === void 0 ? void 0 : _a.identifier) === factory.service.webAPI.Identifier.COA;
});
const customer = params.order.customer;
// 電話番号のフォーマットを日本人にリーダブルに調整(COAではこのフォーマットで扱うので)
const phoneUtil = google_libphonenumber_1.PhoneNumberUtil.getInstance();
const phoneNumber = phoneUtil.parse(customer.telephone, 'JP');
let telNum = phoneUtil.format(phoneNumber, google_libphonenumber_1.PhoneNumberFormat.NATIONAL);
// COAでは数字のみ受け付けるので数字以外を除去
telNum = telNum.replace(/[^\d]/g, '');
const mailAddr = customer.email;
if (mailAddr === undefined) {
throw new factory.errors.Argument('order', 'order.customer.email undefined');
}
const coaReservations = coaReservationOffers
.filter((o) => o.itemOffered.reservationNumber === params.reservationNumber)
.map((o) => {
return o.itemOffered;
});
const coaReservation = coaReservations[0];
const reservationForCOAInfo = coaReservation.reservationFor.coaInfo;
if (reservationForCOAInfo === undefined) {
throw new factory.errors.NotFound('reservationFor.coaInfo');
}
const totalPrice = coaReservation.reservedTicket.coaReserveAmount;
if (totalPrice === undefined) {
throw new factory.errors.NotFound('reservedTicket.coaReserveAmount');
}
const listTicket = coaReservations.map((r) => {
var _a;
if (typeof ((_a = r.reservedTicket.coaTicketInfo) === null || _a === void 0 ? void 0 : _a.ticketCode) !== 'string') {
throw new factory.errors.NotFound('reservedTicket.coaTicketInfo');
}
// 冗長な属性を排除(2023-03-20~)
const { ticketCode, stdPrice, addPrice, spseatAdd1, spseatAdd2, disPrice, salePrice, mvtkAppPrice, ticketCount, spseatKbn, seatNum, addGlasses, kbnEisyahousiki, mvtkNum, mvtkKbnDenshiken, mvtkKbnMaeuriken, mvtkKbnKensyu, mvtkSalesPrice, kbnMgtk } = r.reservedTicket.coaTicketInfo;
return {
ticketCode, stdPrice, addPrice, spseatAdd1, spseatAdd2,
disPrice, salePrice, mvtkAppPrice, ticketCount, spseatKbn,
seatNum, addGlasses, kbnEisyahousiki, mvtkNum, mvtkKbnDenshiken,
mvtkKbnMaeuriken, mvtkKbnKensyu, mvtkSalesPrice, kbnMgtk
};
});
return {
theaterCode: reservationForCOAInfo.theaterCode,
dateJouei: reservationForCOAInfo.dateJouei,
titleCode: reservationForCOAInfo.titleCode,
titleBranchNum: reservationForCOAInfo.titleBranchNum,
timeBegin: reservationForCOAInfo.timeBegin,
tmpReserveNum: params.reservationNumber,
// tslint:disable-next-line:no-irregular-whitespace
reserveName: (0, util_1.format)('%s %s', customer.familyName, customer.givenName),
// tslint:disable-next-line:no-irregular-whitespace
reserveNameJkana: (0, util_1.format)('%s %s', customer.familyName, customer.givenName),
telNum: telNum,
mailAddr: mailAddr,
reserveAmount: totalPrice, // デフォルトのpriceCurrencyがJPYなのでこれでよし
listTicket
};
}
function fixOrderAsPurpose(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
let order;
const purposeOrderNumber = params.purpose.orderNumber;
const orders = yield repos.order.projectFields({
limit: 1,
page: 1,
project: { id: { $eq: params.project.id } },
orderNumbers: [purposeOrderNumber]
}, { inclusion: ['customer', 'orderNumber', 'typeOf'] });
order = orders.shift();
if (order === undefined) {
throw new factory.errors.NotFound('Order as purpose');
}
const acceptedOffers = yield repos.acceptedOffer.searchAcceptedOffersByOrderNumber({
orderNumber: { $eq: order.orderNumber },
project: { id: { $eq: params.project.id } }
}, ['itemOffered', 'offeredThrough']);
return Object.assign(Object.assign({}, order), { acceptedOffers });
});
}
/**
* 予約を確定する
*/
// tslint:disable-next-line:max-func-body-length
function confirmReserveTransaction(params, options) {
return (repos, settings) => __awaiter(this, void 0, void 0, function* () {
let confirmActionObject;
// let updReserveResult: COA.factory.reserve.IUpdReserveResult | undefined;
let recipe;
switch (params.object.typeOf) {
case factory.assetTransactionType.COAReserveTransaction:
// 最適化されたタスクに対応するため、ここでIObject4COAを注文から生成する(2024-01-24~)
const order = yield fixOrderAsPurpose({
project: { id: params.project.id },
purpose: params.purpose
})(repos);
const updReserveArgs = createConfirmObject4COAByOrder({ order, reservationNumber: params.object.transactionNumber });
const object4coa = Object.assign(Object.assign({}, updReserveArgs), { transactionNumber: params.object.transactionNumber, typeOf: factory.assetTransactionType.COAReserveTransaction });
confirmActionObject = object4coa;
recipe = (0, factory_1.processConfirmCOAReserveResult2recipe)({
processConfirmCOAReserveResult: { updReserveArgs: object4coa },
project: { id: params.project.id }
});
break;
default:
confirmActionObject = params.object;
}
const { agent, project, purpose, typeOf, sameAs } = params;
const confirmActionAttributes = Object.assign({ agent, project, purpose, typeOf, object: confirmActionObject }, (typeof (sameAs === null || sameAs === void 0 ? void 0 : sameAs.id) === 'string') ? { sameAs: { id: sameAs.id, typeOf: 'Task' } } : undefined // link sameAs(2024-06-10~)
);
const action = yield repos.action.start(confirmActionAttributes, Object.assign({}, (recipe !== undefined) ? { recipe } : undefined // add recipe(2024-06-11~)
));
try {
const object = confirmActionAttributes.object;
switch (object.typeOf) {
case factory.assetTransactionType.COAReserveTransaction:
// COA本予約
const processConfirmCOAReserveResult = yield (0, reserveCOA_1.confirm)({
project: { id: confirmActionAttributes.project.id },
object: object,
purpose: confirmActionAttributes.purpose
})({ reserveService: repos.reserveService });
// updReserveResult = processConfirmCOAReserveResult.updReserveResult;
recipe = (0, factory_1.processConfirmCOAReserveResult2recipe)({
processConfirmCOAReserveResult,
project: { id: confirmActionAttributes.project.id }
});
break;
default:
// 予約取引確定
yield (0, confirm_1.confirm)({
transactionNumber: object.transactionNumber,
potentialActions: object.potentialActions
})(repos, settings);
}
}
catch (error) {
try {
yield repos.action.giveUp({ typeOf: confirmActionAttributes.typeOf, id: action.id, error });
}
catch (__) {
// 失敗したら仕方ない
}
throw error;
}
const result = {
// ...(updReserveResult !== undefined) ? { updReserveResult } : {} // discontinue(2024-06-11~)
};
yield repos.action.completeWithVoid(Object.assign({ typeOf: confirmActionAttributes.typeOf, id: action.id, result }, (recipe !== undefined) ? { recipe } : undefined // add recipe(2024-06-11~)
));
// sendOrder連携(2024-01-11~)
yield onConfirmed(confirmActionAttributes, options)({
task: repos.task
});
});
}
function onConfirmed(params, options) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
if (options.sendOrder === true) {
// タスク冪等作成
const onAssetTransactionStatusChangedTaskData = {
project: { id: params.project.id, typeOf: factory.organizationType.Project },
object: {
typeOf: params.object.typeOf,
transactionNumber: params.object.transactionNumber,
status: factory.transactionStatusType.Confirmed
},
purpose: {
confirmationNumber: '', // OnAssetTransactionStatusChanged処理内で使用されないので空文字でok
orderNumber: params.purpose.orderNumber,
typeOf: factory.order.OrderType.Order
},
useOnOrderStatusChanged: options.useOnOrderStatusChanged === true
};
const onAssetTransactionStatusChangedTask = {
project: { id: params.project.id, typeOf: factory.organizationType.Project },
name: factory.taskName.OnAssetTransactionStatusChanged,
status: factory.taskStatus.Ready,
runsAt: new Date(),
remainingNumberOfTries: 10,
numberOfTried: 0,
executionResults: [],
data: onAssetTransactionStatusChangedTaskData
};
yield repos.task.createOnAssetTransactionStatusChangedTaskIfNotExist(onAssetTransactionStatusChangedTask, { emitImmediately: true });
}
});
}