UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

536 lines (535 loc) 29.4 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.SeatRepo = exports.DEFAULT_ROOM_MAXIMUM_CAPACITY = void 0; const factory = require("../../factory"); const settings_1 = require("../../settings"); const civicStructure_1 = require("../mongoose/schemas/civicStructure"); const place_1 = require("../mongoose/schemas/place"); exports.DEFAULT_ROOM_MAXIMUM_CAPACITY = 10000; /** * 座席リポジトリ */ class SeatRepo { constructor(connection) { this.civicStructureModel = connection.model(civicStructure_1.modelName, (0, civicStructure_1.createSchema)()); this.placeModel = connection.model(place_1.modelName, (0, place_1.createSchema)()); } static CREATE_SEARCH_SEATS_PROJECTION(params) { const includeSectionBranchCode = params['containedInPlace.branchCode'] !== 0; const includeSectionName = params['containedInPlace.name'] !== 0; const includeSectionTypeOf = params['containedInPlace.typeOf'] !== 0; const includeScreeningRooms = params['containedInPlace.containedInPlace'] !== 0; const projectStage = { _id: 0, typeOf: '$containsPlace.containsPlace.typeOf', branchCode: '$containsPlace.containsPlace.branchCode', name: '$containsPlace.containsPlace.name', seatingType: '$containsPlace.containsPlace.seatingType', maximumAttendeeCapacity: '$containsPlace.containsPlace.maximumAttendeeCapacity', // add maximumAttendeeCapacity(2024-04-02~) containedInPlace: Object.assign(Object.assign(Object.assign(Object.assign({}, (includeSectionBranchCode) ? { branchCode: '$containsPlace.branchCode' } : undefined), (includeSectionName) ? { name: '$containsPlace.name' } : undefined), (includeSectionTypeOf) ? { typeOf: '$containsPlace.typeOf' } : undefined), (includeScreeningRooms) ? { containedInPlace: { typeOf: '$typeOf', branchCode: '$branchCode', name: '$name', containedInPlace: { id: '$containedInPlace.id', typeOf: '$containedInPlace.typeOf', branchCode: '$containedInPlace.branchCode', name: '$containedInPlace.name' } } } : undefined), additionalProperty: '$containsPlace.containsPlace.additionalProperty' }; Object.keys(params) .forEach((field) => { if (typeof projectStage[field] === 'string') { // tslint:disable-next-line:no-dynamic-delete delete projectStage[field]; } }); return projectStage; } // tslint:disable-next-line:cyclomatic-complexity max-func-body-length static CREATE_MATCH_STAGES(params, options) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o; const { filterTypeOf } = options; const matchStages = []; if (filterTypeOf) { matchStages.push({ $match: { typeOf: { $eq: factory.placeType.ScreeningRoom } } }); } const projectIdEq = (_b = (_a = params.project) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.$eq; if (typeof projectIdEq === 'string') { matchStages.push({ $match: { 'project.id': { $eq: projectIdEq } } }); } const parentOrganizationIdEq = (_d = (_c = params.parentOrganization) === null || _c === void 0 ? void 0 : _c.id) === null || _d === void 0 ? void 0 : _d.$eq; if (typeof parentOrganizationIdEq === 'string') { matchStages.push({ $match: { 'parentOrganization.id': { $exists: true, $eq: parentOrganizationIdEq } } }); } if (params.containedInPlace !== undefined) { if (params.containedInPlace.containedInPlace !== undefined) { if (params.containedInPlace.containedInPlace.containedInPlace !== undefined) { if (params.containedInPlace.containedInPlace.containedInPlace.branchCode !== undefined) { // 施設 if (typeof params.containedInPlace.containedInPlace.containedInPlace.branchCode.$eq === 'string') { matchStages.push({ $match: { 'containedInPlace.branchCode': { // $exists: true, // 不要(2025-04-28~) $eq: params.containedInPlace.containedInPlace.containedInPlace.branchCode.$eq } } }); } } } if (params.containedInPlace.containedInPlace.branchCode !== undefined) { // ルーム if (typeof params.containedInPlace.containedInPlace.branchCode.$eq === 'string') { matchStages.push({ $match: { branchCode: { $eq: params.containedInPlace.containedInPlace.branchCode.$eq } } }); } } } } // セクション const containedInPlaceBranchCodeEq = (_f = (_e = params.containedInPlace) === null || _e === void 0 ? void 0 : _e.branchCode) === null || _f === void 0 ? void 0 : _f.$eq; if (typeof containedInPlaceBranchCodeEq === 'string') { matchStages.push({ $match: { 'containsPlace.branchCode': { $exists: true, $eq: containedInPlaceBranchCodeEq } } }); } const containedInPlaceBranchCodeIn = (_h = (_g = params.containedInPlace) === null || _g === void 0 ? void 0 : _g.branchCode) === null || _h === void 0 ? void 0 : _h.$in; if (Array.isArray(containedInPlaceBranchCodeIn)) { matchStages.push({ $match: { 'containsPlace.branchCode': { $exists: true, $in: containedInPlaceBranchCodeIn } } }); } // 座席 if (params.branchCode !== undefined) { if (typeof params.branchCode.$eq === 'string') { matchStages.push({ $match: { 'containsPlace.containsPlace.branchCode': { $exists: true, $eq: params.branchCode.$eq } } }); } } const branchCodeIn = (_j = params.branchCode) === null || _j === void 0 ? void 0 : _j.$in; if (Array.isArray(branchCodeIn)) { matchStages.push({ $match: { 'containsPlace.containsPlace.branchCode': { $exists: true, $in: branchCodeIn } } }); } const branchCodeRegex = (_k = params.branchCode) === null || _k === void 0 ? void 0 : _k.$regex; if (typeof branchCodeRegex === 'string' && branchCodeRegex.length > 0) { matchStages.push({ $match: { 'containsPlace.containsPlace.branchCode': { $exists: true, $regex: new RegExp(branchCodeRegex) } } }); } const nameRegex = (_l = params.name) === null || _l === void 0 ? void 0 : _l.$regex; if (typeof nameRegex === 'string' && nameRegex.length > 0) { matchStages.push({ $match: { $or: [ { 'containsPlace.containsPlace.name.ja': { $exists: true, $regex: new RegExp(nameRegex) } }, { 'containsPlace.containsPlace.name.en': { $exists: true, $regex: new RegExp(nameRegex) } } ] } }); } const seatingTypeEq = (_m = params.seatingType) === null || _m === void 0 ? void 0 : _m.$eq; if (typeof seatingTypeEq === 'string') { matchStages.push({ $match: { 'containsPlace.containsPlace.seatingType': { $exists: true, $eq: seatingTypeEq } } }); } const additionalPropertyElemMatch = (_o = params.additionalProperty) === null || _o === void 0 ? void 0 : _o.$elemMatch; if (additionalPropertyElemMatch !== undefined && additionalPropertyElemMatch !== null) { matchStages.push({ $match: { 'containsPlace.containsPlace.additionalProperty': { $exists: true, $elemMatch: additionalPropertyElemMatch } } }); } return matchStages; } // tslint:disable-next-line:max-func-body-length createSeat(seat) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c; const screeningRoomSection = seat.containedInPlace; if (typeof (screeningRoomSection === null || screeningRoomSection === void 0 ? void 0 : screeningRoomSection.branchCode) !== 'string') { throw new factory.errors.ArgumentNull('containedInPlace.branchCode'); } const screeningRoom = screeningRoomSection.containedInPlace; if (typeof (screeningRoom === null || screeningRoom === void 0 ? void 0 : screeningRoom.branchCode) !== 'string') { throw new factory.errors.ArgumentNull('containedInPlace.containedInPlace.branchCode'); } const movieTheater = screeningRoom.containedInPlace; if (typeof (movieTheater === null || movieTheater === void 0 ? void 0 : movieTheater.branchCode) !== 'string') { throw new factory.errors.ArgumentNull('containedInPlace.containedInPlace.containedInPlace.branchCode'); } // 施設存在確認 const movieTheaterDoc = yield this.civicStructureModel.findOne(Object.assign({ typeOf: { $eq: factory.placeType.MovieTheater }, 'project.id': { $eq: seat.project.id }, branchCode: { $eq: movieTheater.branchCode } }, (typeof ((_a = seat.parentOrganization) === null || _a === void 0 ? void 0 : _a.id) === 'string') ? { 'parentOrganization.id': { $exists: true, $eq: seat.parentOrganization.id } } : undefined), { _id: 1 }) .lean() .exec(); if (movieTheaterDoc === null) { throw new factory.errors.NotFound(factory.placeType.MovieTheater); } const doc = yield this.placeModel.findOneAndUpdate({ typeOf: { $eq: factory.placeType.ScreeningRoom }, 'project.id': { $eq: seat.project.id }, 'containedInPlace.branchCode': { $exists: true, $eq: movieTheater.branchCode }, branchCode: { $eq: screeningRoom.branchCode }, 'containsPlace.branchCode': { $eq: screeningRoomSection.branchCode } }, { $push: { 'containsPlace.$[screeningRoomSection].containsPlace': Object.assign(Object.assign(Object.assign({ typeOf: seat.typeOf, branchCode: seat.branchCode, additionalProperty: seat.additionalProperty }, (typeof ((_b = seat.name) === null || _b === void 0 ? void 0 : _b.ja) === 'string' || typeof ((_c = seat.name) === null || _c === void 0 ? void 0 : _c.en) === 'string') ? { name: seat.name } : undefined), (Array.isArray(seat.seatingType)) ? { seatingType: seat.seatingType } : undefined), (seat.maximumAttendeeCapacity === 0) ? { maximumAttendeeCapacity: seat.maximumAttendeeCapacity } : undefined) } }, { new: true, arrayFilters: [ { 'screeningRoomSection.branchCode': { $eq: screeningRoomSection.branchCode }, 'screeningRoomSection.containsPlace.branchCode': { $ne: seat.branchCode } } ], projection: { 'containedInPlace.id': 1, typeOf: 1 } }) .exec(); // 存在しなければコード重複 if (doc === null) { throw new factory.errors.AlreadyInUse(factory.placeType.Seat, ['branchCode']); } return doc.toObject(); }); } // tslint:disable-next-line:cyclomatic-complexity max-func-body-length updateSeat(seat, $unset) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c; const screeningRoomSection = seat.containedInPlace; if (typeof (screeningRoomSection === null || screeningRoomSection === void 0 ? void 0 : screeningRoomSection.branchCode) !== 'string') { throw new factory.errors.ArgumentNull('containedInPlace.branchCode'); } const screeningRoom = screeningRoomSection.containedInPlace; if (typeof (screeningRoom === null || screeningRoom === void 0 ? void 0 : screeningRoom.branchCode) !== 'string') { throw new factory.errors.ArgumentNull('containedInPlace.containedInPlace.branchCode'); } const movieTheater = screeningRoom.containedInPlace; if (typeof (movieTheater === null || movieTheater === void 0 ? void 0 : movieTheater.branchCode) !== 'string') { throw new factory.errors.ArgumentNull('containedInPlace.containedInPlace.containedInPlace.branchCode'); } const doc = yield this.placeModel.findOneAndUpdate(Object.assign({ typeOf: { $eq: factory.placeType.ScreeningRoom }, 'project.id': { $eq: seat.project.id }, 'containedInPlace.branchCode': { $exists: true, $eq: movieTheater.branchCode }, branchCode: { $eq: screeningRoom.branchCode }, 'containsPlace.branchCode': { $eq: screeningRoomSection.branchCode }, 'containsPlace.containsPlace.branchCode': { $eq: seat.branchCode } }, (typeof ((_a = seat.parentOrganization) === null || _a === void 0 ? void 0 : _a.id) === 'string') ? { 'parentOrganization.id': { $exists: true, $eq: seat.parentOrganization.id } } : undefined), Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ 'containsPlace.$[screeningRoomSection].containsPlace.$[seat].branchCode': seat.branchCode }, (typeof ((_b = seat.name) === null || _b === void 0 ? void 0 : _b.ja) === 'string' || typeof ((_c = seat.name) === null || _c === void 0 ? void 0 : _c.en) === 'string') ? { 'containsPlace.$[screeningRoomSection].containsPlace.$[seat].name': seat.name } : undefined), (Array.isArray(seat.seatingType)) ? { 'containsPlace.$[screeningRoomSection].containsPlace.$[seat].seatingType': seat.seatingType } : undefined), (Array.isArray(seat.additionalProperty)) ? { 'containsPlace.$[screeningRoomSection].containsPlace.$[seat].additionalProperty': seat.additionalProperty } : undefined), (seat.maximumAttendeeCapacity === 0) ? { 'containsPlace.$[screeningRoomSection].containsPlace.$[seat].maximumAttendeeCapacity': seat.maximumAttendeeCapacity } : undefined), { $unset: Object.assign(Object.assign(Object.assign({ noExistingAttributeName: 1 }, (($unset === null || $unset === void 0 ? void 0 : $unset['containsPlace.$[screeningRoom].containsPlace.$[screeningRoomSection].containsPlace.$[seat].name']) === 1 || ($unset === null || $unset === void 0 ? void 0 : $unset['containsPlace.$[screeningRoomSection].containsPlace.$[seat].name']) === 1) ? { 'containsPlace.$[screeningRoomSection].containsPlace.$[seat].name': 1 } : undefined), (($unset === null || $unset === void 0 ? void 0 : $unset['containsPlace.$[screeningRoom].containsPlace.$[screeningRoomSection].containsPlace.$[seat].seatingType']) === 1 || ($unset === null || $unset === void 0 ? void 0 : $unset['containsPlace.$[screeningRoomSection].containsPlace.$[seat].seatingType']) === 1) ? { 'containsPlace.$[screeningRoomSection].containsPlace.$[seat].seatingType': 1 } : undefined), (($unset === null || $unset === void 0 ? void 0 : $unset['containsPlace.$[screeningRoom].containsPlace.$[screeningRoomSection].containsPlace.$[seat].maximumAttendeeCapacity']) === 1 || ($unset === null || $unset === void 0 ? void 0 : $unset['containsPlace.$[screeningRoomSection].containsPlace.$[seat].maximumAttendeeCapacity']) === 1) ? { 'containsPlace.$[screeningRoomSection].containsPlace.$[seat].maximumAttendeeCapacity': 1 } : undefined) }), { new: true, arrayFilters: [ { 'screeningRoomSection.branchCode': { $eq: screeningRoomSection.branchCode } }, { 'seat.branchCode': { $eq: seat.branchCode } } ], projection: { 'containedInPlace.id': 1, typeOf: 1 } }) .exec(); if (doc === null) { throw new factory.errors.NotFound(factory.placeType.Seat); } return doc.toObject(); }); } searchSeats(params) { return __awaiter(this, void 0, void 0, function* () { const matchStages = SeatRepo.CREATE_MATCH_STAGES(params, { filterTypeOf: true }); const projectStage = SeatRepo.CREATE_SEARCH_SEATS_PROJECTION(Object.assign({}, params.$projection)); const aggregate = this.placeModel.aggregate([ { $unwind: { path: '$containsPlace' } }, { $unwind: { path: '$containsPlace.containsPlace' } }, ...matchStages, { $project: projectStage } ]); 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)); } return aggregate .option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS }) .exec(); }); } // ルーム指定の座席検索として再定義(2025-04-28~) projectSeatsByScreeningRoom(params) { return __awaiter(this, void 0, void 0, function* () { const { limit, page, project, containedInPlace, screeningRoom, $projection } = params, searchSeatsConditions = __rest(params, ["limit", "page", "project", "containedInPlace", "screeningRoom", "$projection"]); // まずルーム検索 const screeningRoomDoc = yield this.placeModel.findOne({ typeOf: { $eq: factory.placeType.ScreeningRoom }, 'project.id': { $eq: project.id.$eq }, 'containedInPlace.branchCode': { $exists: true, $eq: screeningRoom.containedInPlace.branchCode.$eq }, branchCode: { $eq: screeningRoom.branchCode.$eq } }, { _id: 1 }) .lean() .exec(); // console.log('screeningRoomDoc:', screeningRoomDoc); if (screeningRoomDoc === null) { return []; } const matchStageBeforeUnwind = { $match: { _id: { $eq: screeningRoomDoc._id } } }; const matchStages = SeatRepo.CREATE_MATCH_STAGES(Object.assign(Object.assign({}, searchSeatsConditions), { containedInPlace: Object.assign(Object.assign({}, containedInPlace), { containedInPlace: { containedInPlace: {} } }) }), { filterTypeOf: false }); const projectStage = SeatRepo.CREATE_SEARCH_SEATS_PROJECTION(Object.assign({}, $projection)); const pageMustBeOne = (typeof page === 'number' && page > 0) ? page : 1; let limitStage; let skipStage; if (typeof limit === 'number' && limit > 0) { limitStage = { $limit: limit * pageMustBeOne }; skipStage = { $skip: limit * (pageMustBeOne - 1) }; } const pipeline = [ // uniwind前はid指定に変更(2025-04-28~) matchStageBeforeUnwind, { $unwind: { path: '$containsPlace' // includeArrayIndex: 'sectionIndex' } }, { $unwind: { path: '$containsPlace.containsPlace' // includeArrayIndex: 'seatIndex' } }, ...matchStages, ...(limitStage !== undefined) ? [limitStage] : [], ...(skipStage !== undefined) ? [skipStage] : [], // { // $sort: { // 'containsPlace.branchCode': factory.sortType.Ascending, // 'containsPlace.containsPlace.branchCode': factory.sortType.Ascending // } // }, // { $skip: limit * (pageMustBeOne - 1) }, // { $limit: limit }, { $project: projectStage } ]; // console.log(pipeline); return this.placeModel.aggregate(pipeline) .option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS // explain: true, // hint: 'searchSeatsSort' }) .exec(); }); } /** * 座席区分集計検索 */ aggregateSeatingTypes(params) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; const matchStages = [{ $match: { typeOf: { $eq: factory.placeType.ScreeningRoom } } }]; const projectIdEq = (_b = (_a = params.project) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.$eq; if (typeof projectIdEq === 'string') { matchStages.push({ $match: { 'project.id': { $eq: projectIdEq } } }); } const branchCodeEq = (_e = (_d = (_c = params.containedInPlace) === null || _c === void 0 ? void 0 : _c.containedInPlace) === null || _d === void 0 ? void 0 : _d.branchCode) === null || _e === void 0 ? void 0 : _e.$eq; if (typeof branchCodeEq === 'string') { matchStages.push({ $match: { branchCode: { $eq: branchCodeEq } } }); } const containedInPlaceBranchCodeEq = (_j = (_h = (_g = (_f = params.containedInPlace) === null || _f === void 0 ? void 0 : _f.containedInPlace) === null || _g === void 0 ? void 0 : _g.containedInPlace) === null || _h === void 0 ? void 0 : _h.branchCode) === null || _j === void 0 ? void 0 : _j.$eq; if (typeof containedInPlaceBranchCodeEq === 'string') { matchStages.push({ $match: { 'containedInPlace.branchCode': { $exists: true, $eq: containedInPlaceBranchCodeEq } } }); } const seatBranchCodeIn = (_k = params.branchCode) === null || _k === void 0 ? void 0 : _k.$in; if (Array.isArray(seatBranchCodeIn)) { matchStages.push({ $match: { 'containsPlace.containsPlace.branchCode': { $exists: true, $in: seatBranchCodeIn } } }); } const sectionBranchCodeIn = (_m = (_l = params.containedInPlace) === null || _l === void 0 ? void 0 : _l.branchCode) === null || _m === void 0 ? void 0 : _m.$in; if (Array.isArray(sectionBranchCodeIn)) { matchStages.push({ $match: { 'containsPlace.branchCode': { $exists: true, $in: sectionBranchCodeIn } } }); } const aggregate = this.placeModel.aggregate([ { $unwind: { path: '$containsPlace', preserveNullAndEmptyArrays: false } }, { $unwind: { path: '$containsPlace.containsPlace', preserveNullAndEmptyArrays: false } }, { $unwind: { path: '$containsPlace.containsPlace.seatingType', preserveNullAndEmptyArrays: false } }, ...matchStages, // $unwindとの順序に注意 { $group: { _id: '$containsPlace.containsPlace.seatingType' } }, { $group: { // tslint:disable-next-line:no-null-keyword _id: null, seatingTypes: { $push: '$_id' } } } ]); const result = (yield aggregate .option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS }) .exec()).shift(); // .then((result) => result.map(({ _id }) => _id)); return (result !== undefined) ? result.seatingTypes : []; }); } deleteSeat(seat) { return __awaiter(this, void 0, void 0, function* () { var _a; const doc = yield this.placeModel.findOneAndUpdate(Object.assign({ typeOf: { $eq: factory.placeType.ScreeningRoom }, 'project.id': { $eq: seat.project.id }, 'containedInPlace.branchCode': { $exists: true, $eq: seat.containedInPlace.containedInPlace.containedInPlace.branchCode }, branchCode: { $eq: seat.containedInPlace.containedInPlace.branchCode }, 'containsPlace.branchCode': { $eq: seat.containedInPlace.branchCode }, 'containsPlace.containsPlace.branchCode': { $eq: seat.branchCode } }, (typeof ((_a = seat.parentOrganization) === null || _a === void 0 ? void 0 : _a.id) === 'string') ? { 'parentOrganization.id': { $exists: true, $eq: seat.parentOrganization.id } } : undefined), { $pull: { 'containsPlace.$[screeningRoomSection].containsPlace': { branchCode: seat.branchCode } } }, { new: true, arrayFilters: [ { 'screeningRoomSection.branchCode': { $eq: seat.containedInPlace.branchCode } } ], projection: { 'containedInPlace.id': 1, typeOf: 1 } }) .exec(); if (doc === null) { throw new factory.errors.NotFound(factory.placeType.Seat); } return doc.toObject(); }); } } exports.SeatRepo = SeatRepo;