@cinerino/sdk 12.9.0 → 12.10.0

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,36 @@
1
+ // tslint:disable:no-console
2
+ // tslint:disable-next-line:no-implicit-dependencies
3
+ import * as client from '../../../../lib/index';
4
+ import * as auth from '../../auth/authAsAdmin';
5
+
6
+ const PROJECT_ID = String(process.env.PROJECT_ID);
7
+ const SELLER_ID = '59d20831e53ebc2b4e774466';
8
+
9
+ // tslint:disable-next-line:max-func-body-length
10
+ async function main() {
11
+ const authClient = await auth.login();
12
+ await authClient.refreshAccessToken();
13
+ const loginTicket = authClient.verifyIdToken({});
14
+ console.log('username is', loginTicket.getUsername());
15
+
16
+ const eventService = await (await client.loadChevreAdmin({
17
+ endpoint: <string>process.env.CHEVRE_ENDPOINT,
18
+ auth: authClient
19
+ })).createEventInstance({
20
+ project: { id: PROJECT_ID },
21
+ seller: { id: SELLER_ID }
22
+ });
23
+
24
+ const events = await eventService.findEvents({
25
+ limit: 10,
26
+ page: 1,
27
+ identifiers: ['x', '20251126ABC12345102200']
28
+ });
29
+ console.log(events);
30
+ }
31
+
32
+ main()
33
+ .then(() => {
34
+ console.log('success!');
35
+ })
36
+ .catch(console.error);
@@ -125,6 +125,16 @@ async function main() {
125
125
  // }
126
126
  // );
127
127
  // console.log('updated.');
128
+
129
+ // イベントを検索する場合
130
+ const events = await adminEventService.findEvents({
131
+ limit: 1,
132
+ page: 1,
133
+ identifiers: [identifier]
134
+ });
135
+ // tslint:disable-next-line:no-null-keyword
136
+ console.dir(events, { depth: null });
137
+ console.log(events.length, 'events found.');
128
138
  }
129
139
 
130
140
  main()
@@ -0,0 +1,312 @@
1
+ // tslint:disable:no-console no-implicit-dependencies no-magic-numbers
2
+ import * as moment from 'moment';
3
+ import * as client from '../../../../lib/index';
4
+ import { auth } from '../../auth/clientCredentials';
5
+
6
+ const project = { id: String(process.env.PROJECT_ID) };
7
+ const { EVENT_ID } = process.env;
8
+ const APPLICATION_IDENTIFIER = 'SmartTheaterTXN';
9
+
10
+ type ISellerMakesOffer = Omit<client.factory.event.screeningEvent.ISellerMakesOffer, 'availableAtOrFrom'> & {
11
+ availableAtOrFrom?: client.factory.event.screeningEvent.IOfferAvailableAtOrFrom
12
+ | client.factory.event.screeningEvent.IOfferAvailableAtOrFrom[];
13
+ };
14
+ type ISeller = Omit<client.factory.event.screeningEvent.ISeller, 'makesOffer'> & {
15
+ makesOffer: ISellerMakesOffer[];
16
+ };
17
+ type IScreeningEventOffer = Omit<client.factory.event.screeningEvent.IOffer, 'seller'> & {
18
+ seller: ISeller;
19
+ };
20
+ type IScreeningEventExtensibleOffer = Omit<client.factory.event.screeningEvent.IExtensibleEventOffer, 'seller'> & {
21
+ seller: ISeller;
22
+ };
23
+ type IEvent = Omit<client.factory.event.screeningEvent.IEvent, 'offers'> & {
24
+ offers?: IScreeningEventOffer | IScreeningEventExtensibleOffer;
25
+ };
26
+
27
+ // tslint:disable-next-line:max-func-body-length
28
+ async function main() {
29
+ const eventService = new (await client.loadService()).Event({
30
+ endpoint: <string>process.env.API_ENDPOINT,
31
+ auth: await auth(),
32
+ project,
33
+ seller: { id: '' }
34
+ });
35
+
36
+ const sellerService = new (await client.loadService()).Seller({
37
+ endpoint: <string>process.env.API_ENDPOINT,
38
+ auth: await auth(),
39
+ project
40
+ });
41
+
42
+ const placeOrderService = await (await client.loadCloudTxn({
43
+ endpoint: <string>process.env.API_TXN_ENDPOINT,
44
+ auth: await auth()
45
+ })).createPlaceOrderInstance({
46
+ project,
47
+ seller: { id: '' }
48
+ });
49
+
50
+ // 販売劇場検索
51
+ const searchSellersResult = await sellerService.search({ branchCode: { $eq: '001' } });
52
+ // tslint:disable-next-line:insecure-random
53
+ const seller = searchSellersResult.data[Math.floor(searchSellersResult.data.length * Math.random())];
54
+ if (seller === undefined) {
55
+ throw new Error('No seller');
56
+ }
57
+ console.log('ordering from seller...', (<client.factory.multilingualString>seller.name).ja);
58
+
59
+ // イベント検索
60
+ const searchScreeningEventsResult = await eventService.search({
61
+ typeOf: client.factory.eventType.ScreeningEvent,
62
+ inSessionFrom: moment()
63
+ .toDate(),
64
+ inSessionThrough: moment()
65
+ .add(1, 'week')
66
+ .toDate(),
67
+ eventStatuses: [client.factory.eventStatusType.EventScheduled],
68
+ ...(typeof EVENT_ID === 'string') ? { id: { $eq: EVENT_ID } } : undefined
69
+ });
70
+ console.log(searchScreeningEventsResult.data.length, 'events found');
71
+
72
+ const availableEvents = <IEvent[]>searchScreeningEventsResult.data;
73
+ if (availableEvents.length === 0) {
74
+ throw new Error('No available events');
75
+ }
76
+
77
+ console.log('starting transaction...');
78
+ const transaction = await placeOrderService.start({
79
+ agent: {
80
+ identifier: [
81
+ { name: 'fromSamples', value: 'true' }
82
+ ]
83
+ },
84
+ seller: { id: String(seller.id) },
85
+ object: {
86
+ // passport: { token: passportToken }
87
+ }
88
+ });
89
+ console.log('transaction started', transaction.id);
90
+
91
+ try {
92
+ const numEvents = 1;
93
+ // tslint:disable-next-line:max-line-length
94
+ const authorizeSeatReservationResults: { price: number }[] = [];
95
+
96
+ // tslint:disable-next-line:no-increment-decrement
97
+ for (let i = 0; i < numEvents; i++) {
98
+ // イベント決定
99
+ // tslint:disable-next-line:insecure-random
100
+ const screeningEvent: IEvent = availableEvents[Math.floor(availableEvents.length * Math.random())];
101
+ const authorizeSeatReservationResult = await authorizeSeatReservationByEvent({
102
+ event: screeningEvent,
103
+ transaction: transaction
104
+ });
105
+ authorizeSeatReservationResults.push(authorizeSeatReservationResult);
106
+ }
107
+ } catch (error) {
108
+ console.error(error);
109
+ }
110
+
111
+ await wait(3000);
112
+
113
+ console.log('canceling transaction...');
114
+ await placeOrderService.cancel({ id: transaction.id });
115
+ console.log('transaction canceled.');
116
+ }
117
+
118
+ type IAuthorizeReservationAction = Pick<client.factory.action.authorize.offer.eventService.IAction, 'id'> & {
119
+ result?: {
120
+ price?: number;
121
+ };
122
+ };
123
+
124
+ // tslint:disable-next-line:max-func-body-length
125
+ async function authorizeSeatReservationByEvent(params: {
126
+ event: IEvent;
127
+ transaction: Pick<client.factory.transaction.placeOrder.ITransaction, 'id'>;
128
+ }): Promise<{
129
+ price: number;
130
+ }> {
131
+ const eventService = new (await client.loadService()).Event({
132
+ endpoint: <string>process.env.API_ENDPOINT,
133
+ auth: await auth(),
134
+ project,
135
+ seller: { id: '' }
136
+ });
137
+
138
+ const offerService = await (await client.loadCloudTxn({
139
+ endpoint: <string>process.env.API_TXN_ENDPOINT,
140
+ auth: await auth()
141
+ })).createOfferInstance({
142
+ project,
143
+ seller: { id: '' }
144
+ });
145
+
146
+ const eventOfferService = await (await client.loadCloudSearch({
147
+ endpoint: <string>process.env.API_ENDPOINT,
148
+ auth: await auth()
149
+ })).createEventOfferInstance({
150
+ project,
151
+ seller: { id: '' }
152
+ });
153
+ const screeningEvent = params.event;
154
+ const transaction = params.transaction;
155
+
156
+ // 券種検索
157
+ let ticketOffers = await eventService.searchTicketOffers({
158
+ event: { id: screeningEvent.id }
159
+ });
160
+ console.log('チケットオファーは以下の通りです');
161
+ console.log(ticketOffers.map((o) => {
162
+ const unitPriceSpecification = o.priceSpecification.priceComponent
163
+ .filter((s) => s.typeOf === client.factory.priceSpecificationType.UnitPriceSpecification)
164
+ .map((s) => `単価:${s.price}/${(<client.factory.priceSpecification.IPriceSpecification<client.factory.priceSpecificationType.UnitPriceSpecification>>s).referenceQuantity.value}`)
165
+ .join(' ');
166
+ const categoryCodeCharge = o.priceSpecification.priceComponent
167
+ .filter((s) => s.typeOf === client.factory.priceSpecificationType.CategoryCodeChargeSpecification)
168
+ .map((s) => `+${(<client.factory.priceSpecification.IPriceSpecification<client.factory.priceSpecificationType.CategoryCodeChargeSpecification>>s).appliesToCategoryCode[0].codeValue}チャージ:${s.price} ${s.priceCurrency}`)
169
+ .join(' ');
170
+
171
+ return `${o.id} ${(<client.factory.multilingualString>o.name).ja} ${unitPriceSpecification} ${categoryCodeCharge}`;
172
+ })
173
+ .join('\n'));
174
+
175
+ // 空席検索
176
+ const searchSeatOffersResult = await eventService.searchSeats({
177
+ event: { id: screeningEvent.id },
178
+ limit: 100,
179
+ page: 1
180
+ });
181
+ const seatOffers = searchSeatOffersResult.data;
182
+ // console.log(seatOffers.length, 'seatOffers found');
183
+ // const seatOffers = offers[0].containsPlace;
184
+ console.log(seatOffers.length, 'seatOffers found');
185
+ const availableSeatOffers
186
+ = seatOffers.filter((o) => o.offers?.shift()?.availability === client.factory.itemAvailability.InStock);
187
+ console.log(availableSeatOffers.length, 'availableSeatOffers found');
188
+ if (availableSeatOffers.length <= 0) {
189
+ throw new Error('No available seats');
190
+ }
191
+
192
+ // ムビチケ以外のメンバーシップオファーを選択
193
+ ticketOffers = ticketOffers
194
+ .filter((offer) => {
195
+ const movieTicketTypeChargeSpecification = offer.priceSpecification.priceComponent.find(
196
+ (component) => component.typeOf === client.factory.priceSpecificationType.MovieTicketTypeChargeSpecification
197
+ );
198
+
199
+ return movieTicketTypeChargeSpecification === undefined;
200
+ });
201
+
202
+ const selectedTicketOffer = ticketOffers.shift();
203
+ if (selectedTicketOffer === undefined) {
204
+ throw new Error('selectedTicketOffer undefined');
205
+ }
206
+ console.log('ticket offer selected', selectedTicketOffer.id, selectedTicketOffer.identifier, selectedTicketOffer.name.ja);
207
+
208
+ // 座席をランダムに選択
209
+ const selectedScreeningRoomSection = String(availableSeatOffers[0].containedInPlace?.branchCode);
210
+ console.log('screening room section selected', selectedScreeningRoomSection);
211
+ console.log(selectedScreeningRoomSection);
212
+ const selectedSeatOffers = availableSeatOffers.slice(0, 1);
213
+ console.log(selectedSeatOffers.length, 'seats selected');
214
+
215
+ /**
216
+ * 拡張イベントオファー使用の場合のオファーチケットトークン
217
+ */
218
+ let ticketToken: string | undefined;
219
+ // 拡張イベントオファー使用の場合、イベントオファーチケットを発行する
220
+ if (screeningEvent.offers?.typeOf === client.factory.offerType.AggregateOffer) {
221
+ // イベントに対するイベントオファー検索
222
+ await wait(3000);
223
+ const eventOffers = await eventOfferService.findEventOffers({
224
+ limit: 20,
225
+ page: 1,
226
+ itemOfferedId: screeningEvent.id,
227
+ availableAtOrFromIdentifier: APPLICATION_IDENTIFIER // 指定のアプリケーションで有効なオファー
228
+ });
229
+ console.log(eventOffers.length, 'eventOffers found.', eventOffers);
230
+
231
+ // 有効なイベントオファーは?
232
+ const now = new Date();
233
+ const validEventOffer = eventOffers.find((eventOffer) => {
234
+ return moment(eventOffer.validFrom)
235
+ .isSameOrBefore(now)
236
+ && moment(eventOffer.validThrough)
237
+ .isSameOrAfter(now);
238
+ });
239
+ if (validEventOffer === undefined) {
240
+ throw new Error('有効なイベントオファーが見つかりません');
241
+ }
242
+ console.log('有効なイベントオファーが見つかりました', validEventOffer.id, validEventOffer.identifier);
243
+
244
+ await wait(3000);
245
+ // 拡張オファー使用の場合、オファーコードを指定してオファーチケットを発行
246
+ const issueEventServiceOfferTicketResult = await offerService.issueEventServiceOfferTicket({
247
+ audience: { id: transaction.id },
248
+ eventId: screeningEvent.id,
249
+ eventOfferId: validEventOffer.id // 拡張オファー使用の場合、イベントオファーIDを指定する
250
+ });
251
+ console.log('offer ticket issued.', ticketToken);
252
+ ticketToken = issueEventServiceOfferTicketResult.ticketToken;
253
+ } else {
254
+ // no op
255
+ }
256
+
257
+ await wait(3000);
258
+ console.log('authorizing seat reservation...');
259
+ const seatReservationAuth = <IAuthorizeReservationAction>await offerService.authorizeEventService({
260
+ object: {
261
+ reservationFor: {
262
+ id: screeningEvent.id
263
+ },
264
+ acceptedOffer: selectedSeatOffers.map((o) => {
265
+ return {
266
+ typeOf: selectedTicketOffer.typeOf,
267
+ id: String(selectedTicketOffer.id),
268
+ itemOffered: {
269
+ serviceOutput: {
270
+ typeOf: client.factory.reservationType.EventReservation,
271
+ reservedTicket: {
272
+ typeOf: 'Ticket',
273
+ ticketedSeat: {
274
+ typeOf: client.factory.placeType.Seat,
275
+ seatNumber: o.branchCode,
276
+ seatSection: selectedScreeningRoomSection,
277
+ seatRow: ''
278
+ }
279
+ }
280
+ }
281
+ }
282
+ };
283
+ })
284
+ },
285
+ purpose: { id: transaction.id, typeOf: client.factory.transactionType.PlaceOrder },
286
+ instrument: [
287
+ ...(typeof ticketToken === 'string')
288
+ ? [{ ticketToken, typeOf: <'Ticket'>'Ticket' }] // オファーチケットを指定する
289
+ : []
290
+ ]
291
+ });
292
+ console.log('seat reservation authorized', seatReservationAuth.id);
293
+
294
+ const price = seatReservationAuth.result?.price;
295
+ // 金額計算
296
+ if (typeof price !== 'number') {
297
+ throw new Error('result.price undefined');
298
+ }
299
+ console.log('price:', price);
300
+
301
+ return { price };
302
+ }
303
+
304
+ async function wait(waitInMilliseconds: number) {
305
+ return new Promise((resolve) => setTimeout(resolve, waitInMilliseconds));
306
+ }
307
+
308
+ main()
309
+ .then(() => {
310
+ console.log('success!');
311
+ })
312
+ .catch(console.error);
@@ -29,6 +29,41 @@ export interface IUpdateEventSellerMakesOfferParamsByIdentifier {
29
29
  location?: never;
30
30
  superEvent?: never;
31
31
  }
32
+ /**
33
+ * adminイベント検索パラメータ
34
+ */
35
+ export interface IFindParams {
36
+ /**
37
+ * max: 20
38
+ */
39
+ limit: number;
40
+ page: number;
41
+ /**
42
+ * イベント識別子リスト
43
+ * max length: 10
44
+ */
45
+ identifiers?: string[];
46
+ }
47
+ /**
48
+ * adminイベント検索結果
49
+ */
50
+ export declare type IEventAsFindResult = Pick<factory.event.screeningEvent.IEvent, 'additionalProperty' | 'doorTime' | 'endDate' | 'eventStatus' | 'id' | 'identifier' | 'location' | 'maximumPhysicalAttendeeCapacity' | 'startDate' | 'superEvent' | 'typeOf'> & {
51
+ offers: {
52
+ /**
53
+ * AggregateOfferであれば拡張イベントオファー使用
54
+ */
55
+ typeOf: factory.offerType.AggregateOffer | factory.offerType.Offer;
56
+ /**
57
+ * 興行
58
+ */
59
+ itemOffered: {
60
+ /**
61
+ * 興行ID
62
+ */
63
+ id: string;
64
+ };
65
+ };
66
+ };
32
67
  /**
33
68
  * イベントサービス
34
69
  */
@@ -93,5 +128,9 @@ export declare class EventService extends Service {
93
128
  };
94
129
  };
95
130
  }): Promise<void>;
131
+ /**
132
+ * 管理者によるイベント検索(在庫管理ロールが必要です)
133
+ */
134
+ findEvents(params: IFindParams): Promise<IEventAsFindResult[]>;
96
135
  }
97
136
  export {};
@@ -174,6 +174,25 @@ var EventService = /** @class */ (function (_super) {
174
174
  });
175
175
  });
176
176
  };
177
+ /**
178
+ * 管理者によるイベント検索(在庫管理ロールが必要です)
179
+ */
180
+ EventService.prototype.findEvents = function (params) {
181
+ return __awaiter(this, void 0, void 0, function () {
182
+ var _this = this;
183
+ return __generator(this, function (_a) {
184
+ return [2 /*return*/, this.fetch({
185
+ uri: '/events',
186
+ method: 'GET',
187
+ qs: params,
188
+ expectedStatusCodes: [http_status_1.OK]
189
+ })
190
+ .then(function (response) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
191
+ return [2 /*return*/, response.json()];
192
+ }); }); })];
193
+ });
194
+ });
195
+ };
177
196
  return EventService;
178
197
  }(service_1.Service));
179
198
  exports.EventService = EventService;
@@ -1,6 +1,6 @@
1
1
  import * as factory from '../../factory';
2
2
  import { Service } from '../../service';
3
- import { ICreateParamsByIdentifier, IUpdateParamsByIdentifier } from '../../chevreAdmin/event';
3
+ import { ICreateParamsByIdentifier, IEventAsFindResult, IFindParams, IUpdateParamsByIdentifier } from '../../chevreAdmin/event';
4
4
  declare type ISendEmailMessageOnEventUpdated = Pick<factory.action.transfer.send.message.email.IAttributes, 'purpose' | 'recipient'> & {
5
5
  object: factory.action.transfer.send.message.email.IObjectAsEmailMessage;
6
6
  };
@@ -39,6 +39,10 @@ export declare class EventService extends Service {
39
39
  updateEventsByIdentifier(params: IUpdateParamsByIdentifier[], options: {
40
40
  typeOf: factory.eventType.ScreeningEvent;
41
41
  }): Promise<void>;
42
+ /**
43
+ * 管理者によるイベント検索(在庫管理ロールが必要です)
44
+ */
45
+ findEvents(params: IFindParams): Promise<IEventAsFindResult[]>;
42
46
  /**
43
47
  * イベントステータス更新
44
48
  */
@@ -136,6 +136,30 @@ var EventService = /** @class */ (function (_super) {
136
136
  });
137
137
  });
138
138
  };
139
+ /**
140
+ * 管理者によるイベント検索(在庫管理ロールが必要です)
141
+ */
142
+ EventService.prototype.findEvents = function (params) {
143
+ return __awaiter(this, void 0, void 0, function () {
144
+ var _a, auth, endpoint, project, seller, disableAutoRetry, chevreAdmin, eventService;
145
+ return __generator(this, function (_b) {
146
+ switch (_b.label) {
147
+ case 0:
148
+ _a = this.options, auth = _a.auth, endpoint = _a.endpoint, project = _a.project, seller = _a.seller, disableAutoRetry = _a.disableAutoRetry;
149
+ return [4 /*yield*/, index_1.loadChevreAdmin({ auth: auth, endpoint: endpoint, disableAutoRetry: disableAutoRetry })];
150
+ case 1:
151
+ chevreAdmin = _b.sent();
152
+ return [4 /*yield*/, chevreAdmin.createEventInstance({
153
+ project: project,
154
+ seller: { id: (typeof (seller === null || seller === void 0 ? void 0 : seller.id) === 'string') ? seller.id : '' }
155
+ })];
156
+ case 2:
157
+ eventService = _b.sent();
158
+ return [2 /*return*/, eventService.findEvents(params)];
159
+ }
160
+ });
161
+ });
162
+ };
139
163
  /**
140
164
  * イベントステータス更新
141
165
  */
package/lib/bundle.js CHANGED
@@ -3061,6 +3061,25 @@ var EventService = /** @class */ (function (_super) {
3061
3061
  });
3062
3062
  });
3063
3063
  };
3064
+ /**
3065
+ * 管理者によるイベント検索(在庫管理ロールが必要です)
3066
+ */
3067
+ EventService.prototype.findEvents = function (params) {
3068
+ return __awaiter(this, void 0, void 0, function () {
3069
+ var _this = this;
3070
+ return __generator(this, function (_a) {
3071
+ return [2 /*return*/, this.fetch({
3072
+ uri: '/events',
3073
+ method: 'GET',
3074
+ qs: params,
3075
+ expectedStatusCodes: [http_status_1.OK]
3076
+ })
3077
+ .then(function (response) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
3078
+ return [2 /*return*/, response.json()];
3079
+ }); }); })];
3080
+ });
3081
+ });
3082
+ };
3064
3083
  return EventService;
3065
3084
  }(service_1.Service));
3066
3085
  exports.EventService = EventService;
@@ -21807,6 +21826,30 @@ var EventService = /** @class */ (function (_super) {
21807
21826
  });
21808
21827
  });
21809
21828
  };
21829
+ /**
21830
+ * 管理者によるイベント検索(在庫管理ロールが必要です)
21831
+ */
21832
+ EventService.prototype.findEvents = function (params) {
21833
+ return __awaiter(this, void 0, void 0, function () {
21834
+ var _a, auth, endpoint, project, seller, disableAutoRetry, chevreAdmin, eventService;
21835
+ return __generator(this, function (_b) {
21836
+ switch (_b.label) {
21837
+ case 0:
21838
+ _a = this.options, auth = _a.auth, endpoint = _a.endpoint, project = _a.project, seller = _a.seller, disableAutoRetry = _a.disableAutoRetry;
21839
+ return [4 /*yield*/, index_1.loadChevreAdmin({ auth: auth, endpoint: endpoint, disableAutoRetry: disableAutoRetry })];
21840
+ case 1:
21841
+ chevreAdmin = _b.sent();
21842
+ return [4 /*yield*/, chevreAdmin.createEventInstance({
21843
+ project: project,
21844
+ seller: { id: (typeof (seller === null || seller === void 0 ? void 0 : seller.id) === 'string') ? seller.id : '' }
21845
+ })];
21846
+ case 2:
21847
+ eventService = _b.sent();
21848
+ return [2 /*return*/, eventService.findEvents(params)];
21849
+ }
21850
+ });
21851
+ });
21852
+ };
21810
21853
  /**
21811
21854
  * イベントステータス更新
21812
21855
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cinerino/sdk",
3
- "version": "12.9.0",
3
+ "version": "12.10.0",
4
4
  "description": "Cinerino SDK",
5
5
  "main": "./lib/index.js",
6
6
  "browser": {