Source: service/reserve.js

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * 予約サービス
 */
const createDebug = require("debug");
const factory = require("../factory");
const debug = createDebug('chevre-domain:service');
/**
 * 予約を確定する
 */
function confirmReservation(actionAttributesList) {
    return (repos) => __awaiter(this, void 0, void 0, function* () {
        yield Promise.all(actionAttributesList.map((actionAttributes) => __awaiter(this, void 0, void 0, function* () {
            // アクション開始
            const action = yield repos.action.start(actionAttributes);
            try {
                // 予約を確定状態に変更する
                yield repos.reservation.confirm(actionAttributes.object);
            }
            catch (error) {
                // actionにエラー結果を追加
                try {
                    const actionError = Object.assign({}, error, { message: error.message, name: error.name });
                    yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error: actionError });
                }
                catch (__) {
                    // 失敗したら仕方ない
                }
                throw error;
            }
            // アクション完了
            const actionResult = {};
            yield repos.action.complete({ typeOf: action.typeOf, id: action.id, result: actionResult });
        })));
        const aggregateTask = {
            name: factory.taskName.AggregateScreeningEvent,
            status: factory.taskStatus.Ready,
            runsAt: new Date(),
            remainingNumberOfTries: 10,
            lastTriedAt: null,
            numberOfTried: 0,
            executionResults: [],
            data: actionAttributesList[0].object.reservationFor
        };
        yield repos.task.save(aggregateTask);
    });
}
exports.confirmReservation = confirmReservation;
/**
 * 進行中の予約をキャンセルする
 */
function cancelPendingReservation(actionAttributesList) {
    return (repos) => __awaiter(this, void 0, void 0, function* () {
        const reserveTransaction = yield repos.transaction.findById({
            typeOf: factory.transactionType.Reserve,
            id: actionAttributesList[0].purpose.id
        });
        debug('canceling reservations...', actionAttributesList);
        yield Promise.all(actionAttributesList.map((actionAttributes) => __awaiter(this, void 0, void 0, function* () {
            // アクション開始
            const action = yield repos.action.start(actionAttributes);
            try {
                // 予約をキャンセル状態に変更する
                const reservation = actionAttributes.object;
                yield repos.reservation.cancel({ id: reservation.id });
                // 予約取引がまだ座席を保持していれば座席ロック解除
                const lockKey = {
                    eventId: reservation.reservationFor.id,
                    offer: {
                        seatNumber: reservation.reservedTicket.ticketedSeat.seatNumber,
                        seatSection: reservation.reservedTicket.ticketedSeat.seatSection
                    }
                };
                const holder = yield repos.eventAvailability.getHolder(lockKey);
                if (holder === reserveTransaction.id) {
                    yield repos.eventAvailability.unlock(lockKey);
                }
            }
            catch (error) {
                // actionにエラー結果を追加
                try {
                    const actionError = Object.assign({}, error, { message: error.message, name: error.name });
                    yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error: actionError });
                }
                catch (__) {
                    // 失敗したら仕方ない
                }
                throw error;
            }
            // アクション完了
            const actionResult = {};
            yield repos.action.complete({ typeOf: action.typeOf, id: action.id, result: actionResult });
        })));
    });
}
exports.cancelPendingReservation = cancelPendingReservation;
/**
 * 予約をキャンセルする
 */
function cancelReservation(actionAttributesList) {
    return (repos) => __awaiter(this, void 0, void 0, function* () {
        const cancelReservationTransaction = yield repos.transaction.findById({ typeOf: factory.transactionType.CancelReservation, id: actionAttributesList[0].purpose.id });
        debug('canceling reservations...', actionAttributesList);
        yield Promise.all(actionAttributesList.map((actionAttributes) => __awaiter(this, void 0, void 0, function* () {
            // アクション開始
            const action = yield repos.action.start(actionAttributes);
            try {
                // 予約をキャンセル状態に変更する
                const reservation = actionAttributes.object;
                yield repos.reservation.cancel({ id: reservation.id });
                // 予約取引がまだ座席を保持していれば座席ロック解除
                const lockKey = {
                    eventId: reservation.reservationFor.id,
                    offer: {
                        seatNumber: reservation.reservedTicket.ticketedSeat.seatNumber,
                        seatSection: reservation.reservedTicket.ticketedSeat.seatSection
                    }
                };
                const holder = yield repos.eventAvailability.getHolder(lockKey);
                if (holder === cancelReservationTransaction.object.transaction.id) {
                    yield repos.eventAvailability.unlock(lockKey);
                }
            }
            catch (error) {
                // actionにエラー結果を追加
                try {
                    const actionError = Object.assign({}, error, { message: error.message, name: error.name });
                    yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error: actionError });
                }
                catch (__) {
                    // 失敗したら仕方ない
                }
                throw error;
            }
            // アクション完了
            const actionResult = {};
            yield repos.action.complete({ typeOf: action.typeOf, id: action.id, result: actionResult });
        })));
        const aggregateTask = {
            name: factory.taskName.AggregateScreeningEvent,
            status: factory.taskStatus.Ready,
            runsAt: new Date(),
            remainingNumberOfTries: 10,
            lastTriedAt: null,
            numberOfTried: 0,
            executionResults: [],
            data: actionAttributesList[0].object.reservationFor
        };
        yield repos.task.save(aggregateTask);
    });
}
exports.cancelReservation = cancelReservation;