@chevre/domain
Version:
Chevre Domain Library for Node.js
297 lines (296 loc) • 17.5 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.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)
});
})));
});
}
;