@chevre/domain
Version:
Chevre Domain Library for Node.js
982 lines (981 loc) • 58.6 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());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventRepo = void 0;
const factory = require("../factory");
const EventFactory = require("../factory/event");
const event_1 = require("./mongoose/schemas/event");
const errorHandler_1 = require("../errorHandler");
const settings_1 = require("../settings");
const AVAILABLE_PUBLIC_PROJECT_FIELDS = [
'additionalProperty', 'aggregateReservation', 'attendeeCount', 'checkInCount', 'coaInfo',
// 'description',
'doorTime', 'endDate', 'eventStatus', 'identifier', 'location',
'maximumAttendeeCapacity', 'name',
// 'offers',
'organizer', 'project', 'remainingAttendeeCapacity', 'startDate', 'superEvent', 'typeOf'
];
/**
* イベントリポジトリ
*/
class EventRepo {
constructor(connection) {
this.eventModel = connection.model(event_1.modelName, (0, event_1.createSchema)());
}
// tslint:disable-next-line:cyclomatic-complexity max-func-body-length
static CREATE_MONGO_CONDITIONS(conditions) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27;
const andConditions = [];
const typeOfEq = conditions.typeOf;
if (typeof typeOfEq === 'string') {
andConditions.push({ typeOf: { $eq: typeOfEq } });
}
const typeOfIn = conditions.typeOfIn;
if (Array.isArray(typeOfIn)) {
andConditions.push({ typeOf: { $in: typeOfIn } });
}
// typeOf条件必須検証(2023-07-13~)
if (typeof typeOfEq !== 'string' && !Array.isArray(typeOfIn)) {
throw new factory.errors.ArgumentNull('typeOf');
}
const projectIdEq = (_b = (_a = conditions.project) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.$eq;
if (typeof projectIdEq === 'string') {
andConditions.push({ 'project.id': { $eq: projectIdEq } });
}
const organizerIdEq = (_d = (_c = conditions.organizer) === null || _c === void 0 ? void 0 : _c.id) === null || _d === void 0 ? void 0 : _d.$eq;
if (typeof organizerIdEq === 'string') {
andConditions.push({ 'organizer.id': { $exists: true, $eq: organizerIdEq } });
}
const idEq = (_e = conditions.id) === null || _e === void 0 ? void 0 : _e.$eq;
if (typeof idEq === 'string') {
andConditions.push({ _id: { $eq: idEq } });
}
const idIn = (_f = conditions.id) === null || _f === void 0 ? void 0 : _f.$in;
if (Array.isArray(idIn)) {
andConditions.push({ _id: { $in: idIn } });
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (Array.isArray(conditions.eventStatuses)) {
andConditions.push({
eventStatus: { $in: conditions.eventStatuses }
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (conditions.inSessionFrom !== undefined) {
andConditions.push({
endDate: { $gte: conditions.inSessionFrom }
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (conditions.inSessionThrough !== undefined) {
andConditions.push({
startDate: { $lte: conditions.inSessionThrough }
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (conditions.startFrom !== undefined) {
andConditions.push({
startDate: { $gte: conditions.startFrom }
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (conditions.startThrough !== undefined) {
andConditions.push({
startDate: { $lte: conditions.startThrough }
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (conditions.endFrom !== undefined) {
andConditions.push({
endDate: { $gte: conditions.endFrom }
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (conditions.endThrough !== undefined) {
andConditions.push({
endDate: { $lte: conditions.endThrough }
});
}
const locationBranchCodeEq = (_h = (_g = conditions.location) === null || _g === void 0 ? void 0 : _g.branchCode) === null || _h === void 0 ? void 0 : _h.$eq;
if (typeof locationBranchCodeEq === 'string') {
andConditions.push({ 'location.branchCode': { $exists: true, $eq: locationBranchCodeEq } });
}
const locationBranchCodeIn = (_k = (_j = conditions.location) === null || _j === void 0 ? void 0 : _j.branchCode) === null || _k === void 0 ? void 0 : _k.$in;
if (Array.isArray(locationBranchCodeIn)) {
andConditions.push({ 'location.branchCode': { $exists: true, $in: locationBranchCodeIn } });
}
// discontinue(2024-09-30)
// const hasOfferCatalogIdEq = conditions.hasOfferCatalog?.id?.$eq;
// if (typeof hasOfferCatalogIdEq === 'string') {
// andConditions.push({
// 'hasOfferCatalog.id': {
// $exists: true,
// $eq: hasOfferCatalogIdEq
// }
// });
// }
const additionalPropertyElemMatch = (_l = conditions.additionalProperty) === null || _l === void 0 ? void 0 : _l.$elemMatch;
if (additionalPropertyElemMatch !== undefined && additionalPropertyElemMatch !== null) {
andConditions.push({
additionalProperty: {
$exists: true,
$elemMatch: additionalPropertyElemMatch
}
});
}
let params;
switch (conditions.typeOf) {
case factory.eventType.Event:
params = conditions;
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (params.offers !== undefined) {
const itemOfferedIdIn4event = (_o = (_m = params.offers.itemOffered) === null || _m === void 0 ? void 0 : _m.id) === null || _o === void 0 ? void 0 : _o.$in;
if (Array.isArray(itemOfferedIdIn4event)) {
andConditions.push({
'offers.itemOffered.id': {
$exists: true,
$in: itemOfferedIdIn4event
}
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (params.offers.itemOffered !== undefined) {
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (params.offers.itemOffered.serviceOutput !== undefined) {
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (params.offers.itemOffered.serviceOutput.reservedTicket !== undefined) {
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (params.offers.itemOffered.serviceOutput.reservedTicket.ticketedSeat !== undefined) {
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (Array.isArray(params.offers.itemOffered.serviceOutput.reservedTicket.ticketedSeat.typeOfs)) {
andConditions.push({
'offers.itemOffered.serviceOutput.reservedTicket.ticketedSeat.typeOf': {
$exists: true,
$in: params.offers.itemOffered.serviceOutput.reservedTicket.ticketedSeat.typeOfs
}
});
}
}
}
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (params.offers.itemOffered.serviceType !== undefined) {
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (Array.isArray(params.offers.itemOffered.serviceType.ids)) {
andConditions.push({
'offers.itemOffered.serviceType.id': {
$exists: true,
$in: params.offers.itemOffered.serviceType.ids
}
});
}
}
}
}
const sellerMakesOfferElemMatch4event = (_r = (_q = (_p = params.offers) === null || _p === void 0 ? void 0 : _p.seller) === null || _q === void 0 ? void 0 : _q.makesOffer) === null || _r === void 0 ? void 0 : _r.$elemMatch;
if (typeof ((_s = sellerMakesOfferElemMatch4event === null || sellerMakesOfferElemMatch4event === void 0 ? void 0 : sellerMakesOfferElemMatch4event['availableAtOrFrom.id']) === null || _s === void 0 ? void 0 : _s.$eq) === 'string') {
andConditions.push({
'offers.seller.makesOffer': {
$exists: true,
$elemMatch: sellerMakesOfferElemMatch4event
}
});
}
const reservationForIdentifierEq = (_x = (_w = (_v = (_u = (_t = params.offers) === null || _t === void 0 ? void 0 : _t.itemOffered) === null || _u === void 0 ? void 0 : _u.serviceOutput) === null || _v === void 0 ? void 0 : _v.reservationFor) === null || _w === void 0 ? void 0 : _w.identifier) === null || _x === void 0 ? void 0 : _x.$eq;
if (typeof reservationForIdentifierEq === 'string') {
andConditions.push({
'offers.itemOffered.serviceOutput.reservationFor.identifier': {
$exists: true,
$eq: reservationForIdentifierEq
}
});
}
const reservationForArrivalBusStopBranchCodeEq = (_3 = (_2 = (_1 = (_0 = (_z = (_y = params.offers) === null || _y === void 0 ? void 0 : _y.itemOffered) === null || _z === void 0 ? void 0 : _z.serviceOutput) === null || _0 === void 0 ? void 0 : _0.reservationFor) === null || _1 === void 0 ? void 0 : _1.arrivalBusStop) === null || _2 === void 0 ? void 0 : _2.branchCode) === null || _3 === void 0 ? void 0 : _3.$eq;
if (typeof reservationForArrivalBusStopBranchCodeEq === 'string') {
andConditions.push({
'offers.itemOffered.serviceOutput.reservationFor.arrivalBusStop.branchCode': {
$exists: true,
$eq: reservationForArrivalBusStopBranchCodeEq
}
});
}
const reservationForDepartureBusStopBranchCodeEq = (_9 = (_8 = (_7 = (_6 = (_5 = (_4 = params.offers) === null || _4 === void 0 ? void 0 : _4.itemOffered) === null || _5 === void 0 ? void 0 : _5.serviceOutput) === null || _6 === void 0 ? void 0 : _6.reservationFor) === null || _7 === void 0 ? void 0 : _7.departureBusStop) === null || _8 === void 0 ? void 0 : _8.branchCode) === null || _9 === void 0 ? void 0 : _9.$eq;
if (typeof reservationForDepartureBusStopBranchCodeEq === 'string') {
andConditions.push({
'offers.itemOffered.serviceOutput.reservationFor.departureBusStop.branchCode': {
$exists: true,
$eq: reservationForDepartureBusStopBranchCodeEq
}
});
}
break;
case factory.eventType.ScreeningEvent:
params = conditions;
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (typeof params.name === 'string' && params.name.length > 0) {
andConditions.push({
$or: [
{
'name.ja': {
$exists: true,
$regex: new RegExp(params.name)
}
},
{
'name.en': {
$exists: true,
$regex: new RegExp(params.name)
}
}
]
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
const superEventLocationIdEq = (_12 = (_11 = (_10 = params.superEvent) === null || _10 === void 0 ? void 0 : _10.location) === null || _11 === void 0 ? void 0 : _11.id) === null || _12 === void 0 ? void 0 : _12.$eq;
if (typeof superEventLocationIdEq === 'string') {
andConditions.push({
'superEvent.location.id': {
$exists: true,
$eq: superEventLocationIdEq
}
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (params.superEvent !== undefined) {
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (Array.isArray(params.superEvent.ids)) {
andConditions.push({
'superEvent.id': {
$exists: true,
$in: params.superEvent.ids
}
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (Array.isArray(params.superEvent.locationBranchCodes)) {
andConditions.push({
'superEvent.location.branchCode': {
$exists: true,
$in: params.superEvent.locationBranchCodes
}
});
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (Array.isArray(params.superEvent.workPerformedIdentifiers)) {
andConditions.push({
'superEvent.workPerformed.identifier': {
$exists: true,
$in: params.superEvent.workPerformedIdentifiers
}
});
}
}
const itemOfferedIdIn = (_15 = (_14 = (_13 = params.offers) === null || _13 === void 0 ? void 0 : _13.itemOffered) === null || _14 === void 0 ? void 0 : _14.id) === null || _15 === void 0 ? void 0 : _15.$in;
if (Array.isArray(itemOfferedIdIn)) {
andConditions.push({
'offers.itemOffered.id': {
$exists: true,
$in: itemOfferedIdIn
}
});
}
const itemOfferedTicketedSeatTypeOfIn = (_20 = (_19 = (_18 = (_17 = (_16 = params.offers) === null || _16 === void 0 ? void 0 : _16.itemOffered) === null || _17 === void 0 ? void 0 : _17.serviceOutput) === null || _18 === void 0 ? void 0 : _18.reservedTicket) === null || _19 === void 0 ? void 0 : _19.ticketedSeat) === null || _20 === void 0 ? void 0 : _20.typeOfs;
if (Array.isArray(itemOfferedTicketedSeatTypeOfIn)) {
andConditions.push({
'offers.itemOffered.serviceOutput.reservedTicket.ticketedSeat.typeOf': {
$exists: true,
$in: itemOfferedTicketedSeatTypeOfIn
}
});
}
const itemOfferedServiceTypeIdIn = (_23 = (_22 = (_21 = params.offers) === null || _21 === void 0 ? void 0 : _21.itemOffered) === null || _22 === void 0 ? void 0 : _22.serviceType) === null || _23 === void 0 ? void 0 : _23.ids;
if (Array.isArray(itemOfferedServiceTypeIdIn)) {
andConditions.push({
'offers.itemOffered.serviceType.id': {
$exists: true,
$in: itemOfferedServiceTypeIdIn
}
});
}
const sellerMakesOfferElemMatch = (_26 = (_25 = (_24 = params.offers) === null || _24 === void 0 ? void 0 : _24.seller) === null || _25 === void 0 ? void 0 : _25.makesOffer) === null || _26 === void 0 ? void 0 : _26.$elemMatch;
if (typeof ((_27 = sellerMakesOfferElemMatch === null || sellerMakesOfferElemMatch === void 0 ? void 0 : sellerMakesOfferElemMatch['availableAtOrFrom.id']) === null || _27 === void 0 ? void 0 : _27.$eq) === 'string') {
andConditions.push({
'offers.seller.makesOffer': {
$exists: true,
$elemMatch: sellerMakesOfferElemMatch
}
});
}
break;
case factory.eventType.ScreeningEventSeries:
throw new factory.errors.Internal('typeOf: ScreeningEventSeries discontinued');
default:
}
return andConditions;
}
/**
* 複数イベントを作成する
*/
createManyEvents(params) {
return __awaiter(this, void 0, void 0, function* () {
const uniqid = yield Promise.resolve().then(() => require('uniqid'));
// let docs: HydratedDocument<factory.event.IEvent<T>>[];
const insertingDocs = params.attributes.map((p) => {
return Object.assign({ _id: uniqid() }, p);
});
try {
yield this.eventModel.insertMany(insertingDocs, { rawResult: true } // rawResult(2024-08-02~)
);
// console.dir(insertResult, { depth: null });
}
catch (error) {
if (yield (0, errorHandler_1.isMongoError)(error)) {
if (error.code === errorHandler_1.MongoErrorCode.DuplicateKey) {
throw new factory.errors.AlreadyInUse(factory.eventType.ScreeningEvent, ['offeredBy.member.identifier']);
}
}
throw error;
}
if (params.expectsNoContent) {
return;
}
return insertingDocs.map(({ _id }) => _id);
});
}
/**
* 特定の追加特性をキーにして、存在しなければ作成する(複数対応)
* 施設コンテンツとルームは1つに限定
* 存在すれば、特定の属性のみ更新する
*/
// tslint:disable-next-line:max-func-body-length
upsertManyByAdditionalProperty(params, options) {
return __awaiter(this, void 0, void 0, function* () {
const { update } = options;
const uniqid = yield Promise.resolve().then(() => require('uniqid'));
const bulkWriteOps = [];
const additionalProperties = [];
const { events, additionalPropertyFilter, eventSeries, screeningRoom } = params;
if (Array.isArray(events)) {
events.forEach((creatingEventParams) => {
var _a, _b;
if (creatingEventParams.typeOf !== factory.eventType.ScreeningEvent) {
throw new factory.errors.NotImplemented(`only ${factory.eventType.ScreeningEvent} implemented`);
}
const additionalPropertyValue = (_b = (_a = creatingEventParams.additionalProperty) === null || _a === void 0 ? void 0 : _a.find((property) => property.name === additionalPropertyFilter.name)) === null || _b === void 0 ? void 0 : _b.value;
if (typeof additionalPropertyValue !== 'string' || additionalPropertyValue === '') {
throw new factory.errors.ArgumentNull('additionalProperty.value');
}
additionalProperties.push({ name: additionalPropertyFilter.name, value: additionalPropertyValue });
if (creatingEventParams.superEvent.id !== eventSeries.id) {
throw new factory.errors.Argument('superEvent.id', 'superEvent.id not matched');
}
if (creatingEventParams.location.branchCode !== screeningRoom.branchCode) {
throw new factory.errors.Argument('location.branchCode', 'location.branchCode not matched');
}
const filter = {
typeOf: { $eq: creatingEventParams.typeOf },
'project.id': { $eq: creatingEventParams.project.id },
// 追加特性をキーに更新
additionalProperty: {
$exists: true,
$all: [{ name: additionalPropertyFilter.name, value: additionalPropertyValue }]
},
'superEvent.id': { $exists: true, $eq: creatingEventParams.superEvent.id } // add superEvent.id(2024-09-15~)
};
if (update === true) {
// implemente(2024-12-20~)
const { eventStatus, superEvent, offers // <-上書き可能な属性を限定的に
} = creatingEventParams;
bulkWriteOps.push({
updateOne: {
filter,
update: {
$set: {
eventStatus,
superEvent,
'offers.seller.makesOffer': offers.seller.makesOffer
}
},
upsert: false
}
});
}
else {
const { coaInfo, // ←適用しない
// identifier, // support identifier(2025-05-13~)
maximumAttendeeCapacity, remainingAttendeeCapacity, checkInCount, attendeeCount, aggregateReservation, // ←適用しない
eventStatus, superEvent } = creatingEventParams, // <-上書き可能な属性を限定的に
setOnInsertFields = __rest(creatingEventParams, ["coaInfo", "maximumAttendeeCapacity", "remainingAttendeeCapacity", "checkInCount", "attendeeCount", "aggregateReservation", "eventStatus", "superEvent"]);
const setOnInsert = Object.assign(Object.assign({}, setOnInsertFields), { _id: uniqid() });
bulkWriteOps.push({
updateOne: {
filter,
update: {
$setOnInsert: setOnInsert,
// 変更可能な属性のみ上書き
$set: {
eventStatus,
superEvent // add superEvent(2024-09-15~)
}
},
upsert: true
}
});
}
});
}
if (bulkWriteOps.length > 0) {
const bulkWriteResult = yield this.eventModel.bulkWrite(bulkWriteOps, { ordered: false });
// modifiedの場合upsertedIdsに含まれないので、idを検索する
const modifiedEvents = yield this.eventModel.find({
typeOf: { $eq: params.events[0].typeOf },
'project.id': { $eq: params.events[0].project.id },
additionalProperty: { $exists: true, $in: additionalProperties },
'superEvent.id': { $exists: true, $eq: eventSeries.id } // add superEvent.id(2024-09-15~)
}, {
_id: 0,
id: { $toString: '$_id' }
})
.lean() // lean(2024-09-15~)
.exec();
return { bulkWriteResult, modifiedEvents };
}
});
}
/**
* イベント部分更新
*/
updatePartiallyById(params) {
return __awaiter(this, void 0, void 0, function* () {
// let doc: Document | null;
const _a = params.attributes, { typeOf } = _a, updateFields = __rest(_a, ["typeOf"]);
if (typeof typeOf !== 'string' || typeOf.length === 0) {
throw new factory.errors.ArgumentNull('attributes.typeOf');
}
const doc = yield this.eventModel.findOneAndUpdate({
_id: { $eq: params.id },
'project.id': { $eq: params.project.id },
typeOf: { $eq: typeOf }
}, {
$set: updateFields
}, { upsert: false, new: false, projection: { _id: 1 } })
.lean()
.exec();
if (doc === null) {
throw new factory.errors.NotFound(this.eventModel.modelName);
}
});
}
/**
* イベントを保管する
*/
saveEvent(params) {
return __awaiter(this, void 0, void 0, function* () {
let savedEventId;
let doc;
const _a = params.attributes, { identifier, project, typeOf } = _a, updateFields = __rest(_a, ["identifier", "project", "typeOf"]);
if (typeof typeOf !== 'string' || typeOf.length === 0) {
throw new factory.errors.ArgumentNull('attributes.typeOf');
}
try {
if (params.id === undefined) {
const uniqid = yield Promise.resolve().then(() => require('uniqid'));
const id = uniqid();
doc = yield this.eventModel.create(Object.assign(Object.assign({}, params.attributes), { _id: id }));
savedEventId = id;
}
else {
// const upsert: boolean = params.upsert === true;
const upsert = false; // always false(2025-05-15~)
doc = yield this.eventModel.findOneAndUpdate({
_id: { $eq: params.id },
typeOf: { $eq: typeOf }
}, Object.assign({
// 上書き禁止属性を除外(2022-08-24~)
$setOnInsert: Object.assign({ typeOf,
project }, (typeof identifier === 'string' && identifier !== '') ? { identifier } : undefined), $set: updateFields }, (params.$unset !== undefined) ? { $unset: params.$unset } : undefined), { upsert, new: true, projection: { _id: 1 } })
.lean()
.exec();
savedEventId = params.id;
}
}
catch (error) {
if (yield (0, errorHandler_1.isMongoError)(error)) {
if (error.code === errorHandler_1.MongoErrorCode.DuplicateKey) {
throw new factory.errors.AlreadyInUse(factory.eventType.ScreeningEvent, ['offeredBy.member.identifier']);
}
}
throw error;
}
if (doc === null) {
throw new factory.errors.NotFound(this.eventModel.modelName);
}
return { id: savedEventId }; // optimize(2024-07-31~)
});
}
saveManyEvents(params) {
return __awaiter(this, void 0, void 0, function* () {
const bulkWriteOps = [];
if (Array.isArray(params)) {
params.forEach((p) => {
const upsert = p.upsert === true;
if (p.attributes.typeOf === factory.eventType.ScreeningEvent) {
// 上書き禁止属性を除外(2022-08-24~)
const _a = p.attributes, { identifier, project, typeOf, remainingAttendeeCapacity } = _a, updateFields = __rest(_a, ["identifier", "project", "typeOf", "remainingAttendeeCapacity"]);
bulkWriteOps.push({
updateOne: {
filter: {
_id: p.id,
typeOf: p.attributes.typeOf
},
update: Object.assign({ $setOnInsert: Object.assign(Object.assign({ typeOf: p.attributes.typeOf, project: p.attributes.project }, (typeof p.attributes.identifier === 'string')
? { identifier: p.attributes.identifier } : undefined), (typeof p.attributes.remainingAttendeeCapacity === 'number')
? { remainingAttendeeCapacity: p.attributes.remainingAttendeeCapacity }
: undefined), $set: updateFields }, (p.$unset !== undefined) ? { $unset: p.$unset } : undefined),
upsert
}
});
}
else if (p.attributes.typeOf === factory.eventType.ScreeningEventSeries) {
throw new factory.errors.Internal('typeOf: ScreeningEventSeries discontinued');
}
});
}
if (bulkWriteOps.length > 0) {
yield this.eventModel.bulkWrite(bulkWriteOps, { ordered: false });
}
});
}
save4ttts(params) {
return __awaiter(this, void 0, void 0, function* () {
// let doc: Document | null;
const _a = params.attributes, { identifier, project, typeOf } = _a, updateFields = __rest(_a, ["identifier", "project", "typeOf"]);
const uniqid = yield Promise.resolve().then(() => require('uniqid'));
const id = uniqid();
const doc = yield this.eventModel.findOneAndUpdate({
'project.id': { $eq: project.id },
typeOf: { $eq: typeOf },
// 追加特性をキーに更新
additionalProperty: {
$exists: true,
$all: [{ name: 'oldEventId', value: params.oldEventId }]
}
},
// upsertの場合、createがありうるので属性を除外しない
{
$setOnInsert: Object.assign({ _id: id, typeOf,
project }, (typeof identifier === 'string' && identifier !== '') ? { identifier } : undefined),
$set: updateFields
}, { upsert: true, new: true, projection: { _id: 1 } })
.lean()
.exec();
if (doc === null) {
throw new factory.errors.NotFound(this.eventModel.modelName);
}
return { id: doc._id }; // optimize(2024-07-31~)
});
}
/**
* イベントを検索する(inclusion projection)
*/
projectEventFields(params, inclusion) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const conditions = EventRepo.CREATE_MONGO_CONDITIONS(params);
let projection = {};
const positiveProjectionFields = (Array.isArray(inclusion))
? inclusion.filter((key) => key !== 'id' && key !== '_id')
: [];
if (Array.isArray(inclusion) && inclusion.length > 0) {
projection = Object.assign({ _id: 0, id: { $toString: '$_id' } }, Object.fromEntries(positiveProjectionFields.map((key) => ([key, 1]))));
}
else {
// discontinue(2024-07-24~)
throw new factory.errors.ArgumentNull('inclusion', 'inclusion must be specified');
}
const query = this.eventModel.find({ $and: conditions }, projection);
if (typeof params.limit === 'number' && params.limit > 0) {
const page = (typeof params.page === 'number' && params.page > 0) ? params.page : 1;
query.limit(params.limit)
.skip(params.limit * (page - 1));
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (((_a = params.sort) === null || _a === void 0 ? void 0 : _a.startDate) !== undefined) {
query.sort({ startDate: params.sort.startDate });
}
// const explainResult = await query.explain()
// .exec();
// console.log(explainResult[0].executionStats.allPlansExecution.map((e: any) => e.executionStages.inputStage));
// console.log(explainResult[0].executionStats.allPlansExecution);
// console.log(explainResult[0].queryPlanner?.winningPlan);
// console.log(explainResult[0].queryPlanner?.winningPlan?.inputStage?.inputStage?.inputStage);
// console.log(explainResult);
// return [];
return query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
.lean() // lean(2024-08-01~)
.exec();
});
}
/**
* apiで公開属性を検索する(2024-10-13~)
*/
aggregatePublicFields(params, inclusion, options) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b;
const { includeOffers, includeSellerMakesOffer, sellerMakesOfferAvailableAtIn } = options;
const conditions = EventRepo.CREATE_MONGO_CONDITIONS(params);
let projection;
let positiveProjectionFields;
if (Array.isArray(inclusion) && inclusion.length > 0) {
positiveProjectionFields = inclusion.filter((key) => AVAILABLE_PUBLIC_PROJECT_FIELDS.includes(key));
projection = Object.assign({ _id: 0, id: { $toString: '$_id' } }, Object.fromEntries(positiveProjectionFields.map((key) => ([key, 1]))));
if (includeOffers) {
projection = Object.assign(Object.assign(Object.assign({}, projection), { 'offers.typeOf': 1,
// 'offers.availabilityEnds': 1,
// 'offers.availabilityStarts': 1,
'offers.eligibleQuantity': 1, 'offers.itemOffered': 1, 'offers.offeredThrough': 1,
// 'offers.validFrom': 1,
// 'offers.validThrough': 1,
'offers.unacceptedPaymentMethod': 1, 'offers.seller.typeOf': 1, 'offers.seller.id': 1, 'offers.seller.name': 1 }), (includeSellerMakesOffer)
? Object.assign({}, (Array.isArray(sellerMakesOfferAvailableAtIn))
? {
'offers.seller.makesOffer': {
$filter: {
input: '$offers.seller.makesOffer',
as: 'sellerMakesOffer',
cond: { $in: ['$$sellerMakesOffer.availableAtOrFrom.id', sellerMakesOfferAvailableAtIn] }
}
}
}
: { 'offers.seller.makesOffer': 1 }) : undefined);
}
}
else {
// discontinue(2024-07-24~)
throw new factory.errors.ArgumentNull('inclusion', 'inclusion must be specified');
}
const aggregate = this.eventModel.aggregate([
{ $match: { $and: conditions } },
...(((_a = params.sort) === null || _a === void 0 ? void 0 : _a.startDate) !== undefined)
? [{ $sort: { startDate: params.sort.startDate } }]
: [],
{ $project: projection }
]);
if (typeof params.limit === 'number' && params.limit > 0) {
const page = (typeof params.page === 'number' && params.page > 0) ? params.page : 1;
aggregate.limit(params.limit * page)
.skip(params.limit * (page - 1));
}
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (((_b = params.sort) === null || _b === void 0 ? void 0 : _b.startDate) !== undefined) {
aggregate.sort({ startDate: params.sort.startDate });
}
return aggregate
.option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
.exec();
});
}
/**
* IDのみで検索する
* projectionなし
*/
findAnyEventById(params) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const doc = yield this.eventModel.findOne(Object.assign({ _id: { $eq: params.id.$eq }, 'project.id': { $eq: params.project.id.$eq }, typeOf: { $in: [factory.eventType.Event, factory.eventType.ScreeningEvent] } }, (typeof ((_a = params.organizer) === null || _a === void 0 ? void 0 : _a.id.$eq) === 'string')
? { 'organizer.id': { $exists: true, $eq: params.organizer.id.$eq } }
: undefined), {
__v: 0,
createdAt: 0,
updatedAt: 0,
// DefaultでaggregateEntranceGateを取得しない(2023-01-25~)
aggregateEntranceGate: 0,
// DefaultでaggregateOfferを取得しない(2023-01-24~)
aggregateOffer: 0
})
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
.exec();
if (doc === null) {
throw new factory.errors.NotFound('Event');
}
return doc.toObject();
});
}
searchEventIds(params) {
return __awaiter(this, void 0, void 0, function* () {
const conditions = EventRepo.CREATE_MONGO_CONDITIONS(params);
const query = this.eventModel.distinct('_id', { $and: conditions });
return query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
.exec();
});
}
/**
* 特定イベントから指定フィールドのみ取得する
* イベント IDは必ず返ります
*/
projectEventFieldsById(params, inclusion // add projection(2024-07-18~)
) {
return __awaiter(this, void 0, void 0, function* () {
const projection = {
_id: 0,
id: { $toString: '$_id' }
};
if (Array.isArray(inclusion) && inclusion.length > 0) {
inclusion.forEach((field) => {
if (field !== '_id' && field !== 'id') {
projection[field] = 1;
}
});
}
else {
// discontinue(2024-07-24~)
throw new factory.errors.ArgumentNull('inclusion', 'inclusion must be specified');
// projection = PROJECTION_MINIMIZED_EVENT;
}
const doc = yield this.eventModel.findOne({ _id: { $eq: params.id } }, projection)
.lean() // lean(2024-07-24~)
.exec();
if (doc === null) {
throw new factory.errors.NotFound(this.eventModel.modelName);
}
return doc;
});
}
/**
* イベントをキャンセルする
*/
cancelEvent(params) {
return __awaiter(this, void 0, void 0, function* () {
return this.eventModel.updateOne({
_id: { $eq: params.id },
'project.id': { $eq: params.project.id }
}, { $set: { eventStatus: factory.eventStatusType.EventCancelled } }, { includeResultMetadata: true })
.exec();
});
}
/**
* 興行イベントのsuperEventを最新の情報に同期する
*/
syncScreeningEventSeries2screeningEvents(params) {
return __awaiter(this, void 0, void 0, function* () {
const superEvent = EventFactory.minimizeSuperEvent({ superEventFromDB: params.superEventFromDB });
yield this.eventModel.updateMany({
typeOf: { $eq: factory.eventType.ScreeningEvent },
'project.id': { $eq: params.project.id },
'superEvent.id': { $exists: true, $eq: params.superEventFromDB.id },
startDate: { $gte: params.startDate.$gte }
}, {
$set: {
superEvent
}
})
.exec();
});
}
deleteEventById(params) {
return __awaiter(this, void 0, void 0, function* () {
yield this.eventModel.findOneAndDelete({
_id: params.id,
'project.id': { $eq: params.project.id }
})
.exec();
});
}
deleteManyEventByOrganizerId(params) {
return __awaiter(this, void 0, void 0, function* () {
return this.eventModel.deleteMany({
'project.id': { $eq: params.project.id },
'organizer.id': { $exists: true, $eq: params.organizer.id }
})
.exec();
});
}
deleteManyEventsByScreeningRoom(params) {
return __awaiter(this, void 0, void 0, function* () {
return this.eventModel.deleteMany({
'project.id': { $eq: params.project.id },
'location.branchCode': { $exists: true, $eq: params.location.branchCode },
'superEvent.location.id': { $exists: true, $eq: params.location.containedInPlace.id }
})
.exec();
});
}
deleteManyBySuperEventId(params) {
return __awaiter(this, void 0, void 0, function* () {
return this.eventModel.deleteMany({
'project.id': { $eq: params.project.id },
'superEvent.id': { $exists: true, $eq: params.superEvent.id }
})
.exec();
});
}
deleteManyBySuperEventLocationId(params) {
return __awaiter(this, void 0, void 0, function* () {
return this.eventModel.deleteMany({
'project.id': { $eq: params.project.id },
'superEvent.location.id': { $exists: true, $eq: params.superEvent.location.id }
})
.exec();
});
}
/**
* 興行(プロダクト)から削除する
*/
deleteManyEventsByItemOfferedId(params) {
return __awaiter(this, void 0, void 0, function* () {
return this.eventModel.deleteMany({
'project.id': { $eq: params.project.id },
'offers.itemOffered.id': { $exists: true, $in: params.offers.itemOffered.id.$in }
})
.exec();
});
}
deleteManyEventsEndedByProject(params) {
return __awaiter(this, void 0, void 0, function* () {
return this.eventModel.deleteMany({
typeOf: { $in: params.typeOf.$in },
'project.id': { $eq: params.project.id },
endDate: { $lte: params.endDate.$lte }
})
.exec();
});
}
deleteManyEventsEnded(params) {
return __awaiter(this, void 0, void 0, function* () {
return this.eventModel.deleteMany({
typeOf: { $eq: params.typeOf.$eq },
endDate: { $lte: params.endDate.$lte }
})
.exec();
});
}
deleteByProject(params) {
return __awaiter(this, void 0, void 0, function* () {
yield this.eventModel.deleteMany({
'project.id': { $eq: params.project.id }
})
.exec();
});
}
/**
* 集計属性を更新する
*/
updateAggregationById(params, update) {
return __awaiter(this, void 0, void 0, function* () {
const doc = yield this.eventModel.findOneAndUpdate({ _id: { $eq: params.id } }, update, {
new: false,
projection: { _id: 1 }
})
.lean()
.exec();
if (doc === null) {
throw new factory.errors.NotFound(this.eventModel.modelName);
}
});
}
bulkWrite(bulkWriteOps) {
return __awaiter(this, void 0, void 0, function* () {
return this.eventModel.bulkWrite(bulkWriteOps, { ordered: false });
});
}
getCursor(conditions, projection) {
return this.eventModel.find(conditions, projection)
.sort({ startDate: factory.sortType.Descending })
.cursor();
}
addAvailableAtOrFrom(params) {
return __awaiter(this, void 0, void 0, function* () {
yield this.eventModel.updateOne({ _id: { $eq: params.id } }, {
$push: {
'offers.seller.makesOffer': params.offers.seller.makesOffer
}
}, { includeResultMetadata: true })
.exec();
});
}
unsetUnnecessaryFields(params) {
return __awaiter(this, void 0, void 0, function* () {
return this.eventModel.updateMany(params.filter, { $unset: params.$unset }, { timestamps: false })
.exec();
});
}
aggregateEvent(params) {
return __awaiter(this, void 0, void 0, function* () {
const statuses = yield Promise.all([
factory.eventStatusType.EventScheduled,
factory.eventStatusType.EventCancelled,
factory.eventStatusType.EventPostponed
].map((eventStatus) => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
const matchConditions = Object.assign({ startDate: {
$gte: params.startFrom,
$lte: params.startThrough
}, typeOf: { $eq: params.typeOf }, eventStatus: { $eq: eventStatus } }, (typeof ((_b = (_a = params.project) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.$ne) === 'string')
? { 'project.id': { $ne: params.project.id.$ne } }
: undefined);
return this.agggregateByStatus({ matchConditions, status: eventStatus });
})));
return { statuses };
});
}
// tslint:disable-next-line:max-func-body-length
agggregateByStatus(params) {
return __awaiter(this, void 0, void 0, function* () {
const matchConditions = params.matchConditions;
const eventStatus = params.status;
const aggregations = yield this.eventModel.aggregate([
{
$match: matchConditions
},
{
$project: {
remainingCapacityRate: {
$cond: {
if: {
$and: [
{ $isNumber: '$maximumAttendeeCapacity' },
{ $isNumber: '$remainingAttendeeCapacity' }
]
},