@chevre/domain
Version:
Chevre Domain Library for Node.js
904 lines (903 loc) • 44 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.importFromCOA = importFromCOA;
exports.minimizeSuperEvent = minimizeSuperEvent;
exports.createScreeningEventIdFromCOA = createScreeningEventIdFromCOA;
exports.updateEvent4ttts = updateEvent4ttts;
const createDebug = require("debug");
// @ts-ignore
const difference = require("lodash.difference");
// import { google } from 'googleapis';
const moment = require("moment-timezone");
const factory = require("../factory");
// import { Settings } from '../settings';
const onEventChanged_1 = require("./offer/onEventChanged");
const debug = createDebug('chevre-domain:service:event');
/**
* イベントをインポートする
*/
function importFromCOA(params) {
// tslint:disable-next-line:max-func-body-length
return (repos) => __awaiter(this, void 0, void 0, function* () {
// 施設更新アクションを分離(2024-04-26~)
const { seller, movieTheater, screeningRooms } = yield processUpdateMovieTheater(params)(repos);
// const targetImportFrom = moment(`${moment(params.importFrom)
// .tz('Asia/Tokyo')
// .format('YYYY-MM-DD')}T00:00:00+09:00`);
// const targetImportThrough = moment(`${moment(params.importThrough)
// .tz('Asia/Tokyo')
// .format('YYYY-MM-DD')}T00:00:00+09:00`)
// .add(1, 'day');
const targetImportFrom = moment(params.importFrom)
.tz('Asia/Tokyo')
.startOf('day');
const targetImportThrough = moment(params.importThrough)
.tz('Asia/Tokyo')
.endOf('day');
const begin = moment(targetImportFrom)
.add(-1, 'day') // 深夜帯スケジュールが前日検索の結果に含まれるため
.tz('Asia/Tokyo')
.format('YYYYMMDD'); // COAは日本時間で判断
const end = moment(targetImportThrough)
// .add(-1, 'day')
.tz('Asia/Tokyo')
.format('YYYYMMDD'); // COAは日本時間で判断
debug('importing screening events...', targetImportFrom, targetImportThrough, begin, end);
const instrument = {
theaterCode: params.locationBranchCode, // debug(2024-04-26~)
begin, // debug(2024-04-24~)
end, // debug(2024-04-24~)
typeOf: 'WebAPI',
identifier: factory.service.webAPI.Identifier.COA
};
const actionAttributes = {
project: { typeOf: factory.organizationType.Project, id: params.project.id },
// typeOf: factory.actionType.UpdateAction,
typeOf: factory.actionType.ReplaceAction, // Replaceに変更(2024-04-26~)
agent: { typeOf: factory.organizationType.Project, id: params.project.id },
object: Object.assign(Object.assign({}, params), { startDate: `${moment(targetImportFrom) // debug(2024-04-26~)
.toISOString()}/${moment(targetImportThrough)
.toISOString()}`, superEvent: { location: { branchCode: params.locationBranchCode } }, typeOf: factory.eventType.ScreeningEvent }),
instrument
};
const action = yield repos.action.start(actionAttributes);
let savedScreeningEventsCount = 0;
let savedScreeningEventSeriesCount = 0;
let cancelledIds = [];
let processTime;
try {
let screeningEventSerieses;
if (params.saveScreeningEventSeries === true) {
const saveScreeningEventSeriesResult = yield saveScreeningEventSeries({
locationBranchCode: params.locationBranchCode,
movieTheater,
project: params.project,
saveScreeningEventSeries: params.saveScreeningEventSeries,
saveScreeningEventSeriesPeriodInMonth: params.saveScreeningEventSeriesPeriodInMonth,
seller: { id: seller.id }
})(repos);
screeningEventSerieses = saveScreeningEventSeriesResult.screeningEventSerieses;
savedScreeningEventSeriesCount = saveScreeningEventSeriesResult.savedEventsCount;
}
else {
// 施設コンテンツを保管しない場合、DBから施設コンテンツを検索するので、ここでは何もしない(2024-09-09~)
}
try {
// イベント永続化
const processStart = process.hrtime.bigint();
const screeningEvents = yield saveScreeningEvents(Object.assign({ movieTheater,
screeningRooms, project: params.project, targetImportFrom: targetImportFrom.toDate(), targetImportThrough: targetImportThrough.toDate(), seller: { id: seller.id }, instrument }, (Array.isArray(screeningEventSerieses)) ? { screeningEventSerieses } : undefined))(repos);
savedScreeningEventsCount = screeningEvents.length;
// COAから削除されたイベントをキャンセル済ステータスへ変更
cancelledIds = yield cancelDeletedEvents({
project: params.project,
locationBranchCode: params.locationBranchCode,
targetImportFrom: targetImportFrom.toDate(),
targetImportThrough: targetImportThrough.toDate(),
idsShouldBe: screeningEvents.map((e) => e.id)
})(repos);
const processEnd = process.hrtime.bigint();
processTime = processEnd - processStart;
}
catch (error) {
let throwsError = true;
if (error.name === 'AbortError') {
// tslint:disable-next-line:no-console
console.error('saveScreeningEvents throwed an error', error.name, error.message);
throwsError = false;
}
if (error.name === 'COAServiceError') {
if (error.message === 'ESOCKETTIMEDOUT') {
// tslint:disable-next-line:no-console
console.error('saveScreeningEvents throwed an error', error.name, error.message);
throwsError = false;
}
}
if (throwsError) {
throw error;
}
}
}
catch (error) {
try {
yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error });
}
catch (__) {
// 失敗したら仕方ない
}
throw error;
}
const actionResult = Object.assign({ cancelledIds, // キャンセルイベント保管(2024-04-26~)
savedScreeningEventsCount,
savedScreeningEventSeriesCount }, (processTime !== undefined) ? { processTime } : undefined);
yield repos.action.completeWithVoid({ typeOf: action.typeOf, id: action.id, result: actionResult });
});
}
// tslint:disable-next-line:max-func-body-length
function processUpdateMovieTheater(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const actionAttributes = {
project: { typeOf: factory.organizationType.Project, id: params.project.id },
typeOf: factory.actionType.ReplaceAction,
agent: { typeOf: factory.organizationType.Project, id: params.project.id },
object: Object.assign(Object.assign({}, params), { branchCode: params.locationBranchCode, typeOf: factory.placeType.MovieTheater }),
instrument: {
theaterCode: params.locationBranchCode,
typeOf: 'WebAPI',
identifier: factory.service.webAPI.Identifier.COA
}
};
const action = yield repos.action.start(actionAttributes);
let seller;
let movieTheater;
let screeningRooms;
let processTime;
try {
// 同ブランチコードの販売者を検索する
const sellersWithSameBranchCode = yield repos.seller.projectFields({
limit: 1,
page: 1,
project: { id: { $eq: params.project.id } },
branchCode: { $eq: params.locationBranchCode }
}, ['id']);
const sellerWithSameBranchCode = sellersWithSameBranchCode.shift();
if (typeof (sellerWithSameBranchCode === null || sellerWithSameBranchCode === void 0 ? void 0 : sellerWithSameBranchCode.id) !== 'string') {
throw new factory.errors.NotFound('Seller', `Seller with branchCode '${params.locationBranchCode}' not found`);
}
seller = { id: sellerWithSameBranchCode.id };
// saveMovieTheater:trueの場合のみ、施設保管(2022-10-10~)
if (params.saveMovieTheater === true) {
const processStart = process.hrtime.bigint();
const savingMovieTheater = createMovieTheaterFromCOA(params.project, { id: seller.id }, yield repos.masterService.theater({ theaterCode: params.locationBranchCode }), yield repos.masterService.screen({ theaterCode: params.locationBranchCode }));
yield repos.movieTheater.saveMovieTheaterByBranchCode4coa(savingMovieTheater);
yield repos.screeningRoom.saveScreeningRooms4coa(savingMovieTheater);
const processEnd = process.hrtime.bigint();
processTime = processEnd - processStart;
}
const movieTheaters = yield repos.movieTheater.projectFields({
limit: 1,
page: 1,
project: { id: { $eq: params.project.id } },
branchCode: { $eq: params.locationBranchCode }
}, ['id', 'typeOf', 'branchCode', 'name', 'kanaName']
// []
);
movieTheater = movieTheaters.shift();
if (movieTheater === undefined) {
throw new factory.errors.NotFound(factory.placeType.MovieTheater);
}
screeningRooms = yield repos.screeningRoom.searchScreeningRooms({
project: { id: { $eq: params.project.id } },
containedInPlace: { branchCode: { $eq: movieTheater.branchCode } }
});
}
catch (error) {
try {
yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error });
}
catch (__) {
// 失敗したら仕方ない
}
throw error;
}
const actionResult = Object.assign({ screeningRoomsCount: screeningRooms.length }, (processTime !== undefined) ? { processTime } : undefined);
yield repos.action.completeWithVoid({ typeOf: action.typeOf, id: action.id, result: actionResult });
return { seller, movieTheater, screeningRooms };
});
}
function saveScreeningEventSeries(params) {
// tslint:disable-next-line:max-func-body-length
return (repos) => __awaiter(this, void 0, void 0, function* () {
const { importingIds } = params;
const project = params.project;
// COAから作品取得
const filmsFromCOA = yield repos.masterService.title({
theaterCode: params.locationBranchCode
});
// COAから区分マスター抽出
const eirinKubuns = yield repos.masterService.kubunName({
theaterCode: params.locationBranchCode,
kubunClass: '044'
});
const eizouKubuns = yield repos.masterService.kubunName({
theaterCode: params.locationBranchCode,
kubunClass: '042'
});
const joueihousikiKubuns = yield repos.masterService.kubunName({
theaterCode: params.locationBranchCode,
kubunClass: '045'
});
const jimakufukikaeKubuns = yield repos.masterService.kubunName({
theaterCode: params.locationBranchCode,
kubunClass: '043'
});
debug('kubunNames found.');
const availablePaymentMethodTypes = yield repos.categoryCode.projectFields({
project: { id: { $eq: params.project.id } },
inCodeSet: { identifier: { $eq: factory.categoryCode.CategorySetIdentifier.PaymentMethodType } }
}, ['additionalProperty', 'codeValue']);
const screeningEventSerieses = filmsFromCOA.map((filmFromCOA) => {
return createScreeningEventSeriesFromCOA({
project: project,
filmFromCOA: filmFromCOA,
movieTheater: params.movieTheater,
eirinKubuns: eirinKubuns,
eizouKubuns: eizouKubuns,
joueihousikiKubuns: joueihousikiKubuns,
jimakufukikaeKubuns: jimakufukikaeKubuns,
availablePaymentMethodTypes,
seller: params.seller
});
});
const COA_IMPORT_SCREENING_EVENT_SERIES_PERIOD_IN_MONTH = (typeof params.saveScreeningEventSeriesPeriodInMonth === 'number')
? params.saveScreeningEventSeriesPeriodInMonth
// tslint:disable-next-line:no-magic-numbers
: 3;
let savedEventsCount = 0;
// saveScreeningEventSeries:trueの場合のみ保管(2022-10-10~)
if (params.saveScreeningEventSeries === true) {
let saveParams;
if (Array.isArray(importingIds) && importingIds.length > 0) {
saveParams = screeningEventSerieses
.filter((screeningEventSeries) => importingIds.includes(screeningEventSeries.id))
.map((screeningEventSeries) => {
return {
id: screeningEventSeries.id,
attributes: screeningEventSeries,
upsert: true
};
});
}
else {
// 更新対象が無限に増えるのを防ぐためにstartDateでフィルター
const someMonthsAgo = moment()
.add(-COA_IMPORT_SCREENING_EVENT_SERIES_PERIOD_IN_MONTH, 'months');
saveParams = screeningEventSerieses
.filter((screeningEventSeries) => {
return moment(screeningEventSeries.startDate)
.isAfter(someMonthsAgo);
})
.map((screeningEventSeries) => {
return {
id: screeningEventSeries.id,
attributes: screeningEventSeries,
upsert: true
};
});
}
debug('saving', saveParams.length, 'ScreeningEventSeries...');
yield repos.eventSeries.upsertManyEventSeriesById4sskts(saveParams);
debug('saved', saveParams.length, 'ScreeningEventSeries');
savedEventsCount = saveParams.length;
// コンテンツ永続化(2023-10-23~)
try {
debug('saving', saveParams.length, 'movies...');
yield repos.creativeWork.upsertMoviesByIdentifier(saveParams.map((saveScreeningEventSeriesParams) => {
var _a;
return {
$set: Object.assign(Object.assign({ typeOf: factory.creativeWorkType.Movie, project: params.project, identifier: saveScreeningEventSeriesParams.attributes.workPerformed.identifier, name: { ja: (_a = saveScreeningEventSeriesParams.attributes.workPerformed.name) === null || _a === void 0 ? void 0 : _a.ja }, offers: { typeOf: factory.offerType.Offer } }, (typeof saveScreeningEventSeriesParams.attributes.workPerformed.contentRating === 'string')
? { contentRating: saveScreeningEventSeriesParams.attributes.workPerformed.contentRating }
: undefined), (typeof saveScreeningEventSeriesParams.attributes.workPerformed.duration === 'string')
? { duration: saveScreeningEventSeriesParams.attributes.workPerformed.duration }
: undefined)
};
}));
debug('saved', saveParams.length, 'movies');
}
catch (error) {
// tslint:disable-next-line:no-console
console.error('failed in upsertMoviesByIdentifier', error);
}
}
return { screeningEventSerieses, savedEventsCount };
});
}
function saveScreeningEvents(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const screeningEvents = yield createScreeningEvents(params)(repos);
// 永続化
debug(`storing ${screeningEvents.length} screeningEvents...`);
const saveParams = [];
for (const screeningEvent of screeningEvents) {
try {
const attributes = screeningEvent;
saveParams.push({
id: screeningEvent.id,
attributes: attributes,
upsert: true
});
}
catch (error) {
// no op
}
}
yield repos.event.saveManyEvents(saveParams);
debug(`${screeningEvents.length} screeningEvents stored.`);
return screeningEvents;
});
}
function createScreeningEvents(params) {
// tslint:disable-next-line:max-func-body-length
return (repos) => __awaiter(this, void 0, void 0, function* () {
const project = params.project;
// COAからイベント取得;
const schedulesFromCOA = yield repos.masterService.schedule({
theaterCode: params.instrument.theaterCode,
begin: params.instrument.begin, // COAは日本時間で判断
end: params.instrument.end // COAは日本時間で判断
});
// COAから区分マスター抽出
const serviceKubuns = yield repos.masterService.kubunName({
theaterCode: params.instrument.theaterCode,
kubunClass: '009'
});
const acousticKubuns = yield repos.masterService.kubunName({
theaterCode: params.instrument.theaterCode,
kubunClass: '046'
});
let screeningEventSerieses;
if (Array.isArray(params.screeningEventSerieses)) {
screeningEventSerieses = params.screeningEventSerieses;
}
else {
// 指定がなければDBから検索する(2024-09-09~)
const importingEventSeriesIds = [...new Set(schedulesFromCOA.map((scheduleFromCOA) => {
return createScreeningEventSeriesId({
theaterCode: params.instrument.theaterCode,
titleCode: scheduleFromCOA.titleCode,
titleBranchNum: scheduleFromCOA.titleBranchNum
});
}))];
debug('searching eventSeries... importingEventSeriesIds:', importingEventSeriesIds);
if (importingEventSeriesIds.length > 0) {
screeningEventSerieses = yield repos.eventSeries.projectEventSeriesFields({
id: { $in: importingEventSeriesIds },
project: { id: { $eq: params.project.id } }
}, [
'project', 'typeOf', 'eventStatus', 'identifier',
'name', 'kanaName', 'alternativeHeadline', 'location',
'organizer', 'videoFormat', 'soundFormat', 'workPerformed',
'duration', 'endDate', 'startDate', 'coaInfo',
'offers', 'additionalProperty'
]);
debug(screeningEventSerieses.length, 'screeningEventSerieses for importing events found.');
// 万が一未インポートの施設コンテンツがあれば強制的にインポート(2024-09-09~)
if (screeningEventSerieses.length < importingEventSeriesIds.length) {
const saveScreeningEventSeriesResult = yield saveScreeningEventSeries({
locationBranchCode: params.instrument.theaterCode,
movieTheater: params.movieTheater,
project: params.project,
saveScreeningEventSeries: true,
saveScreeningEventSeriesPeriodInMonth: 0, // importingIds指定するので0でok
seller: { id: params.seller.id },
importingIds: importingEventSeriesIds
})(repos);
screeningEventSerieses = saveScreeningEventSeriesResult.screeningEventSerieses;
}
}
else {
screeningEventSerieses = [];
}
}
// イベントごとに永続化トライ
const screeningEvents = [];
schedulesFromCOA.forEach((scheduleFromCOA) => {
const screeningEventSeriesId = createScreeningEventSeriesId({
theaterCode: params.instrument.theaterCode,
titleCode: scheduleFromCOA.titleCode,
titleBranchNum: scheduleFromCOA.titleBranchNum
});
// ルーム存在チェック
const screenRoom = params.screeningRooms.find((place) => place.branchCode === scheduleFromCOA.screenCode);
// const screenRoom = <factory.place.screeningRoom.IPlace | undefined>movieTheater.containsPlace.find(
// (place) => place.branchCode === scheduleFromCOA.screenCode
// );
if (screenRoom === undefined) {
// tslint:disable-next-line:no-console
console.error('screenRoom not found.', scheduleFromCOA.screenCode);
return;
}
// イベントシリーズ取得
const screeningEventSeries = screeningEventSerieses.find((e) => e.id === screeningEventSeriesId);
if (screeningEventSeries === undefined) {
// tslint:disable-next-line:no-console
console.error('screeningEventSeries not found.', screeningEventSeriesId);
return;
}
const screeningEvent = createScreeningEventFromCOA({
project: project,
performanceFromCOA: scheduleFromCOA,
screenRoom: screenRoom,
superEvent: screeningEventSeries,
serviceKubuns: serviceKubuns,
acousticKubuns: acousticKubuns,
seller: params.seller
});
// インポート期間で確実に絞る(2024-04-25~)
const isStartDateInTarget = moment(screeningEvent.startDate)
.isBetween(params.targetImportFrom, params.targetImportThrough, 'second', '[]');
if (isStartDateInTarget) {
screeningEvents.push(screeningEvent);
}
});
debug('createScreeningEvents processed', params.targetImportFrom, params.targetImportThrough, params.instrument.begin, params.instrument.end, 'schedulesFromCOA.length:', schedulesFromCOA.length, 'screeningEvents.length:', screeningEvents.length);
return screeningEvents;
});
}
function cancelDeletedEvents(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
// distinctでidのみ取得(2023-01-25~)
// COAから削除されたイベントをキャンセル済ステータスへ変更
const ids = yield repos.event.searchEventIds({
project: { id: { $eq: params.project.id } },
typeOf: factory.eventType.ScreeningEvent,
superEvent: {
locationBranchCodes: [params.locationBranchCode]
},
startFrom: params.targetImportFrom,
startThrough: params.targetImportThrough
});
const idsShouldBe = params.idsShouldBe;
const cancelledIds = difference(ids, idsShouldBe);
debug(`cancelling ${cancelledIds.length} events...`);
for (const cancelledId of cancelledIds) {
try {
yield repos.event.cancelEvent({
id: cancelledId,
project: { id: params.project.id }
});
}
catch (error) {
// no op
}
}
debug(`${cancelledIds.length} events cancelled.`);
return cancelledIds;
});
}
function minimizeSuperEvent(params) {
const { workPerformed, videoFormat, startDate, soundFormat, name, location, kanaName, identifier, endDate, duration, coaInfo, alternativeHeadline,
// additionalProperty,
typeOf, id
// project,
// organizer,
// offers,
// eventStatus
} = params.superEvent;
return {
workPerformed, videoFormat, startDate, soundFormat,
name, location, kanaName, identifier,
endDate, duration, coaInfo, alternativeHeadline,
// additionalProperty,
typeOf, id
};
}
/**
* コアデータからイベントを作成する
*/
function createScreeningEventFromCOA(params) {
const id = createScreeningEventIdFromCOA({
theaterCode: params.superEvent.location.branchCode,
titleCode: params.superEvent.workPerformed.identifier,
titleBranchNum: params.performanceFromCOA.titleBranchNum,
dateJouei: params.performanceFromCOA.dateJouei,
screenCode: params.performanceFromCOA.screenCode,
timeBegin: params.performanceFromCOA.timeBegin
});
// COA情報を整形して開始日時と終了日時を作成('2500'のような日またぎの時刻入力に対応)
const DAY = 2400;
let timeBegin = params.performanceFromCOA.timeBegin;
let timeEnd = params.performanceFromCOA.timeEnd;
let addDay4startDate = 0;
let addDay4endDate = 0;
try {
addDay4startDate += Math.floor(Number(timeBegin) / DAY);
// tslint:disable-next-line:no-magic-numbers
timeBegin = `0000${Number(timeBegin) % DAY}`.slice(-4);
addDay4endDate += Math.floor(Number(timeEnd) / DAY);
// tslint:disable-next-line:no-magic-numbers
timeEnd = `0000${Number(timeEnd) % DAY}`.slice(-4);
}
catch (error) {
// no op
}
let endDate = moment(`${params.performanceFromCOA.dateJouei} ${timeEnd} +09:00`, 'YYYYMMDD HHmm Z')
.add(addDay4endDate, 'days')
.toDate();
const startDate = moment(`${params.performanceFromCOA.dateJouei} ${timeBegin} +09:00`, 'YYYYMMDD HHmm Z')
.add(addDay4startDate, 'days')
.toDate();
// startDateの方が大きければ日またぎイベントなので調整
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore if */
if (moment(startDate)
.isAfter(moment(endDate))) {
endDate = moment(endDate)
.add(1, 'day')
.toDate();
}
const offers = {
typeOf: factory.offerType.Offer,
offeredThrough: {
typeOf: 'WebAPI',
identifier: factory.service.webAPI.Identifier.COA
},
eligibleQuantity: {
typeOf: 'QuantitativeValue',
unitCode: factory.unitCode.C62,
maxValue: Number(params.performanceFromCOA.availableNum)
},
itemOffered: {
serviceOutput: {
reservedTicket: {
typeOf: 'Ticket',
ticketedSeat: { typeOf: factory.placeType.Seat } // 必ず指定席
}
}
},
seller: {
typeOf: factory.organizationType.Corporation,
id: params.seller.id,
// name: params.sellerFromDB.name,
makesOffer: []
}
};
const { additionalProperty, coaInfo } = createScreeningEventAdditionalPropertyFromCOA(params);
const superEvent = minimizeSuperEvent({ superEvent: params.superEvent }); // optimize superEvent(2024-09-10~)
return {
project: { typeOf: params.project.typeOf, id: params.project.id },
typeOf: factory.eventType.ScreeningEvent,
id: id,
identifier: id,
name: params.superEvent.name,
eventStatus: factory.eventStatusType.EventScheduled,
location: {
typeOf: params.screenRoom.typeOf,
branchCode: params.screenRoom.branchCode,
name: params.screenRoom.name
},
endDate: endDate,
startDate: startDate,
superEvent,
coaInfo,
offers: offers,
checkInCount: 0,
attendeeCount: 0,
maximumAttendeeCapacity: params.screenRoom.maximumAttendeeCapacity,
remainingAttendeeCapacity: params.screenRoom.maximumAttendeeCapacity,
additionalProperty,
organizer: { id: params.seller.id }
};
}
function createScreeningEventAdditionalPropertyFromCOA(params) {
const coaInfo = {
theaterCode: params.superEvent.location.branchCode,
dateJouei: params.performanceFromCOA.dateJouei,
titleCode: params.performanceFromCOA.titleCode,
titleBranchNum: params.performanceFromCOA.titleBranchNum,
timeBegin: params.performanceFromCOA.timeBegin,
timeEnd: params.performanceFromCOA.timeEnd,
screenCode: params.performanceFromCOA.screenCode,
trailerTime: params.performanceFromCOA.trailerTime,
kbnService: params.serviceKubuns.filter((kubun) => kubun.kubunCode === params.performanceFromCOA.kbnService)[0],
kbnAcoustic: params.acousticKubuns.filter((kubun) => kubun.kubunCode === params.performanceFromCOA.kbnAcoustic)[0],
nameServiceDay: params.performanceFromCOA.nameServiceDay,
availableNum: params.performanceFromCOA.availableNum,
rsvStartDate: params.performanceFromCOA.rsvStartDate,
rsvEndDate: params.performanceFromCOA.rsvEndDate,
flgEarlyBooking: params.performanceFromCOA.flgEarlyBooking
};
return {
coaInfo,
additionalProperty: [
{ name: 'coaInfo', value: JSON.stringify(coaInfo) }
]
};
}
/**
* 作品抽出結果から施設コンテンツを作成する
*/
function createScreeningEventSeriesFromCOA(params) {
const endDate = (moment(`${params.filmFromCOA.dateEnd} +09:00`, 'YYYYMMDD Z')
.isValid())
? moment(`${params.filmFromCOA.dateEnd} +09:00`, 'YYYYMMDD Z')
.toDate()
: moment('2118-01-01T00:00:00+09:00') // 値がない場合、十分に長く
.toDate();
const startDate = (moment(`${params.filmFromCOA.dateBegin} +09:00`, 'YYYYMMDD Z')
.isValid())
? moment(`${params.filmFromCOA.dateBegin} +09:00`, 'YYYYMMDD Z')
.toDate()
: moment('2018-01-01T00:00:00+09:00') // 値がない場合、十分に長く
.toDate();
// title_codeは施設をまたいで共有、title_branch_numは施設毎に管理
const id = createScreeningEventSeriesId({
theaterCode: params.movieTheater.branchCode,
titleCode: params.filmFromCOA.titleCode,
titleBranchNum: params.filmFromCOA.titleBranchNum
});
const { additionalProperty, coaInfo } = createScreeningEventSeriesAdditionalPropertyFromCOA(params);
const { unacceptedPaymentMethod } = createScreeningEventSeriesUnacceptedPaymentMethodFromCOA(params);
const workPerformed = Object.assign({
// id: `${params.movieTheater.branchCode}-${params.filmFromCOA.titleCode}`, // discontinue(2025-01-03~)
identifier: params.filmFromCOA.titleCode, name: {
ja: params.filmFromCOA.titleNameOrig
}, duration: moment.duration(params.filmFromCOA.showTime, 'm')
.toISOString(), contentRating: params.eirinKubuns.filter((kubun) => kubun.kubunCode === params.filmFromCOA.kbnEirin)[0], typeOf: factory.creativeWorkType.Movie }, (typeof params.filmFromCOA.titleBranchNum === 'string' && params.filmFromCOA.titleBranchNum.length > 0)
? { version: params.filmFromCOA.titleBranchNum } // add version(2024-01-31~)
: undefined);
// redefine videoFormat(2024-09-18~)
// const videoFormat: factory.event.screeningEventSeries.ICOAKubun =
// params.eizouKubuns.filter((kubun) => kubun.kubunCode === params.filmFromCOA.kbnEizou)[0];
const videoFormat = params.joueihousikiKubuns.filter(({ kubunCode }) => kubunCode === params.filmFromCOA.kbnJoueihousiki)
.map(({ kubunCode }) => ({ typeOf: kubunCode, name: kubunCode }));
return {
project: { typeOf: params.project.typeOf, id: params.project.id },
typeOf: factory.eventType.ScreeningEventSeries,
eventStatus: factory.eventStatusType.EventScheduled,
id: id,
identifier: id,
name: {
ja: params.filmFromCOA.titleName,
en: params.filmFromCOA.titleNameEng
},
kanaName: params.filmFromCOA.titleNameKana,
alternativeHeadline: params.filmFromCOA.titleNameShort,
location: {
id: (params.movieTheater.id !== undefined) ? params.movieTheater.id : '',
branchCode: params.movieTheater.branchCode,
name: params.movieTheater.name,
// 廃止(2024-03-05~)
// kanaName: params.movieTheater.kanaName,
typeOf: params.movieTheater.typeOf
},
// 必須化(2023-07-12~)
organizer: { id: params.seller.id },
videoFormat,
soundFormat: [],
workPerformed,
duration: moment.duration(params.filmFromCOA.showTime, 'm')
.toISOString(),
endDate: endDate,
startDate: startDate,
coaInfo,
offers: Object.assign({ typeOf: factory.offerType.Offer }, (Array.isArray(unacceptedPaymentMethod)) ? { unacceptedPaymentMethod: unacceptedPaymentMethod } : undefined),
additionalProperty
};
}
function createScreeningEventSeriesAdditionalPropertyFromCOA(params) {
const coaInfo = Object.assign(Object.assign(Object.assign({ titleBranchNum: params.filmFromCOA.titleBranchNum, kbnEirin: params.eirinKubuns.filter((k) => k.kubunCode === params.filmFromCOA.kbnEirin)[0], kbnEizou: params.eizouKubuns.filter((k) => k.kubunCode === params.filmFromCOA.kbnEizou)[0], kbnJoueihousiki: params.joueihousikiKubuns.filter((k) => k.kubunCode === params.filmFromCOA.kbnJoueihousiki)[0], kbnJimakufukikae: params.jimakufukikaeKubuns.filter((k) => k.kubunCode === params.filmFromCOA.kbnJimakufukikae)[0], flgMvtkUse: params.filmFromCOA.flgMvtkUse, dateMvtkBegin: params.filmFromCOA.dateMvtkBegin }, (typeof params.filmFromCOA.flgMgtkUse === 'string') ? { flgMgtkUse: params.filmFromCOA.flgMgtkUse } : undefined), (typeof params.filmFromCOA.dateMgtkBegin === 'string') ? { dateMgtkBegin: params.filmFromCOA.dateMgtkBegin } : undefined), (typeof params.filmFromCOA.flgNotDiscount === 'string') ? { flgNotDiscount: params.filmFromCOA.flgNotDiscount } : undefined);
return {
coaInfo,
additionalProperty: [
// { name: 'coaInfo', value: JSON.stringify(coaInfo) } // discontinue(2024-09-13~)
]
};
}
function createScreeningEventSeriesUnacceptedPaymentMethodFromCOA(params) {
let unacceptedPaymentMethod;
// flgMvtkUseはムビチケ、MGチケットの両方に適用される(<-flgMgtkUseが追加されるまで)(~2024-03-05)
if (params.filmFromCOA.flgMvtkUse === '1') {
// no op
}
else {
if (!Array.isArray(unacceptedPaymentMethod)) {
unacceptedPaymentMethod = [];
}
// flgMvtkUseで決済方法区分から動的に
unacceptedPaymentMethod.push(...params.availablePaymentMethodTypes.filter(({ additionalProperty }) => { var _a; return ((_a = additionalProperty === null || additionalProperty === void 0 ? void 0 : additionalProperty.find(({ name }) => name === 'flgMvtkUse')) === null || _a === void 0 ? void 0 : _a.value) === '1'; })
.map(({ codeValue }) => codeValue));
}
if (params.filmFromCOA.flgMgtkUse === '0') {
if (!Array.isArray(unacceptedPaymentMethod)) {
unacceptedPaymentMethod = [];
}
// flgMgtkUseで決済方法区分から動的に
unacceptedPaymentMethod.push(...params.availablePaymentMethodTypes.filter(({ additionalProperty }) => { var _a; return ((_a = additionalProperty === null || additionalProperty === void 0 ? void 0 : additionalProperty.find(({ name }) => name === 'flgMgtkUse')) === null || _a === void 0 ? void 0 : _a.value) === '1'; })
.map(({ codeValue }) => codeValue));
}
if (Array.isArray(unacceptedPaymentMethod)) {
// 重複排除
unacceptedPaymentMethod = [...new Set(unacceptedPaymentMethod)];
}
return { unacceptedPaymentMethod };
}
/**
* COA情報からイベントIDを作成する
*/
function createScreeningEventIdFromCOA(params) {
return [
createScreeningEventSeriesId(params),
params.dateJouei,
params.screenCode,
params.timeBegin
].join('');
}
/**
* COA情報からイベント識別子を作成する
*/
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore next */
function createScreeningEventSeriesId(params) {
return [
params.theaterCode,
params.titleCode,
params.titleBranchNum
].join('');
}
/**
* コアマスター抽出結果から作成する
*/
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore next */
function createMovieTheaterFromCOA(project, seller, theaterFromCOA, screensFromCOA) {
// const id = `MovieTheater-${theaterFromCOA.theaterCode}`;
return {
project: { typeOf: project.typeOf, id: project.id },
// id: id,
// screenCount: screensFromCOA.length,
branchCode: theaterFromCOA.theaterCode,
name: {
ja: theaterFromCOA.theaterName,
en: theaterFromCOA.theaterNameEng
},
kanaName: theaterFromCOA.theaterNameKana,
containsPlace: screensFromCOA.map((screenFromCOA) => {
return createScreeningRoomFromCOA(project, seller, screenFromCOA);
}),
typeOf: factory.placeType.MovieTheater,
telephone: theaterFromCOA.theaterTelNum,
offers: {
// project: { typeOf: project.typeOf, id: project.id }, // optimize(2023-11-06~)
// priceCurrency: factory.priceCurrency.JPY, // optimize(2023-11-06~)
typeOf: factory.offerType.Offer,
eligibleQuantity: {
typeOf: 'QuantitativeValue',
maxValue: 6,
unitCode: factory.unitCode.C62
},
availabilityStartsGraceTime: {
typeOf: 'QuantitativeValue',
value: -2,
unitCode: factory.unitCode.Day
},
availabilityEndsGraceTime: {
typeOf: 'QuantitativeValue',
value: 1200,
unitCode: factory.unitCode.Sec
},
availabilityStartsGraceTimeOnPOS: {
typeOf: 'QuantitativeValue',
value: -93,
unitCode: factory.unitCode.Day
},
availabilityEndsGraceTimeOnPOS: {
typeOf: 'QuantitativeValue',
value: 2678400,
unitCode: factory.unitCode.Sec
}
},
parentOrganization: { id: seller.id, typeOf: factory.organizationType.Corporation }
};
}
/**
* コアスクリーン抽出結果からルームを作成する
*/
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore next */
function createScreeningRoomFromCOA(project, seller, screenFromCOA) {
const sections = [];
const sectionCodes = [];
screenFromCOA.listSeat.forEach((seat) => {
if (sectionCodes.indexOf(seat.seatSection) < 0) {
sectionCodes.push(seat.seatSection);
sections.push({
project: { typeOf: project.typeOf, id: project.id },
branchCode: seat.seatSection,
name: {
ja: `セクション${seat.seatSection}`,
en: `section${seat.seatSection}`
},
containsPlace: [],
typeOf: factory.placeType.ScreeningRoomSection
});
}
sections[sectionCodes.indexOf(seat.seatSection)].containsPlace.push({
project: { typeOf: project.typeOf, id: project.id },
branchCode: seat.seatNum,
typeOf: factory.placeType.Seat,
additionalProperty: [
{ name: 'flgFree', value: String(seat.flgFree) },
{ name: 'flgHc', value: String(seat.flgHc) },
{ name: 'flgPair', value: String(seat.flgPair) },
{ name: 'flgSpare', value: String(seat.flgSpare) },
{ name: 'flgSpecial', value: String(seat.flgSpecial) }
]
});
});
return {
project: { typeOf: project.typeOf, id: project.id },
containsPlace: sections,
branchCode: screenFromCOA.screenCode,
name: {
ja: screenFromCOA.screenName,
en: screenFromCOA.screenNameEng
},
typeOf: factory.placeType.ScreeningRoom,
maximumAttendeeCapacity: sections[0].containsPlace.length,
// 必須化(2023-07-14~)
parentOrganization: { id: seller.id, typeOf: factory.organizationType.Corporation }
};
}
function updateEvent4ttts(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const actionAttributes = Object.assign({ project: { typeOf: factory.organizationType.Project, id: params.project.id }, typeOf: factory.actionType.UpdateAction, agent: params.agent, object: {
id: params.oldEventId,
typeOf: factory.eventType.ScreeningEvent
} }, {
// replacee: reservation,
// replacer: params.attributes, // $unsetもありうるのでいったん保留
targetCollection: {
id: params.oldEventId,
typeOf: factory.eventType.ScreeningEvent
}
});
const action = yield repos.action.start(actionAttributes);
let savedEvent;
try {
savedEvent = yield repos.event.save4ttts({
oldEventId: params.oldEventId,
attributes: params.attributes
});
}
catch (error) {
try {
yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error });
}
catch (__) {
// 失敗したら仕方ない
}
throw error;
}
// アクション完了
yield repos.action.completeWithVoid({ typeOf: action.typeOf, id: action.id, result: { id: savedEvent.id } });
yield (0, onEventChanged_1.onEventChanged)({
id: [savedEvent.id],
project: { id: params.project.id },
typeOf: factory.eventType.ScreeningEvent,
isNew: false,
useInform: true
})(repos
// スケジュールによるイベント作成ではendDateに変更がないのでpendingReservationsへの同期はひとまず必要なし
);
});
}