@chevre/domain 26.1.0-alpha.6 → 26.1.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/chevre/repo/adminPendingReservation.d.ts +53 -0
- package/lib/chevre/repo/adminPendingReservation.js +107 -0
- package/lib/chevre/repo/pendingReservation.d.ts +1 -54
- package/lib/chevre/repo/pendingReservation.js +24 -243
- package/lib/chevre/repo/stockHolder.d.ts +0 -4
- package/lib/chevre/repo/stockHolder.js +6 -79
- package/lib/chevre/repository.d.ts +5 -0
- package/lib/chevre/repository.js +13 -2
- package/package.json +1 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Connection, FilterQuery } from 'mongoose';
|
|
2
|
+
import { IReservationPackage, ISubReservation } from './mongoose/schemas/pendingReservation';
|
|
3
|
+
interface ISearchConditions {
|
|
4
|
+
limit?: number;
|
|
5
|
+
page?: number;
|
|
6
|
+
project?: {
|
|
7
|
+
id?: {
|
|
8
|
+
$eq?: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
provider?: {
|
|
12
|
+
id?: {
|
|
13
|
+
$eq?: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
reservationFor?: {
|
|
17
|
+
id?: {
|
|
18
|
+
$eq?: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
reservationNumber?: {
|
|
22
|
+
$eq?: string;
|
|
23
|
+
};
|
|
24
|
+
subReservation?: {
|
|
25
|
+
identifier?: {
|
|
26
|
+
$eq?: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
type IProjectFieldResult = Pick<IReservationPackage, 'bookingTime' | 'numSeats' | 'dateCreated' | 'dateModified' | 'expires' | 'reservationFor' | 'reservationNumber' | 'typeOf'>;
|
|
31
|
+
type IProjectSubReservationResult = Pick<ISubReservation, 'identifier'> & {
|
|
32
|
+
index: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* 保留予約管理リポジトリ
|
|
36
|
+
*/
|
|
37
|
+
export declare class AdminPendingReservationRepo {
|
|
38
|
+
private readonly pendingReservationModel;
|
|
39
|
+
constructor(connection: Connection);
|
|
40
|
+
static CREATE_FILTER_QUERY(params: ISearchConditions): FilterQuery<IReservationPackage>[];
|
|
41
|
+
findPendingReservations(params: ISearchConditions): Promise<IProjectFieldResult[]>;
|
|
42
|
+
projectSubReservationByReservationNumber(params: {
|
|
43
|
+
project: {
|
|
44
|
+
id: {
|
|
45
|
+
$eq: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
reservationNumber: {
|
|
49
|
+
$eq: string;
|
|
50
|
+
};
|
|
51
|
+
}): Promise<IProjectSubReservationResult[]>;
|
|
52
|
+
}
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AdminPendingReservationRepo = void 0;
|
|
4
|
+
const factory_1 = require("../factory");
|
|
5
|
+
const settings_1 = require("../settings");
|
|
6
|
+
const pendingReservation_1 = require("./mongoose/schemas/pendingReservation");
|
|
7
|
+
/**
|
|
8
|
+
* 保留予約管理リポジトリ
|
|
9
|
+
*/
|
|
10
|
+
class AdminPendingReservationRepo {
|
|
11
|
+
pendingReservationModel;
|
|
12
|
+
constructor(connection) {
|
|
13
|
+
this.pendingReservationModel = connection.model(pendingReservation_1.modelName, (0, pendingReservation_1.createSchema)());
|
|
14
|
+
}
|
|
15
|
+
static CREATE_FILTER_QUERY(params) {
|
|
16
|
+
const filterQueries = [
|
|
17
|
+
// { numSeats: { $gte: 1 } }
|
|
18
|
+
];
|
|
19
|
+
const projectIdEq = params.project?.id?.$eq;
|
|
20
|
+
if (typeof projectIdEq === 'string') {
|
|
21
|
+
filterQueries.push({ 'project.id': { $eq: projectIdEq } });
|
|
22
|
+
}
|
|
23
|
+
const providerIdEq = params.provider?.id?.$eq;
|
|
24
|
+
if (typeof providerIdEq === 'string') {
|
|
25
|
+
filterQueries.push({ 'provider.id': { $eq: providerIdEq } });
|
|
26
|
+
}
|
|
27
|
+
const reservationForIdEq = params.reservationFor?.id?.$eq;
|
|
28
|
+
if (typeof reservationForIdEq === 'string') {
|
|
29
|
+
filterQueries.push({ 'reservationFor.id': { $eq: reservationForIdEq } });
|
|
30
|
+
}
|
|
31
|
+
const reservationNumberEq = params.reservationNumber?.$eq;
|
|
32
|
+
if (typeof reservationNumberEq === 'string') {
|
|
33
|
+
filterQueries.push({ reservationNumber: { $eq: reservationNumberEq } });
|
|
34
|
+
}
|
|
35
|
+
const subReservationIdentifierEq = params.subReservation?.identifier?.$eq;
|
|
36
|
+
if (typeof subReservationIdentifierEq === 'string') {
|
|
37
|
+
filterQueries.push({ 'subReservation.identifier': { $eq: subReservationIdentifierEq } });
|
|
38
|
+
}
|
|
39
|
+
return filterQueries;
|
|
40
|
+
}
|
|
41
|
+
async findPendingReservations(params) {
|
|
42
|
+
const { limit, page } = params;
|
|
43
|
+
const filterQueries = AdminPendingReservationRepo.CREATE_FILTER_QUERY(params);
|
|
44
|
+
const matchStage = (filterQueries.length > 0) ? { $match: { $and: filterQueries } } : undefined;
|
|
45
|
+
let limitStage;
|
|
46
|
+
let skipStage;
|
|
47
|
+
if (typeof limit === 'number' && limit > 0) {
|
|
48
|
+
const pageMustBePositive = (typeof page === 'number' && page > 0) ? page : 1;
|
|
49
|
+
skipStage = { $skip: limit * (pageMustBePositive - 1) };
|
|
50
|
+
limitStage = { $limit: limit };
|
|
51
|
+
}
|
|
52
|
+
const projectStage = {
|
|
53
|
+
$project: {
|
|
54
|
+
_id: 0,
|
|
55
|
+
typeOf: '$typeOf',
|
|
56
|
+
bookingTime: '$bookingTime',
|
|
57
|
+
dateCreated: '$dateCreated',
|
|
58
|
+
dateModified: '$dateModified',
|
|
59
|
+
expires: '$expires',
|
|
60
|
+
numSeats: '$numSeats',
|
|
61
|
+
reservationFor: '$reservationFor',
|
|
62
|
+
reservationNumber: '$reservationNumber',
|
|
63
|
+
subReservationCount: { $size: '$subReservation' }
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const pipeline = [
|
|
67
|
+
...(matchStage !== undefined) ? [matchStage] : [],
|
|
68
|
+
{ $sort: { bookingTime: factory_1.factory.sortType.Descending } },
|
|
69
|
+
...(skipStage !== undefined) ? [skipStage] : [],
|
|
70
|
+
...(limitStage !== undefined) ? [limitStage] : [],
|
|
71
|
+
projectStage
|
|
72
|
+
];
|
|
73
|
+
return this.pendingReservationModel.aggregate(pipeline)
|
|
74
|
+
.option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
75
|
+
.exec();
|
|
76
|
+
}
|
|
77
|
+
async projectSubReservationByReservationNumber(params) {
|
|
78
|
+
const matchStage = {
|
|
79
|
+
$match: {
|
|
80
|
+
'project.id': { $eq: params.project.id.$eq },
|
|
81
|
+
reservationNumber: { $eq: params.reservationNumber.$eq }
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const projectStage = {
|
|
85
|
+
$project: {
|
|
86
|
+
_id: 0,
|
|
87
|
+
identifier: '$subReservation.identifier',
|
|
88
|
+
index: `$reservationIndex`
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const unwindStage = {
|
|
92
|
+
$unwind: {
|
|
93
|
+
path: '$subReservation',
|
|
94
|
+
includeArrayIndex: 'reservationIndex'
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const pipeline = [
|
|
98
|
+
matchStage,
|
|
99
|
+
unwindStage,
|
|
100
|
+
projectStage
|
|
101
|
+
];
|
|
102
|
+
return this.pendingReservationModel.aggregate(pipeline)
|
|
103
|
+
.option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
104
|
+
.exec();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.AdminPendingReservationRepo = AdminPendingReservationRepo;
|
|
@@ -1,44 +1,11 @@
|
|
|
1
|
-
import type { Connection
|
|
2
|
-
import { IReservationPackage, ISubReservation } from './mongoose/schemas/pendingReservation';
|
|
1
|
+
import type { Connection } from 'mongoose';
|
|
3
2
|
import { AbstractStockHolderRepo, IGetHolderResult, ILockKey, IOffer, IUnlockKey } from './stockHolderAbstract';
|
|
4
|
-
interface ISearchConditions {
|
|
5
|
-
limit?: number;
|
|
6
|
-
page?: number;
|
|
7
|
-
project?: {
|
|
8
|
-
id?: {
|
|
9
|
-
$eq?: string;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
provider?: {
|
|
13
|
-
id?: {
|
|
14
|
-
$eq?: string;
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
reservationFor?: {
|
|
18
|
-
id?: {
|
|
19
|
-
$eq?: string;
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
reservationNumber?: {
|
|
23
|
-
$eq?: string;
|
|
24
|
-
};
|
|
25
|
-
subReservation?: {
|
|
26
|
-
identifier?: {
|
|
27
|
-
$eq?: string;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
type IProjectFieldResult = Pick<IReservationPackage, 'bookingTime' | 'numSeats' | 'dateCreated' | 'dateModified' | 'expires' | 'reservationFor' | 'reservationNumber' | 'typeOf'>;
|
|
32
|
-
type IProjectSubReservationResult = Pick<ISubReservation, 'identifier'> & {
|
|
33
|
-
index: number;
|
|
34
|
-
};
|
|
35
3
|
/**
|
|
36
4
|
* 保留予約リポジトリ
|
|
37
5
|
*/
|
|
38
6
|
export declare class PendingReservationRepo implements AbstractStockHolderRepo {
|
|
39
7
|
private readonly pendingReservationModel;
|
|
40
8
|
constructor(connection: Connection);
|
|
41
|
-
static CREATE_FILTER_QUERY(params: ISearchConditions): FilterQuery<IReservationPackage>[];
|
|
42
9
|
private static offer2identifier;
|
|
43
10
|
private static lockKey2reservationPackage;
|
|
44
11
|
lockIfNotLimitExceeded(lockKey: ILockKey, maximumReservationCount: number): Promise<void>;
|
|
@@ -67,25 +34,6 @@ export declare class PendingReservationRepo implements AbstractStockHolderRepo {
|
|
|
67
34
|
hasTicketedSeat: boolean;
|
|
68
35
|
offers: IOffer[];
|
|
69
36
|
}): Promise<IGetHolderResult[]>;
|
|
70
|
-
docExists(params: {
|
|
71
|
-
eventId: string;
|
|
72
|
-
}): Promise<boolean>;
|
|
73
|
-
deleteExpiredMany(params: {
|
|
74
|
-
expires: {
|
|
75
|
-
$lte: Date;
|
|
76
|
-
};
|
|
77
|
-
}): Promise<import("mongodb").DeleteResult>;
|
|
78
|
-
projectFields(params: ISearchConditions): Promise<IProjectFieldResult[]>;
|
|
79
|
-
projectSubReservationByReservationNumber(params: {
|
|
80
|
-
project: {
|
|
81
|
-
id: {
|
|
82
|
-
$eq: string;
|
|
83
|
-
};
|
|
84
|
-
};
|
|
85
|
-
reservationNumber: {
|
|
86
|
-
$eq: string;
|
|
87
|
-
};
|
|
88
|
-
}): Promise<IProjectSubReservationResult[]>;
|
|
89
37
|
/**
|
|
90
38
|
* expiresを最新の情報に同期する
|
|
91
39
|
*/
|
|
@@ -100,4 +48,3 @@ export declare class PendingReservationRepo implements AbstractStockHolderRepo {
|
|
|
100
48
|
private deleteReservationPackage;
|
|
101
49
|
private deleteReservationIfExists;
|
|
102
50
|
}
|
|
103
|
-
export {};
|
|
@@ -14,37 +14,10 @@ const debug = (0, debug_1.default)('chevre-domain:repo:pendingReservation');
|
|
|
14
14
|
* 保留予約リポジトリ
|
|
15
15
|
*/
|
|
16
16
|
class PendingReservationRepo {
|
|
17
|
-
// private readonly aggregateReservationModel: IModel;
|
|
18
17
|
pendingReservationModel;
|
|
19
18
|
constructor(connection) {
|
|
20
19
|
this.pendingReservationModel = connection.model(pendingReservation_1.modelName, (0, pendingReservation_1.createSchema)());
|
|
21
20
|
}
|
|
22
|
-
static CREATE_FILTER_QUERY(params) {
|
|
23
|
-
const filterQueries = [
|
|
24
|
-
// { numSeats: { $gte: 1 } }
|
|
25
|
-
];
|
|
26
|
-
const projectIdEq = params.project?.id?.$eq;
|
|
27
|
-
if (typeof projectIdEq === 'string') {
|
|
28
|
-
filterQueries.push({ 'project.id': { $eq: projectIdEq } });
|
|
29
|
-
}
|
|
30
|
-
const providerIdEq = params.provider?.id?.$eq;
|
|
31
|
-
if (typeof providerIdEq === 'string') {
|
|
32
|
-
filterQueries.push({ 'provider.id': { $eq: providerIdEq } });
|
|
33
|
-
}
|
|
34
|
-
const reservationForIdEq = params.reservationFor?.id?.$eq;
|
|
35
|
-
if (typeof reservationForIdEq === 'string') {
|
|
36
|
-
filterQueries.push({ 'reservationFor.id': { $eq: reservationForIdEq } });
|
|
37
|
-
}
|
|
38
|
-
const reservationNumberEq = params.reservationNumber?.$eq;
|
|
39
|
-
if (typeof reservationNumberEq === 'string') {
|
|
40
|
-
filterQueries.push({ reservationNumber: { $eq: reservationNumberEq } });
|
|
41
|
-
}
|
|
42
|
-
const subReservationIdentifierEq = params.subReservation?.identifier?.$eq;
|
|
43
|
-
if (typeof subReservationIdentifierEq === 'string') {
|
|
44
|
-
filterQueries.push({ 'subReservation.identifier': { $eq: subReservationIdentifierEq } });
|
|
45
|
-
}
|
|
46
|
-
return filterQueries;
|
|
47
|
-
}
|
|
48
21
|
static offer2identifier(params, hasTicketedSeat) {
|
|
49
22
|
if (hasTicketedSeat) {
|
|
50
23
|
return `${params.seatSection}:${params.seatNumber}`;
|
|
@@ -60,34 +33,6 @@ class PendingReservationRepo {
|
|
|
60
33
|
}
|
|
61
34
|
}
|
|
62
35
|
}
|
|
63
|
-
// private static lockKey2aggregateReservation(lockKey: ILockKey): IAggregateReservation {
|
|
64
|
-
// const { eventId, startDate, holder, offers, expires, hasTicketedSeat } = lockKey;
|
|
65
|
-
// if (!(startDate instanceof Date)) {
|
|
66
|
-
// throw new factory.errors.Argument('startDate', 'must be Date');
|
|
67
|
-
// }
|
|
68
|
-
// const reservations = offers.map((offer) => {
|
|
69
|
-
// const reservationIdentifier = PendingReservationRepo.offer2identifier(offer, hasTicketedSeat);
|
|
70
|
-
// const reservationId = `${holder}:${reservationIdentifier}`;
|
|
71
|
-
// return {
|
|
72
|
-
// identifier: reservationIdentifier,
|
|
73
|
-
// reservationId
|
|
74
|
-
// };
|
|
75
|
-
// });
|
|
76
|
-
// // check uniqueness
|
|
77
|
-
// const reservationIdentifiers = reservations.map(({ identifier }) => identifier);
|
|
78
|
-
// const uniqueIdentifiers = [...new Set(reservationIdentifiers)];
|
|
79
|
-
// if (uniqueIdentifiers.length !== reservationIdentifiers.length) {
|
|
80
|
-
// throw new factory.errors.Argument('offers', 'offers must be unique');
|
|
81
|
-
// }
|
|
82
|
-
// return {
|
|
83
|
-
// project: { id: lockKey.project.id, typeOf: factory.organizationType.Project },
|
|
84
|
-
// typeOf: 'AggregateReservation',
|
|
85
|
-
// expires,
|
|
86
|
-
// reservationCount: 0,
|
|
87
|
-
// reservationFor: { id: eventId, startDate },
|
|
88
|
-
// reservationIds: reservations.map(({ reservationId }) => reservationId)
|
|
89
|
-
// };
|
|
90
|
-
// }
|
|
91
36
|
static lockKey2reservationPackage(lockKey) {
|
|
92
37
|
const { eventId, startDate, holder, offers, expires, hasTicketedSeat, bookingTime } = lockKey;
|
|
93
38
|
if (!(startDate instanceof Date)) {
|
|
@@ -108,32 +53,6 @@ class PendingReservationRepo {
|
|
|
108
53
|
subReservation
|
|
109
54
|
};
|
|
110
55
|
}
|
|
111
|
-
// public async lockIfNotLimitExceeded(lockKey: ILockKey, maximumReservationCount: number): Promise<void> {
|
|
112
|
-
// const aggregateReservation = PendingReservationRepo.lockKey2aggregateReservation(lockKey);
|
|
113
|
-
// const reservationPackage = PendingReservationRepo.lockKey2reservationPackage(lockKey);
|
|
114
|
-
// // まずcreate document
|
|
115
|
-
// await this.createIfNotExist(aggregateReservation);
|
|
116
|
-
// await this.increaseReservationCount(aggregateReservation, { maximumReservationCount });
|
|
117
|
-
// try {
|
|
118
|
-
// await this.createReservationPackageIfPossible(reservationPackage);
|
|
119
|
-
// } catch (error) {
|
|
120
|
-
// await this.decreaseReservationCountByLockKey(lockKey);
|
|
121
|
-
// throw error;
|
|
122
|
-
// }
|
|
123
|
-
// }
|
|
124
|
-
// public async lock(lockKey: ILockKey): Promise<void> {
|
|
125
|
-
// const aggregateReservation = PendingReservationRepo.lockKey2aggregateReservation(lockKey);
|
|
126
|
-
// const reservationPackage = PendingReservationRepo.lockKey2reservationPackage(lockKey);
|
|
127
|
-
// // まずcreate document
|
|
128
|
-
// await this.createIfNotExist(aggregateReservation);
|
|
129
|
-
// await this.increaseReservationCount(aggregateReservation, {});
|
|
130
|
-
// try {
|
|
131
|
-
// await this.createReservationPackageIfPossible(reservationPackage);
|
|
132
|
-
// } catch (error) {
|
|
133
|
-
// await this.decreaseReservationCountByLockKey(lockKey);
|
|
134
|
-
// throw error;
|
|
135
|
-
// }
|
|
136
|
-
// }
|
|
137
56
|
async lockIfNotLimitExceeded(lockKey, maximumReservationCount) {
|
|
138
57
|
const { eventId } = lockKey;
|
|
139
58
|
const reservationPackage = PendingReservationRepo.lockKey2reservationPackage(lockKey);
|
|
@@ -173,33 +92,9 @@ class PendingReservationRepo {
|
|
|
173
92
|
const reservationPackage = PendingReservationRepo.lockKey2reservationPackage(lockKey);
|
|
174
93
|
await this.createReservationPackageIfPossible(reservationPackage);
|
|
175
94
|
}
|
|
176
|
-
// public async unlock(params: IUnlockKey): Promise<void> {
|
|
177
|
-
// await this.decreaseReservationCount(params);
|
|
178
|
-
// await this.deleteReservationIfExists(params);
|
|
179
|
-
// }
|
|
180
95
|
async unlock(params) {
|
|
181
96
|
await this.deleteReservationIfExists(params);
|
|
182
97
|
}
|
|
183
|
-
// public async countUnavailableOffers(params: {
|
|
184
|
-
// event: {
|
|
185
|
-
// id: string;
|
|
186
|
-
// startDate: Date;
|
|
187
|
-
// hasTicketedSeat: boolean;
|
|
188
|
-
// };
|
|
189
|
-
// }): Promise<number> {
|
|
190
|
-
// const { event } = params;
|
|
191
|
-
// const doc = await this.aggregateReservationModel.findOne(
|
|
192
|
-
// { 'reservationFor.id': { $eq: event.id } },
|
|
193
|
-
// {
|
|
194
|
-
// _id: 0,
|
|
195
|
-
// reservationCount: 1
|
|
196
|
-
// }
|
|
197
|
-
// )
|
|
198
|
-
// .setOptions({ maxTimeMS: MONGO_MAX_TIME_MS })
|
|
199
|
-
// .lean<Pick<IAggregateReservation, 'reservationCount'>>()
|
|
200
|
-
// .exec();
|
|
201
|
-
// return (doc !== null) ? doc.reservationCount : 0;
|
|
202
|
-
// }
|
|
203
98
|
/**
|
|
204
99
|
* 現時点での保留予約数を集計する
|
|
205
100
|
*/
|
|
@@ -316,86 +211,30 @@ class PendingReservationRepo {
|
|
|
316
211
|
// .option({ maxTimeMS: MONGO_MAX_TIME_MS })
|
|
317
212
|
// .exec();
|
|
318
213
|
// }
|
|
319
|
-
async docExists(params
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
limitStage = { $limit: limit };
|
|
344
|
-
}
|
|
345
|
-
const projectStage = {
|
|
346
|
-
$project: {
|
|
347
|
-
_id: 0,
|
|
348
|
-
typeOf: '$typeOf',
|
|
349
|
-
bookingTime: '$bookingTime',
|
|
350
|
-
dateCreated: '$dateCreated',
|
|
351
|
-
dateModified: '$dateModified',
|
|
352
|
-
expires: '$expires',
|
|
353
|
-
numSeats: '$numSeats',
|
|
354
|
-
reservationFor: '$reservationFor',
|
|
355
|
-
reservationNumber: '$reservationNumber',
|
|
356
|
-
subReservationCount: { $size: '$subReservation' }
|
|
357
|
-
}
|
|
358
|
-
};
|
|
359
|
-
const pipeline = [
|
|
360
|
-
...(matchStage !== undefined) ? [matchStage] : [],
|
|
361
|
-
{ $sort: { bookingTime: factory_1.factory.sortType.Descending } },
|
|
362
|
-
...(skipStage !== undefined) ? [skipStage] : [],
|
|
363
|
-
...(limitStage !== undefined) ? [limitStage] : [],
|
|
364
|
-
projectStage
|
|
365
|
-
];
|
|
366
|
-
return this.pendingReservationModel.aggregate(pipeline)
|
|
367
|
-
.option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
368
|
-
.exec();
|
|
369
|
-
}
|
|
370
|
-
async projectSubReservationByReservationNumber(params) {
|
|
371
|
-
const matchStage = {
|
|
372
|
-
$match: {
|
|
373
|
-
'project.id': { $eq: params.project.id.$eq },
|
|
374
|
-
reservationNumber: { $eq: params.reservationNumber.$eq }
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
const projectStage = {
|
|
378
|
-
$project: {
|
|
379
|
-
_id: 0,
|
|
380
|
-
identifier: '$subReservation.identifier',
|
|
381
|
-
index: `$reservationIndex`
|
|
382
|
-
}
|
|
383
|
-
};
|
|
384
|
-
const unwindStage = {
|
|
385
|
-
$unwind: {
|
|
386
|
-
path: '$subReservation',
|
|
387
|
-
includeArrayIndex: 'reservationIndex'
|
|
388
|
-
}
|
|
389
|
-
};
|
|
390
|
-
const pipeline = [
|
|
391
|
-
matchStage,
|
|
392
|
-
unwindStage,
|
|
393
|
-
projectStage
|
|
394
|
-
];
|
|
395
|
-
return this.pendingReservationModel.aggregate(pipeline)
|
|
396
|
-
.option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
397
|
-
.exec();
|
|
398
|
-
}
|
|
214
|
+
// public async docExists(params: {
|
|
215
|
+
// eventId: string;
|
|
216
|
+
// }): Promise<boolean> {
|
|
217
|
+
// const { eventId } = params;
|
|
218
|
+
// const doc = await this.pendingReservationModel.findOne(
|
|
219
|
+
// { 'reservationFor.id': { $eq: eventId } },
|
|
220
|
+
// { _id: 0, typeOf: 1 }
|
|
221
|
+
// )
|
|
222
|
+
// .setOptions({ maxTimeMS: MONGO_MAX_TIME_MS })
|
|
223
|
+
// .lean<Pick<IReservationPackage, 'typeOf'>>()
|
|
224
|
+
// .exec();
|
|
225
|
+
// return doc !== null;
|
|
226
|
+
// }
|
|
227
|
+
// public async deleteExpiredMany(params: {
|
|
228
|
+
// expires: {
|
|
229
|
+
// $lte: Date;
|
|
230
|
+
// };
|
|
231
|
+
// }) {
|
|
232
|
+
// const { expires } = params;
|
|
233
|
+
// return this.pendingReservationModel.deleteMany({
|
|
234
|
+
// expires: { $lte: expires.$lte }
|
|
235
|
+
// })
|
|
236
|
+
// .exec();
|
|
237
|
+
// }
|
|
399
238
|
/**
|
|
400
239
|
* expiresを最新の情報に同期する
|
|
401
240
|
*/
|
|
@@ -493,64 +332,6 @@ class PendingReservationRepo {
|
|
|
493
332
|
await this.pendingReservationModel.deleteOne({ reservationNumber: { $eq: reservationNumber } })
|
|
494
333
|
.exec();
|
|
495
334
|
}
|
|
496
|
-
// private async decreaseReservationCountByLockKey(
|
|
497
|
-
// lockKey: ILockKey
|
|
498
|
-
// ): Promise<void> {
|
|
499
|
-
// const { project, eventId, startDate, offers, hasTicketedSeat, holder } = lockKey;
|
|
500
|
-
// for (const offer of offers) {
|
|
501
|
-
// await this.decreaseReservationCount({
|
|
502
|
-
// project: { id: project.id },
|
|
503
|
-
// eventId,
|
|
504
|
-
// startDate,
|
|
505
|
-
// hasTicketedSeat,
|
|
506
|
-
// offer,
|
|
507
|
-
// holder
|
|
508
|
-
// });
|
|
509
|
-
// }
|
|
510
|
-
// }
|
|
511
|
-
// private async increaseReservationCount(
|
|
512
|
-
// aggregateReservation: IAggregateReservation,
|
|
513
|
-
// options: {
|
|
514
|
-
// maximumReservationCount?: number;
|
|
515
|
-
// }
|
|
516
|
-
// ): Promise<void> {
|
|
517
|
-
// const { maximumReservationCount } = options;
|
|
518
|
-
// const newReservationCount = aggregateReservation.reservationIds.length;
|
|
519
|
-
// let reservationCountLte: number | undefined;
|
|
520
|
-
// if (typeof maximumReservationCount === 'number') {
|
|
521
|
-
// reservationCountLte = maximumReservationCount - newReservationCount;
|
|
522
|
-
// if (reservationCountLte < 0) {
|
|
523
|
-
// throw new factory.errors.Argument('Event', 'maximumAttendeeCapacity exceeded');
|
|
524
|
-
// }
|
|
525
|
-
// }
|
|
526
|
-
// const doc = await this.aggregateReservationModel.findOneAndUpdate(
|
|
527
|
-
// {
|
|
528
|
-
// 'reservationFor.id': { $eq: aggregateReservation.reservationFor.id },
|
|
529
|
-
// // 'reservations.identifier': { $nin: reservationIdentifiers }, // pendingReservationsで重複回避済の前提で実行される
|
|
530
|
-
// ...(typeof reservationCountLte === 'number')
|
|
531
|
-
// ? { reservationCount: { $lte: reservationCountLte } }
|
|
532
|
-
// : undefined
|
|
533
|
-
// // : { reservationCount: { $exists: true } } // 必ず条件内になるように
|
|
534
|
-
// },
|
|
535
|
-
// {
|
|
536
|
-
// $inc: { reservationCount: newReservationCount },
|
|
537
|
-
// $push: {
|
|
538
|
-
// reservationIds: { $each: aggregateReservation.reservationIds }
|
|
539
|
-
// },
|
|
540
|
-
// $set: { expires: aggregateReservation.expires }
|
|
541
|
-
// },
|
|
542
|
-
// {
|
|
543
|
-
// new: false, // trueである必要はない
|
|
544
|
-
// projection: { typeOf: 1 }
|
|
545
|
-
// }
|
|
546
|
-
// )
|
|
547
|
-
// .setOptions({ maxTimeMS: MONGO_MAX_TIME_MS })
|
|
548
|
-
// .lean<Pick<IAggregateReservation, 'typeOf'>>()
|
|
549
|
-
// .exec();
|
|
550
|
-
// if (doc === null) {
|
|
551
|
-
// throw new factory.errors.Argument('Event', 'maximumAttendeeCapacity exceeded');
|
|
552
|
-
// }
|
|
553
|
-
// }
|
|
554
335
|
async deleteReservationIfExists(params) {
|
|
555
336
|
const { eventId, offer, hasTicketedSeat, holder } = params;
|
|
556
337
|
const reservationIdentifier = PendingReservationRepo.offer2identifier(offer, hasTicketedSeat);
|
|
@@ -17,18 +17,7 @@ class StockHolderRepo {
|
|
|
17
17
|
* 座席をロックする(maxキャパシティチェック有)
|
|
18
18
|
*/
|
|
19
19
|
async lockIfNotLimitExceeded(lockKey, maximum) {
|
|
20
|
-
|
|
21
|
-
project: { id: lockKey.project.id },
|
|
22
|
-
eventId: lockKey.eventId,
|
|
23
|
-
startDate: lockKey.startDate,
|
|
24
|
-
hasTicketedSeat: lockKey.hasTicketedSeat
|
|
25
|
-
});
|
|
26
|
-
if (useMongoose) {
|
|
27
|
-
return this.pendingReservationRepo.lockIfNotLimitExceeded(lockKey, maximum);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
throw new factory_1.factory.errors.NotImplemented('useRedis discontinued.');
|
|
31
|
-
}
|
|
20
|
+
return this.pendingReservationRepo.lockIfNotLimitExceeded(lockKey, maximum);
|
|
32
21
|
}
|
|
33
22
|
/**
|
|
34
23
|
* 座席をロックする
|
|
@@ -37,94 +26,32 @@ class StockHolderRepo {
|
|
|
37
26
|
if (!(lockKey.expires instanceof Date)) {
|
|
38
27
|
throw new factory_1.factory.errors.Argument('expires', 'must be Date');
|
|
39
28
|
}
|
|
40
|
-
|
|
41
|
-
project: { id: lockKey.project.id },
|
|
42
|
-
eventId: lockKey.eventId,
|
|
43
|
-
startDate: lockKey.startDate,
|
|
44
|
-
hasTicketedSeat: lockKey.hasTicketedSeat
|
|
45
|
-
});
|
|
46
|
-
if (useMongoose) {
|
|
47
|
-
return this.pendingReservationRepo.lock(lockKey);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
throw new factory_1.factory.errors.NotImplemented('useRedis discontinued.');
|
|
51
|
-
}
|
|
29
|
+
return this.pendingReservationRepo.lock(lockKey);
|
|
52
30
|
}
|
|
53
31
|
/**
|
|
54
32
|
* 座席ロックを解除する
|
|
55
33
|
*/
|
|
56
34
|
async unlock(params) {
|
|
57
|
-
|
|
58
|
-
project: { id: params.project.id },
|
|
59
|
-
eventId: params.eventId,
|
|
60
|
-
startDate: params.startDate,
|
|
61
|
-
hasTicketedSeat: params.hasTicketedSeat
|
|
62
|
-
});
|
|
63
|
-
if (useMongoose) {
|
|
64
|
-
return this.pendingReservationRepo.unlock(params);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
throw new factory_1.factory.errors.NotImplemented('useRedis discontinued.');
|
|
68
|
-
}
|
|
35
|
+
return this.pendingReservationRepo.unlock(params);
|
|
69
36
|
}
|
|
70
37
|
/**
|
|
71
38
|
* 空席でない座席をカウントする
|
|
72
39
|
*/
|
|
73
40
|
async countUnavailableOffers(params) {
|
|
74
|
-
|
|
75
|
-
project: { id: params.project.id },
|
|
76
|
-
eventId: params.event.id,
|
|
77
|
-
startDate: params.event.startDate,
|
|
78
|
-
hasTicketedSeat: params.event.hasTicketedSeat
|
|
79
|
-
})) {
|
|
80
|
-
return this.pendingReservationRepo.countUnavailableOffers(params);
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
throw new factory_1.factory.errors.NotImplemented('useRedis discontinued.');
|
|
84
|
-
}
|
|
41
|
+
return this.pendingReservationRepo.countUnavailableOffers(params);
|
|
85
42
|
}
|
|
86
43
|
/**
|
|
87
44
|
* 保持者を取得する
|
|
88
45
|
*/
|
|
89
46
|
async getHolder(params) {
|
|
90
|
-
|
|
91
|
-
project: { id: params.project.id },
|
|
92
|
-
eventId: params.eventId,
|
|
93
|
-
startDate: params.startDate,
|
|
94
|
-
hasTicketedSeat: params.hasTicketedSeat
|
|
95
|
-
})) {
|
|
96
|
-
return this.pendingReservationRepo.getHolder(params);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
throw new factory_1.factory.errors.NotImplemented('useRedis discontinued.');
|
|
100
|
-
}
|
|
47
|
+
return this.pendingReservationRepo.getHolder(params);
|
|
101
48
|
}
|
|
102
49
|
async searchHolders(params) {
|
|
103
50
|
// validate offers.length(2025-04-18~)
|
|
104
51
|
if (params.offers.length > SEARCH_OFFERS_MAX_LENGTH) {
|
|
105
52
|
throw new factory_1.factory.errors.Argument('offers', `offers.length must be <= ${SEARCH_OFFERS_MAX_LENGTH}`);
|
|
106
53
|
}
|
|
107
|
-
|
|
108
|
-
project: { id: params.project.id },
|
|
109
|
-
eventId: params.eventId,
|
|
110
|
-
startDate: params.startDate,
|
|
111
|
-
hasTicketedSeat: params.hasTicketedSeat
|
|
112
|
-
})) {
|
|
113
|
-
return this.pendingReservationRepo.searchHolders(params);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
throw new factory_1.factory.errors.NotImplemented('useRedis discontinued.');
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* 新リポジトリを使用するかどうか
|
|
121
|
-
*/
|
|
122
|
-
useMongoose(params) {
|
|
123
|
-
if (!(params.startDate instanceof Date)) {
|
|
124
|
-
throw new factory_1.factory.errors.Argument('startDate', 'must be Date');
|
|
125
|
-
}
|
|
126
|
-
// always use mongo(2025-08-17~)
|
|
127
|
-
return true;
|
|
54
|
+
return this.pendingReservationRepo.searchHolders(params);
|
|
128
55
|
}
|
|
129
56
|
}
|
|
130
57
|
exports.StockHolderRepo = StockHolderRepo;
|
|
@@ -26,6 +26,7 @@ import type { AdminActionRepo } from './repo/adminAction';
|
|
|
26
26
|
import type { AdminAssetTransactionRepo } from './repo/adminAssetTransaction';
|
|
27
27
|
import type { AdminCheckMovieTicketActionRepo } from './repo/adminCheckMovieTicketAction';
|
|
28
28
|
import type { AdminAsyncActionRepo } from './repo/adminAsyncAction';
|
|
29
|
+
import type { AdminPendingReservationRepo } from './repo/adminPendingReservation';
|
|
29
30
|
import type { AdminScheduledTaskRepo } from './repo/adminScheduledTask';
|
|
30
31
|
import type { AdminTaskRepo } from './repo/adminTask';
|
|
31
32
|
import type { AdminTransactionRepo } from './repo/adminTransaction';
|
|
@@ -214,6 +215,10 @@ export type AdminAsyncAction = AdminAsyncActionRepo;
|
|
|
214
215
|
export declare namespace AdminAsyncAction {
|
|
215
216
|
function createInstance(...params: ConstructorParameters<typeof AdminAsyncActionRepo>): Promise<AdminAsyncActionRepo>;
|
|
216
217
|
}
|
|
218
|
+
export type AdminPendingReservation = AdminPendingReservationRepo;
|
|
219
|
+
export declare namespace AdminPendingReservation {
|
|
220
|
+
function createInstance(...params: ConstructorParameters<typeof AdminPendingReservationRepo>): Promise<AdminPendingReservationRepo>;
|
|
221
|
+
}
|
|
217
222
|
export type AdminScheduledTask = AdminScheduledTaskRepo;
|
|
218
223
|
export declare namespace AdminScheduledTask {
|
|
219
224
|
function createInstance(...params: ConstructorParameters<typeof AdminScheduledTaskRepo>): Promise<AdminScheduledTaskRepo>;
|
package/lib/chevre/repository.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.WebSite = exports.rateLimit = exports.TransactionProcess = exports.TransactionNumber = exports.transaction = exports.Transaction = exports.Ticket = exports.AsyncAction = exports.TaskDelayed = exports.Task = exports.ScheduledTask = exports.StockHolder = exports.setting = exports.Setting = exports.ServiceAvailableHour = exports.SellerReturnPolicy = exports.SellerPaymentAccepted = exports.SellerMakesOffer = exports.Seller = exports.Schedule = exports.Role = exports.ReserveInterface = exports.Reservation = exports.ProjectMakesOffer = exports.Project = exports.ProductHasOfferCatalog = exports.Product = exports.PriceSpecification = exports.PotentialAction = exports.place = exports.Person = exports.PendingReservation = exports.PaymentServiceProvider = exports.PaymentServiceChannel = exports.PaymentService = exports.Passport = exports.OrderNumber = exports.OrderInTransaction = exports.Order = exports.Offer = exports.OfferItemCondition = void 0;
|
|
3
|
+
exports.OfferCatalog = exports.NoteAboutOrder = exports.Note = exports.MovieTicketType = exports.Message = exports.MerchantReturnPolicy = exports.MemberProgram = exports.Member = exports.Issuer = exports.IdentityProvider = exports.Identity = exports.EventSeries = exports.EventSellerMakesOffer = exports.EventOffer = exports.Event = exports.EmailMessage = exports.CustomerType = exports.Customer = exports.Credentials = exports.CreativeWork = exports.ConfirmationNumber = exports.Authorization = exports.CategoryCode = exports.assetTransaction = exports.AssetTransaction = exports.Aggregation = exports.AggregateReservation = exports.AggregateOrder = exports.AggregateOffer = exports.AggregateAssetTransaction = exports.AggregateTransaction = exports.AggregateTask = exports.AggregateScheduledTask = exports.AggregateUseAction = exports.AggregateCheckMovieTicketAction = exports.AggregateAction = exports.AdminTransaction = exports.AdminTask = exports.AdminScheduledTask = exports.AdminPendingReservation = exports.AdminAsyncAction = exports.AdminAssetTransaction = exports.AdminCheckMovieTicketAction = exports.AdminAction = exports.AdminAccountingReport = exports.AdditionalProperty = exports.action = exports.AccountTitle = exports.AccountingReport = exports.AcceptedOffer = void 0;
|
|
4
|
+
exports.WebSite = exports.rateLimit = exports.TransactionProcess = exports.TransactionNumber = exports.transaction = exports.Transaction = exports.Ticket = exports.AsyncAction = exports.TaskDelayed = exports.Task = exports.ScheduledTask = exports.StockHolder = exports.setting = exports.Setting = exports.ServiceAvailableHour = exports.SellerReturnPolicy = exports.SellerPaymentAccepted = exports.SellerMakesOffer = exports.Seller = exports.Schedule = exports.Role = exports.ReserveInterface = exports.Reservation = exports.ProjectMakesOffer = exports.Project = exports.ProductHasOfferCatalog = exports.Product = exports.PriceSpecification = exports.PotentialAction = exports.place = exports.Person = exports.PendingReservation = exports.PaymentServiceProvider = exports.PaymentServiceChannel = exports.PaymentService = exports.Passport = exports.OrderNumber = exports.OrderInTransaction = exports.Order = exports.Offer = exports.OfferItemCondition = exports.OfferCatalogItem = void 0;
|
|
5
5
|
var AcceptedOffer;
|
|
6
6
|
(function (AcceptedOffer) {
|
|
7
7
|
let repo;
|
|
@@ -269,6 +269,17 @@ var AdminAsyncAction;
|
|
|
269
269
|
}
|
|
270
270
|
AdminAsyncAction.createInstance = createInstance;
|
|
271
271
|
})(AdminAsyncAction || (exports.AdminAsyncAction = AdminAsyncAction = {}));
|
|
272
|
+
var AdminPendingReservation;
|
|
273
|
+
(function (AdminPendingReservation) {
|
|
274
|
+
let repo;
|
|
275
|
+
async function createInstance(...params) {
|
|
276
|
+
if (repo === undefined) {
|
|
277
|
+
repo = (await import('./repo/adminPendingReservation.js')).AdminPendingReservationRepo;
|
|
278
|
+
}
|
|
279
|
+
return new repo(...params);
|
|
280
|
+
}
|
|
281
|
+
AdminPendingReservation.createInstance = createInstance;
|
|
282
|
+
})(AdminPendingReservation || (exports.AdminPendingReservation = AdminPendingReservation = {}));
|
|
272
283
|
var AdminScheduledTask;
|
|
273
284
|
(function (AdminScheduledTask) {
|
|
274
285
|
let repo;
|
package/package.json
CHANGED