UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

982 lines (981 loc) 58.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; 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' } ] },