UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

263 lines (262 loc) 13.9 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.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 }); } }); }