@chevre/domain 22.13.0-alpha.5 → 22.13.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.
@@ -0,0 +1,386 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.schedule2events = schedule2events;
13
+ const createDebug = require("debug");
14
+ const moment = require("moment-timezone");
15
+ const factory = require("../../../../factory");
16
+ // import { Settings } from '../../../settings';
17
+ const debug = createDebug('chevre-domain:service:task');
18
+ // tslint:disable-next-line:max-func-body-length
19
+ // function schedule2createEventParams(
20
+ // schedule: factory.schedule.IEventWithSchedule,
21
+ // createDate: Date
22
+ // ): factory.event.screeningEvent.ICreateParams[] {
23
+ // const eventServiceId = schedule.offers?.itemOffered?.id;
24
+ // const makesOffer = schedule.offers?.seller?.makesOffer;
25
+ // const applicationIds: string[] = (Array.isArray(makesOffer))
26
+ // ? makesOffer.map(({ availableAtOrFrom }) => availableAtOrFrom.id)
27
+ // : [];
28
+ // const eventSeriesId = schedule.superEvent?.id;
29
+ // if (typeof eventServiceId !== 'string' || eventServiceId === '') {
30
+ // throw new factory.errors.NotFound('schedule.offers.itemOffered.id');
31
+ // }
32
+ // if (typeof eventSeriesId !== 'string' || eventSeriesId === '') {
33
+ // throw new factory.errors.NotFound('schedule.superEvent.id');
34
+ // }
35
+ // // 引数情報取得
36
+ // if (schedule.eventSchedule === undefined) {
37
+ // throw new factory.errors.NotFound('eventSchedule');
38
+ // }
39
+ // const targetInfo = getTargetInfoByEventWithSchedule(schedule, createDate);
40
+ // debug(targetInfo.length, 'targetInfos ->', targetInfo);
41
+ // const createParams: factory.event.screeningEvent.ICreateParams[] = [];
42
+ // for (const performanceInfo of targetInfo) {
43
+ // const oldEventId = [
44
+ // // tslint:disable-next-line:no-magic-numbers
45
+ // performanceInfo.day.slice(-6),
46
+ // workPerformedIdentifier,
47
+ // movieTheater.branchCode,
48
+ // screeningRoom.branchCode,
49
+ // performanceInfo.start_time
50
+ // ].join('');
51
+ // const maxValue = movieTheater.offers?.eligibleQuantity?.maxValue;
52
+ // const availabilityEnds: Date = moment(performanceInfo.end_date)
53
+ // .tz('Asia/Tokyo')
54
+ // .endOf('date')
55
+ // .toDate();
56
+ // const availabilityStarts: Date = moment(performanceInfo.start_date)
57
+ // .tz('Asia/Tokyo')
58
+ // .startOf('date')
59
+ // // tslint:disable-next-line:no-magic-numbers
60
+ // .add(-3, 'months')
61
+ // .toDate();
62
+ // const validThrough: Date = moment(performanceInfo.end_date)
63
+ // .tz('Asia/Tokyo')
64
+ // .endOf('date')
65
+ // .toDate();
66
+ // const validFrom: Date = moment(performanceInfo.start_date)
67
+ // .tz('Asia/Tokyo')
68
+ // .startOf('date')
69
+ // // tslint:disable-next-line:no-magic-numbers
70
+ // .add(-3, 'months')
71
+ // .toDate();
72
+ // // イベント作成
73
+ // createParams.push({
74
+ // eventStatus: factory.eventStatusType.EventScheduled,
75
+ // doorTime: performanceInfo.door_time,
76
+ // startDate: performanceInfo.start_date,
77
+ // endDate: performanceInfo.end_date,
78
+ // offers: {
79
+ // eligibleQuantity: {
80
+ // ...(typeof maxValue === 'number') ? { maxValue } : undefined // ひとまず全座席予約可能なように
81
+ // },
82
+ // itemOffered: {
83
+ // // 興行ID追加(2022-09-01~)
84
+ // id: eventServiceId,
85
+ // serviceOutput: {
86
+ // typeOf: factory.reservationType.EventReservation,
87
+ // reservedTicket: {
88
+ // typeOf: 'Ticket',
89
+ // ticketedSeat: { typeOf: factory.placeType.Seat }
90
+ // }
91
+ // },
92
+ // },
93
+ // seller: {
94
+ // // event.offersにseller.makesOfferを追加(2022-11-18~)
95
+ // makesOffer: applicationIds.map((applicationId) => {
96
+ // return {
97
+ // typeOf: factory.offerType.Offer,
98
+ // availableAtOrFrom: { id: applicationId }, // support no-array(2024-10-13~),
99
+ // availabilityEnds,
100
+ // availabilityStarts,
101
+ // validFrom,
102
+ // validThrough
103
+ // };
104
+ // })
105
+ // }
106
+ // },
107
+ // // 旧フォーマットIDを追加特性に追加(2022-09-08~)
108
+ // additionalProperty: [
109
+ // { name: 'tourNumber', value: String(performanceInfo.tour_number) },
110
+ // { name: 'oldEventId', value: oldEventId }
111
+ // ],
112
+ // identifier: oldEventId
113
+ // });
114
+ // }
115
+ // return createParams;
116
+ // }
117
+ function schedule2events(schedule, createDate) {
118
+ // tslint:disable-next-line:cyclomatic-complexity max-func-body-length
119
+ return (repos) => __awaiter(this, void 0, void 0, function* () {
120
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
121
+ debug('schedule2events processing...', JSON.stringify(schedule), createDate);
122
+ const eventServiceId = (_b = (_a = schedule.offers) === null || _a === void 0 ? void 0 : _a.itemOffered) === null || _b === void 0 ? void 0 : _b.id;
123
+ const makesOffer = (_d = (_c = schedule.offers) === null || _c === void 0 ? void 0 : _c.seller) === null || _d === void 0 ? void 0 : _d.makesOffer;
124
+ const applicationIds = (Array.isArray(makesOffer))
125
+ ? makesOffer.map(({ availableAtOrFrom }) => availableAtOrFrom.id)
126
+ : [];
127
+ const eventSeriesId = (_e = schedule.superEvent) === null || _e === void 0 ? void 0 : _e.id;
128
+ const maxValue = (_g = (_f = schedule.offers) === null || _f === void 0 ? void 0 : _f.eligibleQuantity) === null || _g === void 0 ? void 0 : _g.maxValue;
129
+ const locationBranchCode = (_h = schedule.location) === null || _h === void 0 ? void 0 : _h.branchCode;
130
+ if (typeof eventServiceId !== 'string' || eventServiceId === '') {
131
+ throw new factory.errors.NotFound('schedule.offers.itemOffered.id required');
132
+ }
133
+ if (typeof eventSeriesId !== 'string' || eventSeriesId === '') {
134
+ throw new factory.errors.NotFound('schedule.superEvent.id required');
135
+ }
136
+ if (typeof maxValue !== 'number') {
137
+ throw new factory.errors.NotFound('schedule.offers.eligibleQuantity.maxValue required');
138
+ }
139
+ if (typeof locationBranchCode !== 'string' || locationBranchCode === '') {
140
+ throw new factory.errors.NotFound('location.branchCode required');
141
+ }
142
+ const project = schedule.project;
143
+ // 引数情報取得
144
+ if (schedule.eventSchedule === undefined) {
145
+ throw new factory.errors.NotFound('schedule.eventSchedule required');
146
+ }
147
+ const targetInfo = getTargetInfoByEventWithSchedule(schedule, createDate);
148
+ debug(targetInfo.length, 'targetInfos ->', targetInfo);
149
+ // fs.writeFileSync(
150
+ // `${__dirname}/../../../../../targetInfo_${schedule.eventSchedule?.typeOf}.json`,
151
+ // JSON.stringify(targetInfo, null, ' ')
152
+ // );
153
+ // return;
154
+ // 施設コンテンツ検索
155
+ const screeningEventSeries = (yield repos.eventSeries.projectEventSeriesFields({
156
+ project: { id: { $eq: project.id } },
157
+ id: { $eq: eventSeriesId }
158
+ }, [
159
+ 'location', 'additionalProperty', 'description', 'endDate', 'headline', 'kanaName', 'name',
160
+ 'soundFormat', 'startDate', 'typeOf', 'videoFormat', 'workPerformed'
161
+ ])).shift();
162
+ if (screeningEventSeries === undefined) {
163
+ throw new factory.errors.NotFound(factory.eventType.ScreeningEventSeries);
164
+ }
165
+ const workPerformedIdentifier = screeningEventSeries.workPerformed.identifier;
166
+ // 劇場検索
167
+ const movieTheater = (yield repos.movieTheater.projectFields({
168
+ limit: 1,
169
+ page: 1,
170
+ project: { id: { $eq: project.id } },
171
+ branchCode: { $eq: screeningEventSeries.location.branchCode }
172
+ }, ['id', 'branchCode', 'parentOrganization'])).shift();
173
+ if (movieTheater === undefined) {
174
+ throw new factory.errors.NotFound(factory.placeType.MovieTheater);
175
+ }
176
+ const seller = movieTheater.parentOrganization;
177
+ const screeningRoom = (yield repos.screeningRoom.searchScreeningRooms({
178
+ limit: 1,
179
+ page: 1,
180
+ project: { id: { $eq: project.id } },
181
+ containedInPlace: { id: { $eq: movieTheater.id } },
182
+ branchCode: { $eq: locationBranchCode }
183
+ })).shift();
184
+ if (screeningRoom === undefined) {
185
+ throw new factory.errors.NotFound(factory.placeType.ScreeningRoom, `${factory.placeType.ScreeningRoom} ${locationBranchCode} not found`);
186
+ }
187
+ // 興行検索
188
+ const eventService = (yield repos.product.projectFields({
189
+ limit: 1,
190
+ page: 1,
191
+ project: { id: { $eq: project.id } },
192
+ id: { $eq: eventServiceId }
193
+ // productID: { $eq: eventServiceProductID }
194
+ }, ['name'])).shift();
195
+ if (typeof (eventService === null || eventService === void 0 ? void 0 : eventService.id) !== 'string') {
196
+ throw new Error(`EventService ${eventServiceId} not found`);
197
+ }
198
+ let existingApplicationMembers = [];
199
+ if (applicationIds.length > 0) {
200
+ existingApplicationMembers = yield repos.member.searchCustomerMembers({
201
+ limit: 100,
202
+ page: 1,
203
+ project: { id: project.id },
204
+ member: {
205
+ // typeOf: {
206
+ // $eq: factory.creativeWorkType.WebApplication
207
+ // },
208
+ id: { $in: applicationIds }
209
+ }
210
+ });
211
+ }
212
+ // ロールで絞る(customer or pos)
213
+ // existingApplicationMembers = existingApplicationMembers
214
+ // .filter((m) => {
215
+ // return Array.isArray(m.member.hasRole) && m.member.hasRole.some((r) => AVAILABLE_ROLE_NAMES.includes(r.roleName));
216
+ // });
217
+ const creatingEvents = [];
218
+ for (const performanceInfo of targetInfo) {
219
+ const oldEventId = [
220
+ // tslint:disable-next-line:no-magic-numbers
221
+ performanceInfo.day.slice(-6),
222
+ workPerformedIdentifier,
223
+ movieTheater.branchCode,
224
+ screeningRoom.branchCode,
225
+ performanceInfo.start_time
226
+ ].join('');
227
+ // const maxValue = movieTheater.offers?.eligibleQuantity?.maxValue;
228
+ const availabilityEnds = moment(performanceInfo.end_date)
229
+ .tz('Asia/Tokyo')
230
+ .endOf('date')
231
+ .toDate();
232
+ const availabilityStarts = moment(performanceInfo.start_date)
233
+ .tz('Asia/Tokyo')
234
+ .startOf('date')
235
+ // tslint:disable-next-line:no-magic-numbers
236
+ .add(-3, 'months')
237
+ .toDate();
238
+ const validThrough = moment(performanceInfo.end_date)
239
+ .tz('Asia/Tokyo')
240
+ .endOf('date')
241
+ .toDate();
242
+ const validFrom = moment(performanceInfo.start_date)
243
+ .tz('Asia/Tokyo')
244
+ .startOf('date')
245
+ // tslint:disable-next-line:no-magic-numbers
246
+ .add(-3, 'months')
247
+ .toDate();
248
+ const offersSeller = {
249
+ typeOf: factory.organizationType.Corporation,
250
+ id: String(seller === null || seller === void 0 ? void 0 : seller.id),
251
+ // event.offersにseller.makesOfferを追加(2022-11-18~)
252
+ makesOffer: existingApplicationMembers.map((a) => {
253
+ return {
254
+ typeOf: factory.offerType.Offer,
255
+ availableAtOrFrom: { id: a.member.id }, // support no-array(2024-10-13~),
256
+ availabilityEnds,
257
+ availabilityStarts,
258
+ validFrom,
259
+ validThrough
260
+ };
261
+ })
262
+ };
263
+ const offers = {
264
+ typeOf: factory.offerType.Offer,
265
+ eligibleQuantity: {
266
+ typeOf: 'QuantitativeValue',
267
+ unitCode: factory.unitCode.C62,
268
+ maxValue
269
+ },
270
+ itemOffered: Object.assign({
271
+ // 興行ID追加(2022-09-01~)
272
+ id: eventService.id, serviceOutput: {
273
+ typeOf: factory.reservationType.EventReservation,
274
+ reservedTicket: {
275
+ typeOf: 'Ticket',
276
+ ticketedSeat: { typeOf: factory.placeType.Seat }
277
+ }
278
+ }, typeOf: factory.product.ProductType.EventService, availableChannel: {
279
+ typeOf: 'ServiceChannel',
280
+ serviceLocation: {
281
+ typeOf: screeningRoom.typeOf,
282
+ branchCode: screeningRoom.branchCode,
283
+ name: screeningRoom.name,
284
+ containedInPlace: Object.assign({ typeOf: screeningEventSeries.location.typeOf, id: screeningEventSeries.location.id, branchCode: screeningEventSeries.location.branchCode }, (screeningEventSeries.location.name !== undefined)
285
+ ? { name: screeningEventSeries.location.name }
286
+ : undefined)
287
+ }
288
+ } }, { name: { ja: (typeof eventService.name === 'string') ? eventService.name : String((_j = eventService.name) === null || _j === void 0 ? void 0 : _j.ja) } }),
289
+ seller: offersSeller
290
+ };
291
+ const screeningEventSuperEvent = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ typeOf: screeningEventSeries.typeOf, id: screeningEventSeries.id, videoFormat: screeningEventSeries.videoFormat, soundFormat: screeningEventSeries.soundFormat, workPerformed: screeningEventSeries.workPerformed, location: screeningEventSeries.location, kanaName: screeningEventSeries.kanaName, name: screeningEventSeries.name }, (Array.isArray(screeningEventSeries.additionalProperty))
292
+ ? { additionalProperty: screeningEventSeries.additionalProperty }
293
+ : undefined), (screeningEventSeries.startDate !== undefined)
294
+ ? { startDate: screeningEventSeries.startDate }
295
+ : undefined), (screeningEventSeries.endDate !== undefined)
296
+ ? { endDate: screeningEventSeries.endDate }
297
+ : undefined), (screeningEventSeries.description !== undefined)
298
+ ? { description: screeningEventSeries.description }
299
+ : undefined), (screeningEventSeries.headline !== undefined)
300
+ ? { headline: screeningEventSeries.headline }
301
+ : undefined);
302
+ // イベント作成
303
+ creatingEvents.push({
304
+ project: { id: project.id, typeOf: factory.organizationType.Project },
305
+ typeOf: factory.eventType.ScreeningEvent,
306
+ eventStatus: factory.eventStatusType.EventScheduled,
307
+ name: screeningEventSeries.name,
308
+ doorTime: performanceInfo.door_time,
309
+ startDate: performanceInfo.start_date,
310
+ endDate: performanceInfo.end_date,
311
+ superEvent: screeningEventSuperEvent,
312
+ location: Object.assign({ typeOf: screeningRoom.typeOf, branchCode: screeningRoom.branchCode, name: screeningRoom.name }, (screeningRoom.address !== undefined) ? { address: screeningRoom.address } : undefined),
313
+ offers: offers,
314
+ // 旧フォーマットIDを追加特性に追加(2022-09-08~)
315
+ additionalProperty: [
316
+ { name: 'tourNumber', value: String(performanceInfo.tour_number) },
317
+ { name: 'oldEventId', value: oldEventId }
318
+ ],
319
+ // organizer追加(2023-07-12~)
320
+ organizer: { id: seller.id },
321
+ identifier: oldEventId
322
+ });
323
+ }
324
+ return creatingEvents;
325
+ });
326
+ }
327
+ function getTargetInfoByEventWithSchedule(settings, createDate) {
328
+ const performanceInfos = [];
329
+ const { eventSchedule } = settings;
330
+ // 作成対象時間: 9,10,11など
331
+ // const hours: string[] = ['9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22'];
332
+ // const minutes = ['00', '15', '30', '45'];
333
+ // const tours = ['1', '2', '3', '4'];
334
+ // 1日分作成する
335
+ const now = (createDate instanceof Date)
336
+ ? moment(createDate)
337
+ : moment();
338
+ let startDate = moment.tz(`${now.tz(eventSchedule.scheduleTimezone)
339
+ .format('YYYYMMDD')} ${eventSchedule.startTime}`, 'YYYYMMDD HH:mm:ss', eventSchedule.scheduleTimezone);
340
+ const startDateShouldBeLte = moment.tz(`${now.tz(eventSchedule.scheduleTimezone)
341
+ .format('YYYYMMDD')} ${eventSchedule.endTime}`, 'YYYYMMDD HH:mm:ss', eventSchedule.scheduleTimezone);
342
+ const frequencyInMinutes = moment.duration(eventSchedule.repeatFrequency)
343
+ .asMinutes();
344
+ // tslint:disable-next-line:no-magic-numbers
345
+ const repeatCountInHour = Math.floor(60 / frequencyInMinutes);
346
+ let i = 0;
347
+ while (startDate < startDateShouldBeLte) {
348
+ i += 1;
349
+ if (i > 1) {
350
+ startDate = moment(startDate)
351
+ .add(moment.duration(eventSchedule.repeatFrequency));
352
+ }
353
+ const hour = `0${moment(startDate)
354
+ .format('HH')}`
355
+ // 2桁でない時は'0'詰め
356
+ // tslint:disable-next-line:no-magic-numbers
357
+ .slice(-2);
358
+ let tourIndex = i % repeatCountInHour;
359
+ if (tourIndex === 0) {
360
+ tourIndex = repeatCountInHour;
361
+ }
362
+ const tourNumber = `${hour}${tourIndex}`;
363
+ const endDate = moment(startDate)
364
+ .add(moment.duration(eventSchedule.duration));
365
+ const day = moment(startDate)
366
+ .tz(eventSchedule.scheduleTimezone)
367
+ .format('YYYYMMDD');
368
+ const startTime = moment(startDate)
369
+ .tz(eventSchedule.scheduleTimezone)
370
+ .format('HHmm');
371
+ const endTime = moment(endDate)
372
+ .tz(eventSchedule.scheduleTimezone)
373
+ .format('HHmm');
374
+ performanceInfos.push({
375
+ day: day,
376
+ start_time: startTime,
377
+ end_time: endTime,
378
+ door_time: startDate.toDate(),
379
+ start_date: startDate.toDate(),
380
+ end_date: endDate.toDate(),
381
+ tour_number: tourNumber,
382
+ duration: eventSchedule.duration
383
+ });
384
+ }
385
+ return performanceInfos;
386
+ }