@chevre/domain
Version:
Chevre Domain Library for Node.js
389 lines (388 loc) • 21.3 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.validateAcceptedOffers = validateAcceptedOffers;
const factory = require("../../../../factory");
function createAppliesToMovieTicket(params) {
const isMvtkOrMG = typeof params.ticketInfo.mvtkNum === 'string' && params.ticketInfo.mvtkNum.length > 0;
let movieTicketTypeChargePriceSpec;
let appliesToMovieTicket;
if (isMvtkOrMG) {
// kbnMgtkから動的にavailablePaymentMethodを設定
let kbnMgtk = params.ticketInfo.kbnMgtk;
if (typeof kbnMgtk !== 'string') {
kbnMgtk = '';
}
const availablePaymentMethodType = params.availablePaymentMethodTypes.find((categoryCode) => { var _a, _b; return ((_b = (_a = categoryCode.additionalProperty) === null || _a === void 0 ? void 0 : _a.find((property) => property.name === 'kbnMgtk')) === null || _b === void 0 ? void 0 : _b.value) === kbnMgtk; });
if (availablePaymentMethodType === undefined) {
throw new factory.errors.Argument('offer', `available payment method type not found for kbnMgtk: ${kbnMgtk}`);
}
const availablePaymentMethod = availablePaymentMethodType.codeValue;
movieTicketTypeChargePriceSpec = {
typeOf: factory.priceSpecificationType.MovieTicketTypeChargeSpecification,
name: { ja: params.ticketInfo.ticketName, en: params.ticketInfo.ticketNameEng },
price: params.ticketInfo.addPrice,
priceCurrency: factory.priceCurrency.JPY,
valueAddedTaxIncluded: true,
appliesToMovieTicket: {
typeOf: factory.service.paymentService.PaymentServiceType.MovieTicket,
serviceType: params.ticketInfo.mvtkKbnKensyu,
serviceOutput: { typeOf: availablePaymentMethod }
},
appliesToVideoFormat: params.appliesToVideoFormat
};
appliesToMovieTicket = {
typeOf: factory.service.paymentService.PaymentServiceType.MovieTicket,
identifier: params.ticketInfo.mvtkNum,
serviceType: params.ticketInfo.mvtkKbnKensyu,
serviceOutput: { typeOf: availablePaymentMethod }
};
}
return { movieTicketTypeChargePriceSpec, appliesToMovieTicket };
}
// tslint:disable-next-line:cyclomatic-complexity max-func-body-length
function createPriceComponent(params) {
var _a, _b, _c, _d, _e, _f, _g, _h;
const acceptedOffer = params.acceptedOffer;
const availableUnitPriceOffer = params.availableUnitPriceOffer;
const kbnJoueihousiki = (_a = params.screeningEvent.superEvent.coaInfo) === null || _a === void 0 ? void 0 : _a.kbnJoueihousiki;
const appliesToVideoFormat = (typeof (kbnJoueihousiki === null || kbnJoueihousiki === void 0 ? void 0 : kbnJoueihousiki.kubunCode) === 'string')
? kbnJoueihousiki.kubunCode
: 'Default';
const { name, ticketInfo } = acceptedOffer;
// appliesToMovieTicket.serviceOutput.typeOfを自動補完(2023-03-13~)
const { appliesToMovieTicket, movieTicketTypeChargePriceSpec } = createAppliesToMovieTicket({
ticketInfo,
availablePaymentMethodTypes: params.availablePaymentMethodTypes,
appliesToVideoFormat
});
let surfrockChargePriceSpec;
let appliesToMovieTicket4surfrock;
// let eligibleMonetaryAmount: [factory.offer.IEligibleMonetaryAmount] | undefined;
// appliesToSurfrockの指定があれば強制的にMovieTicket決済
const appliesToSurfrockByUnitPriceOffer = (_b = availableUnitPriceOffer.priceSpecification.appliesToMovieTicket) === null || _b === void 0 ? void 0 : _b.at(0);
const surfrockIdentifier = (_d = (_c = acceptedOffer.priceSpecification) === null || _c === void 0 ? void 0 : _c.appliesToSurfrock) === null || _d === void 0 ? void 0 : _d.identifier;
const surfrockPaymentMethodType = (_g = (_f = (_e = acceptedOffer.priceSpecification) === null || _e === void 0 ? void 0 : _e.appliesToSurfrock) === null || _f === void 0 ? void 0 : _f.serviceOutput) === null || _g === void 0 ? void 0 : _g.typeOf;
if (typeof surfrockIdentifier === 'string' && surfrockIdentifier.length > 0
&& typeof surfrockPaymentMethodType === 'string' && surfrockPaymentMethodType.length > 0) {
const paymentMethodTypeByUnitPriceOffer = appliesToSurfrockByUnitPriceOffer === null || appliesToSurfrockByUnitPriceOffer === void 0 ? void 0 : appliesToSurfrockByUnitPriceOffer.serviceOutput.typeOf;
if (typeof paymentMethodTypeByUnitPriceOffer === 'string') {
if (paymentMethodTypeByUnitPriceOffer !== surfrockPaymentMethodType) {
throw new factory.errors.Argument(`priceSpecification.appliesToSurfrock.serviceOutput.typeOf must be ${paymentMethodTypeByUnitPriceOffer}`);
}
}
surfrockChargePriceSpec = {
appliesToMovieTicket: {
typeOf: factory.service.paymentService.PaymentServiceType.MovieTicket,
serviceOutput: { typeOf: surfrockPaymentMethodType },
serviceType: ticketInfo.ticketCode // serviceTypeはticketCode
},
appliesToVideoFormat,
name,
price: 0, // 加算料金は必ず0
priceCurrency: factory.priceCurrency.JPY,
typeOf: factory.priceSpecificationType.MovieTicketTypeChargeSpecification,
valueAddedTaxIncluded: true
};
appliesToMovieTicket4surfrock = {
typeOf: factory.service.paymentService.PaymentServiceType.MovieTicket,
identifier: surfrockIdentifier,
serviceOutput: { typeOf: surfrockPaymentMethodType },
serviceType: ticketInfo.ticketCode // serviceTypeはticketCode
};
}
else {
// discontinue eligibleMonetaryAmount(2025-01-03~)
// appliesToSurfrockの指定がなければ単価オファーの適用通貨条件を強制適用
// if (Array.isArray(availableUnitPriceOffer.eligibleMonetaryAmount)) {
// eligibleMonetaryAmount = availableUnitPriceOffer.eligibleMonetaryAmount;
// }
if (typeof (appliesToSurfrockByUnitPriceOffer === null || appliesToSurfrockByUnitPriceOffer === void 0 ? void 0 : appliesToSurfrockByUnitPriceOffer.serviceType) === 'string') {
throw new factory.errors.ArgumentNull('priceSpecification.appliesToSurfrock');
}
}
const { disPrice, limitCount, stdPrice } = ticketInfo;
if (typeof stdPrice !== 'number') {
throw new factory.errors.Argument('ticketInfo.stdPrice', 'must be number');
}
const accountsReceivable = (ticketInfo.mvtkAppPrice > 0) ? ticketInfo.mvtkAppPrice : stdPrice;
// const maxPrice: number = stdPrice;
let price = stdPrice;
// support disPrice(2024-09-02~)
if (typeof disPrice === 'number' && disPrice > 0) {
price -= disPrice;
}
let referenceQuantity = {
typeOf: 'QuantitativeValue',
unitCode: factory.unitCode.C62,
value: 1
};
switch (ticketInfo.limitUnit) {
case '001':
referenceQuantity = {
typeOf: 'QuantitativeValue',
unitCode: factory.unitCode.C62,
value: Number(limitCount)
};
price = Number(limitCount) * price;
break;
case '002':
referenceQuantity = {
typeOf: 'QuantitativeValue',
unitCode: factory.unitCode.C62,
value: 1,
minValue: Number(limitCount)
};
break;
default:
// no op
// referenceQuantity.value = 1;
}
const unitPriceSpec = Object.assign({ typeOf: factory.priceSpecificationType.UnitPriceSpecification, name: { ja: ticketInfo.ticketName, en: ticketInfo.ticketNameEng }, price, priceCurrency: factory.priceCurrency.JPY, referenceQuantity, valueAddedTaxIncluded: true, accounting: {
typeOf: 'Accounting',
accountsReceivable
} }, (appliesToMovieTicket !== undefined || appliesToMovieTicket4surfrock !== undefined)
? {
appliesToMovieTicket: [
...(appliesToMovieTicket !== undefined) ? [appliesToMovieTicket] : [],
...(appliesToMovieTicket4surfrock !== undefined) ? [appliesToMovieTicket4surfrock] : []
]
}
: undefined);
// 区分加算料金
const categoryCodeChargeSpecs = [];
// movieTicketTypeChargePriceSpecにaddPriceが含まれる場合は除く
if (movieTicketTypeChargePriceSpec === undefined) {
if (ticketInfo.addPrice > 0) {
const videoFormatTypeCharge = (typeof (kbnJoueihousiki === null || kbnJoueihousiki === void 0 ? void 0 : kbnJoueihousiki.kubunAddPrice) === 'number') ? kbnJoueihousiki.kubunAddPrice : 0;
const kbnAcoustic = (_h = params.screeningEvent.coaInfo) === null || _h === void 0 ? void 0 : _h.kbnAcoustic;
const soundFormatTypeCharge = (typeof (kbnAcoustic === null || kbnAcoustic === void 0 ? void 0 : kbnAcoustic.kubunAddPrice) === 'number') ? kbnAcoustic.kubunAddPrice : 0;
// 上映方式区分加算料金と音響区分加算料金を考慮する
if (videoFormatTypeCharge > 0) {
categoryCodeChargeSpecs.push({
name: {
en: (typeof (kbnJoueihousiki === null || kbnJoueihousiki === void 0 ? void 0 : kbnJoueihousiki.kubunNameEng) === 'string')
? kbnJoueihousiki.kubunNameEng
: String(kbnJoueihousiki === null || kbnJoueihousiki === void 0 ? void 0 : kbnJoueihousiki.kubunCode),
ja: (typeof (kbnJoueihousiki === null || kbnJoueihousiki === void 0 ? void 0 : kbnJoueihousiki.kubunName) === 'string')
? `${kbnJoueihousiki.kubunName}加算料金`
: '加算単価'
},
price: videoFormatTypeCharge,
priceCurrency: factory.priceCurrency.JPY,
typeOf: factory.priceSpecificationType.CategoryCodeChargeSpecification,
appliesToCategoryCode: [{
typeOf: 'CategoryCode',
codeValue: String(kbnJoueihousiki === null || kbnJoueihousiki === void 0 ? void 0 : kbnJoueihousiki.kubunCode),
inCodeSet: {
typeOf: 'CategoryCodeSet',
identifier: factory.categoryCode.CategorySetIdentifier.VideoFormatType
}
}],
valueAddedTaxIncluded: true
});
}
if (soundFormatTypeCharge > 0) {
categoryCodeChargeSpecs.push({
name: {
en: (typeof (kbnAcoustic === null || kbnAcoustic === void 0 ? void 0 : kbnAcoustic.kubunNameEng) === 'string')
? kbnAcoustic.kubunNameEng
: String(kbnAcoustic === null || kbnAcoustic === void 0 ? void 0 : kbnAcoustic.kubunCode),
ja: (typeof (kbnAcoustic === null || kbnAcoustic === void 0 ? void 0 : kbnAcoustic.kubunName) === 'string')
? `${kbnAcoustic.kubunName}加算料金`
: '加算単価'
},
price: soundFormatTypeCharge,
priceCurrency: factory.priceCurrency.JPY,
typeOf: factory.priceSpecificationType.CategoryCodeChargeSpecification,
appliesToCategoryCode: [{
typeOf: 'CategoryCode',
codeValue: String(kbnAcoustic === null || kbnAcoustic === void 0 ? void 0 : kbnAcoustic.kubunCode),
inCodeSet: {
typeOf: 'CategoryCodeSet',
identifier: factory.categoryCode.CategorySetIdentifier.SoundFormatType
}
}],
valueAddedTaxIncluded: true
});
}
}
}
if (ticketInfo.spseatAdd1 > 0) {
const existingSeatingType = params.seatingTypes.find((seatingType) => seatingType.codeValue === ticketInfo.spseatKbn);
categoryCodeChargeSpecs.push({
name: {
en: (typeof (existingSeatingType === null || existingSeatingType === void 0 ? void 0 : existingSeatingType.name.en) === 'string')
? `${existingSeatingType.name.en}`
: ticketInfo.spseatKbn,
ja: (typeof (existingSeatingType === null || existingSeatingType === void 0 ? void 0 : existingSeatingType.name.ja) === 'string')
? `${existingSeatingType.name.ja}加算料金`
: '特別席加算額'
},
price: ticketInfo.spseatAdd1,
priceCurrency: factory.priceCurrency.JPY,
typeOf: factory.priceSpecificationType.CategoryCodeChargeSpecification,
appliesToCategoryCode: [{
// project: { id: params.project.id, typeOf: factory.organizationType.Project },
typeOf: 'CategoryCode',
codeValue: ticketInfo.spseatKbn,
inCodeSet: {
typeOf: 'CategoryCodeSet',
identifier: factory.categoryCode.CategorySetIdentifier.SeatingType
}
}],
valueAddedTaxIncluded: true
});
}
// アドオン単価
const addOnUnitPriceSpecs = [];
if (ticketInfo.spseatAdd2 > 0) {
addOnUnitPriceSpecs.push({
typeOf: factory.priceSpecificationType.UnitPriceSpecification,
name: { ja: 'ミールクーポン', en: 'Meal Coupon' },
price: ticketInfo.spseatAdd2,
priceCurrency: factory.priceCurrency.JPY,
referenceQuantity: {
typeOf: 'QuantitativeValue',
unitCode: factory.unitCode.C62,
value: 1
},
valueAddedTaxIncluded: true,
appliesToAddOn: [{
typeOf: factory.offerType.Offer,
// id?: string;
// identifier?: string;
itemOffered: {
// id: '',
name: { ja: 'ミールクーポン', en: 'Meal Coupon' },
productID: '',
typeOf: factory.product.ProductType.Product
}
}]
});
}
if (ticketInfo.addGlasses > 0) {
addOnUnitPriceSpecs.push({
typeOf: factory.priceSpecificationType.UnitPriceSpecification,
name: { ja: 'メガネ', en: 'Glasses' },
price: Number(ticketInfo.addGlasses),
priceCurrency: factory.priceCurrency.JPY,
referenceQuantity: {
typeOf: 'QuantitativeValue',
unitCode: factory.unitCode.C62,
value: 1
},
valueAddedTaxIncluded: true,
appliesToAddOn: [{
typeOf: factory.offerType.Offer,
// id?: string;
// identifier?: string;
itemOffered: {
// id: '',
name: { ja: 'メガネ', en: 'Glasses' },
productID: '',
typeOf: factory.product.ProductType.Product
}
}]
});
}
const priceComponent = [
unitPriceSpec,
...(movieTicketTypeChargePriceSpec !== undefined) ? [movieTicketTypeChargePriceSpec] : [],
...(surfrockChargePriceSpec !== undefined) ? [surfrockChargePriceSpec] : [],
...categoryCodeChargeSpecs,
...addOnUnitPriceSpecs
];
return { priceComponent };
}
/**
* 受け入れらたオファーの内容を検証
*/
// tslint:disable-next-line:max-func-body-length
function validateAcceptedOffers(params) {
// tslint:disable-next-line:max-func-body-length
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a;
const theaterCode = String((_a = params.screeningEvent.coaInfo) === null || _a === void 0 ? void 0 : _a.theaterCode);
const offerIdentifiers = (Array.isArray(params.object.acceptedOffer))
? [...new Set((params.object.acceptedOffer).map((o) => {
return `COA-${theaterCode}-${String(o.ticketInfo.ticketCode)}`;
}))]
: [];
let availableUnitPriceOffers = [];
// 指定された単価オファーを検索
// ticketCodeで検索(2023-03-22~)
if (offerIdentifiers.length > 0) {
availableUnitPriceOffers = yield repos.offer.search({
identifier: { $in: offerIdentifiers },
project: { id: { $eq: params.project.id } }
});
}
const acceptedOffers = params.object.acceptedOffer.map((acceptedOffer) => {
var _a, _b;
const availableUnitPriceOffer = availableUnitPriceOffers.find((unitPriceOffer) => {
var _a, _b;
const ticketCodeByUnitPriceOffer = (_b = (_a = unitPriceOffer.additionalProperty) === null || _a === void 0 ? void 0 : _a.find((p) => p.name === 'ticketCode')) === null || _b === void 0 ? void 0 : _b.value;
return ticketCodeByUnitPriceOffer === acceptedOffer.ticketInfo.ticketCode;
});
if (availableUnitPriceOffer === undefined) {
throw new factory.errors.NotFound(factory.offerType.Offer, `${acceptedOffer.ticketInfo.ticketCode} not found`);
}
const { additionalProperty, itemOffered, name, ticketInfo } = acceptedOffer;
// priceComponentを再生成(2023-03-14~)
const { priceComponent } = createPriceComponent({
project: { id: params.project.id },
availablePaymentMethodTypes: params.availablePaymentMethodTypes,
seatingTypes: params.seatingTypes,
videoFormatTypes: params.videoFormatTypes,
acceptedOffer,
availableUnitPriceOffer,
screeningEvent: params.screeningEvent
});
const priceSpecification = {
typeOf: factory.priceSpecificationType.CompoundPriceSpecification,
priceCurrency: factory.priceCurrency.JPY,
priceComponent,
valueAddedTaxIncluded: true
};
// 実際の発生金額を算出
const price = [
ticketInfo.salesTicketSalePrice,
ticketInfo.addGlasses,
ticketInfo.spseatAdd1,
ticketInfo.spseatAdd2
].reduce((a, b) => a + b, 0);
// COAに渡す販売金額については、特別席加算額は興収部分のみ加算
const salePrice = [
ticketInfo.salesTicketSalePrice,
ticketInfo.addGlasses,
ticketInfo.spseatAdd1
].reduce((a, b) => a + b, 0);
const usePointValue = (_b = (_a = availableUnitPriceOffer.additionalProperty) === null || _a === void 0 ? void 0 : _a.find((p) => p.name === 'usePoint')) === null || _b === void 0 ? void 0 : _b.value;
return Object.assign({ additionalProperty,
itemOffered,
name,
price,
priceSpecification, ticketInfo: Object.assign(Object.assign({}, ticketInfo), {
// usePointを自動設定(2023-03-22~)
usePoint: (typeof usePointValue === 'string') ? Number(usePointValue) : 0, salePrice // COAに渡す販売金額を上書き(2023-03-20~)
}),
// 以下属性については単価オファーから読む(2023-03-09~)
priceCurrency: availableUnitPriceOffer.priceCurrency, id: availableUnitPriceOffer.id, identifier: availableUnitPriceOffer.identifier, typeOf: availableUnitPriceOffer.typeOf }, {
// discontinue(2025-01-03~)
// seatNumber: itemOffered.serviceOutput?.reservedTicket?.ticketedSeat?.seatNumber,
// discontinue(2025-01-03~)
// seatSection: itemOffered.serviceOutput?.reservedTicket?.ticketedSeat?.seatSection
});
});
return { acceptedOffers };
});
}