UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

297 lines (296 loc) 17.5 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.createAcceptedOffersWithoutDetails = createAcceptedOffersWithoutDetails; exports.validateOffers = validateOffers; const COA = require("@motionpicture/coa-service"); const http_status_1 = require("http-status"); const errorHandler_1 = require("../../../../errorHandler"); const factory = require("../../../../factory"); function createAcceptedOffersWithoutDetails(params) { return (repos) => __awaiter(this, void 0, void 0, function* () { const { listSeat } = yield repos.reserveService.stateReserveSeat(params.coaInfo); // 供給情報の有効性を確認 return params.object.acceptedOffer.map((offer) => { const section = listSeat.find((s) => s.seatSection === offer.seatSection); const freeSeat = section === null || section === void 0 ? void 0 : section.listFreeSeat.find((s) => s.seatNum === offer.seatNumber); if (freeSeat === undefined) { throw new factory.errors.AlreadyInUse('offer', ['seatNumber'], 'Seat not available'); } const spseatAdd1 = (typeof freeSeat.spseatAdd1 === 'number') ? freeSeat.spseatAdd1 : 0; const spseatAdd2 = (typeof freeSeat.spseatAdd2 === 'number') ? freeSeat.spseatAdd2 : 0; const spseatKbn = (typeof freeSeat.spseatKbn === 'string') ? freeSeat.spseatKbn : ''; return Object.assign(Object.assign({}, offer), { ticketInfo: Object.assign(Object.assign({}, offer.ticketInfo), { spseatAdd1, spseatAdd2, spseatKbn }) }); }); }); } /** * 受入オファーをCOA販売チケットへ変換する */ function offer2availableSalesTicket(params) { // tslint:disable-next-line:cyclomatic-complexity max-func-body-length return (repos) => __awaiter(this, void 0, void 0, function* () { let availableSalesTicket; const offers = params.offers; const offer = params.offer; const offerIndex = params.offerIndex; const availableSalesTickets = params.availableSalesTickets; const coaInfo = params.coaInfo; const isMvtkOrMG = typeof offer.ticketInfo.mvtkNum === 'string' && offer.ticketInfo.mvtkNum.length > 0; const couponCode = offer.ticketInfo.couponCode; // 2024-08-27~ // ポイント消費鑑賞券の場合 if (typeof offer.ticketInfo.usePoint === 'number' && offer.ticketInfo.usePoint > 0) { // COA側のマスタ構成で、 // 券種マスタに消費ポイント、販売可能チケット情報に販売金額 を持っている availableSalesTicket = availableSalesTickets.find((t) => t.ticketCode === offer.ticketInfo.ticketCode); // 利用可能な券種が見つからなければエラー if (availableSalesTicket === undefined) { throw new factory.errors.NotFound(`offers.${offerIndex}`, `ticketCode ${offer.ticketInfo.ticketCode} not found.`); } } else if (isMvtkOrMG) { // MovieTicket情報をCOA券種に変換 try { const kbnMgtk = offer.ticketInfo.kbnMgtk; if (typeof kbnMgtk === 'string' && kbnMgtk === 'MG') { const mgtkTicketcodeResult = yield repos.masterService.mgtkTicketcode({ theaterCode: coaInfo.theaterCode, mgtkTicketcode: offer.ticketInfo.mvtkKbnKensyu, // MG券種区分 titleCode: coaInfo.titleCode, titleBranchNum: coaInfo.titleBranchNum, dateJouei: coaInfo.dateJouei }); availableSalesTicket = Object.assign(Object.assign({}, mgtkTicketcodeResult), { // IFが少なめなので補ってあげる stdPrice: 0, salePrice: mgtkTicketcodeResult.addPrice, addGlasses: mgtkTicketcodeResult.addPriceGlasses }); } else { const mvtkTicketcodeResult = yield repos.masterService.mvtkTicketcode({ theaterCode: coaInfo.theaterCode, kbnDenshiken: offer.ticketInfo.mvtkKbnDenshiken, kbnMaeuriken: offer.ticketInfo.mvtkKbnMaeuriken, kbnKensyu: offer.ticketInfo.mvtkKbnKensyu, salesPrice: offer.ticketInfo.mvtkSalesPrice, appPrice: offer.ticketInfo.mvtkAppPrice, kbnEisyahousiki: offer.ticketInfo.kbnEisyahousiki, titleCode: coaInfo.titleCode, titleBranchNum: coaInfo.titleBranchNum, dateJouei: coaInfo.dateJouei }); availableSalesTicket = Object.assign(Object.assign({}, mvtkTicketcodeResult), { // IFが少なめなので補ってあげる stdPrice: 0, salePrice: mvtkTicketcodeResult.addPrice, addGlasses: mvtkTicketcodeResult.addPriceGlasses }); } } catch (error) { // COAサービスエラーの場合ハンドリング if (error.name === 'COAServiceError') { // COAはクライアントエラーかサーバーエラーかに関わらずステータスコード200 or 500を返却する。 // 500未満であればクライアントエラーとみなす if (typeof error.code === 'number' && error.code < http_status_1.INTERNAL_SERVER_ERROR) { throw new factory.errors.NotFound(`offers.${offerIndex}`, `ticketCode ${offer.ticketInfo.ticketCode} not found. ${error.message}`); } } throw error; } // COA券種が見つかっても、指定された券種コードと異なればエラー if (offer.ticketInfo.ticketCode !== availableSalesTicket.ticketCode) { throw new factory.errors.NotFound(`offers.${offerIndex}`, `ticketInfo of ticketCode ${offer.ticketInfo.ticketCode} is invalid.`); } } else { if (typeof couponCode === 'string') { // クーポンコード指定の場合クーポンチケット検索結果から販売チケットをfix(2024-08-27~) try { const couponTicketResult = yield repos.reserveService.couponTicket({ theaterCode: coaInfo.theaterCode, couponCode, titleCode: coaInfo.titleCode, titleBranchNum: coaInfo.titleBranchNum, dateJouei: coaInfo.dateJouei, timeBegin: coaInfo.timeBegin, flgMember: (params.isMember) ? COA.factory.reserve.FlgMember.Member : COA.factory.reserve.FlgMember.NonMember }); availableSalesTicket = couponTicketResult.listTicket.find((t) => t.ticketCode === offer.ticketInfo.ticketCode); } catch (error) { // COAサービスエラーの場合ハンドリング if (error.name === 'COAServiceError') { // COAはクライアントエラーかサーバーエラーかに関わらずステータスコード200 or 500を返却する。 // 500未満であればクライアントエラーとみなす if (typeof error.code === 'number' && error.code < http_status_1.INTERNAL_SERVER_ERROR) { throw new factory.errors.NotFound(`offers.${offerIndex}`, `couponTicket ${offer.ticketInfo.ticketCode} not found. ${error.message}`); } } throw error; } } else { availableSalesTicket = availableSalesTickets.find((t) => t.ticketCode === offer.ticketInfo.ticketCode); } // 利用可能な券種が見つからなければエラー if (availableSalesTicket === undefined) { throw new factory.errors.NotFound(`offers.${offerIndex}`, `ticketCode ${offer.ticketInfo.ticketCode} not found.`); } const ticketCode = availableSalesTicket.ticketCode; // 制限単位がn人単位(例えば夫婦割り)の場合、同一券種の数を確認 // '001'の値は、区分マスター取得APIにて、"kubunCode": "011"を指定すると取得できる if (availableSalesTicket.limitUnit === '001') { const numberOfSameOffer = offers.filter((o) => o.ticketInfo.ticketCode === ticketCode).length; if (numberOfSameOffer % availableSalesTicket.limitCount !== 0) { // 割引条件が満たされていません // 選択した券種の中に、割引券が含まれています。 // 割引券の適用条件を再度ご確認ください。 const invalidOfferIndexes = offers.reduce((a, b, index) => (b.ticketInfo.ticketCode === ticketCode) ? [...a, ...[index]] : a, []); throw invalidOfferIndexes.map((index) => new factory.errors.Argument(`offers.${index}`, '割引条件が満たされていません。')); } } } return { availableSalesTicket }; }); } // tslint:disable-next-line:cyclomatic-complexity max-func-body-length function availableSalesTicket2offerWithDetails(params) { var _a, _b, _c, _d, _e, _f, _g, _h; let offerWithDetails; const availableSalesTicket = params.availableSalesTicket; const offer = params.offer; const includeGlasses = (offer.ticketInfo.addGlasses > 0); const isMvtkOrMG = typeof offer.ticketInfo.mvtkNum === 'string' && offer.ticketInfo.mvtkNum.length > 0; let appliesToSurfrock; // 会員であればappliesToSurfrockを強制適用 if (params.isMember) { appliesToSurfrock = params.appliesToSurfrock; // オファーごとに指定可能化(2023-08-02~) if (typeof ((_b = (_a = offer.priceSpecification) === null || _a === void 0 ? void 0 : _a.appliesToSurfrock) === null || _b === void 0 ? void 0 : _b.identifier) === 'string' && typeof ((_d = (_c = offer.priceSpecification) === null || _c === void 0 ? void 0 : _c.appliesToSurfrock.serviceOutput) === null || _d === void 0 ? void 0 : _d.typeOf) === 'string') { appliesToSurfrock = { identifier: offer.priceSpecification.appliesToSurfrock.identifier, serviceOutput: { typeOf: offer.priceSpecification.appliesToSurfrock.serviceOutput.typeOf } }; } } const priceSpecification = Object.assign({}, (typeof (appliesToSurfrock === null || appliesToSurfrock === void 0 ? void 0 : appliesToSurfrock.identifier) === 'string') ? { appliesToSurfrock } : undefined); const disPrice = (typeof availableSalesTicket.disPrice === 'number' && availableSalesTicket.disPrice > 0) ? availableSalesTicket.disPrice : 0; // support case of coupon(2024-08-31~) const ticketInfo = { ticketCode: availableSalesTicket.ticketCode, ticketName: availableSalesTicket.ticketName, ticketNameEng: availableSalesTicket.ticketNameEng, ticketNameKana: availableSalesTicket.ticketNameKana, stdPrice: availableSalesTicket.stdPrice, addPrice: availableSalesTicket.addPrice, disPrice, // salePrice: salePrice, salesTicketSalePrice: Number(availableSalesTicket.salePrice), spseatAdd1: offer.ticketInfo.spseatAdd1, spseatAdd2: offer.ticketInfo.spseatAdd2, spseatKbn: offer.ticketInfo.spseatKbn, addGlasses: (includeGlasses) ? availableSalesTicket.addGlasses : 0, ticketCount: 1, seatNum: offer.seatNumber, // usePoint: (coaPointTicket !== undefined) ? coaPointTicket.usePoint : 0, mvtkAppPrice: (isMvtkOrMG) ? offer.ticketInfo.mvtkAppPrice : 0, kbnEisyahousiki: (isMvtkOrMG) ? offer.ticketInfo.kbnEisyahousiki : '00', mvtkNum: (isMvtkOrMG) ? offer.ticketInfo.mvtkNum : '', mvtkKbnDenshiken: (isMvtkOrMG) ? offer.ticketInfo.mvtkKbnDenshiken : '00', mvtkKbnMaeuriken: (isMvtkOrMG) ? offer.ticketInfo.mvtkKbnMaeuriken : '00', mvtkKbnKensyu: (isMvtkOrMG) ? offer.ticketInfo.mvtkKbnKensyu : '00', mvtkSalesPrice: (isMvtkOrMG) ? offer.ticketInfo.mvtkSalesPrice : 0, kbnMgtk: (typeof offer.ticketInfo.kbnMgtk === 'string') ? offer.ticketInfo.kbnMgtk : '', limitUnit: (typeof availableSalesTicket.limitUnit === 'string') ? availableSalesTicket.limitUnit : '', limitCount: (typeof availableSalesTicket.limitCount === 'number') ? availableSalesTicket.limitCount : 1 }; offerWithDetails = { // ticketCodeで照合するためidは不要(2023-03-22~) // id: params.offerId, // identifierはchevre/apiで自動補完(2023-03-10~) // identifier: params.offerIdentifier, name: { ja: availableSalesTicket.ticketName, en: availableSalesTicket.ticketNameEng }, priceSpecification, ticketInfo, itemOffered: { serviceOutput: Object.assign(Object.assign({ typeOf: factory.reservationType.EventReservation, reservedTicket: { typeOf: 'Ticket', ticketedSeat: { seatSection: offer.seatSection, seatNumber: offer.seatNumber, seatRow: '', typeOf: factory.placeType.Seat } } }, (typeof ((_f = (_e = offer.itemOffered) === null || _e === void 0 ? void 0 : _e.serviceOutput) === null || _f === void 0 ? void 0 : _f.additionalTicketText) === 'string') ? { additionalTicketText: offer.itemOffered.serviceOutput.additionalTicketText } : undefined), (Array.isArray((_h = (_g = offer.itemOffered) === null || _g === void 0 ? void 0 : _g.serviceOutput) === null || _h === void 0 ? void 0 : _h.additionalProperty)) ? { additionalProperty: offer.itemOffered.serviceOutput.additionalProperty } : undefined) }, additionalProperty: (Array.isArray(offer.additionalProperty)) ? offer.additionalProperty : [] }; // メガネ代込み要求の場合、チケット名調整特別対応 if (includeGlasses) { offerWithDetails.ticketInfo.ticketName = `${availableSalesTicket.ticketName}メガネ込み`; } return offerWithDetails; } function validateOffers(coaInfo, offers, appliesToSurfrock, // isMember: boolean, // flgMemberと重複なので不要(2024-05-27~) flgMember) { return (repos) => __awaiter(this, void 0, void 0, function* () { let availableSalesTickets = []; try { // 会員の場合、非会員の検索は不要(2023-03-10~) availableSalesTickets = yield repos.reserveService.salesTicket({ theaterCode: coaInfo.theaterCode, dateJouei: coaInfo.dateJouei, titleCode: coaInfo.titleCode, titleBranchNum: coaInfo.titleBranchNum, timeBegin: coaInfo.timeBegin, flgMember: flgMember }); } catch (error) { throw (0, errorHandler_1.handleCOAReserveTemporarilyError)(error); } // 利用可能でないチケットコードがオファーに含まれていれば引数エラー // オファーごとに確認 return Promise.all(offers.map((offer, offerIndex) => __awaiter(this, void 0, void 0, function* () { const { availableSalesTicket } = yield offer2availableSalesTicket({ offers: offers, offer: offer, offerIndex: offerIndex, availableSalesTickets: availableSalesTickets, coaInfo: coaInfo, isMember: (flgMember === COA.factory.reserve.FlgMember.Member) })({ masterService: repos.masterService, reserveService: repos.reserveService }); return availableSalesTicket2offerWithDetails({ availableSalesTicket, offer, offerIndex, appliesToSurfrock, isMember: (flgMember === COA.factory.reserve.FlgMember.Member) }); }))); }); }