@chevre/domain 22.2.0-alpha.0 → 22.2.0-alpha.10

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.
Files changed (27) hide show
  1. package/example/src/chevre/{projectReservationFieldsById.ts → projectOwnershipInfoFieldsById.ts} +4 -4
  2. package/lib/chevre/repo/authorization.d.ts +3 -1
  3. package/lib/chevre/repo/authorization.js +21 -10
  4. package/lib/chevre/repo/categoryCode.d.ts +6 -2
  5. package/lib/chevre/repo/ownershipInfo.d.ts +10 -6
  6. package/lib/chevre/repo/ownershipInfo.js +37 -10
  7. package/lib/chevre/service/assetTransaction/pay/factory.js +1 -1
  8. package/lib/chevre/service/assetTransaction/refund/factory.js +1 -1
  9. package/lib/chevre/service/assetTransaction/reserve/start/createSubReservations.js +69 -30
  10. package/lib/chevre/service/assetTransaction/reserve/start/factory/createReservation.js +12 -2
  11. package/lib/chevre/service/offer/event/authorize/factory.js +20 -6
  12. package/lib/chevre/service/offer/event/authorize/processStartReserve4chevre/requestedProgramMembershipUsed2permit.d.ts +24 -0
  13. package/lib/chevre/service/offer/event/authorize/processStartReserve4chevre/requestedProgramMembershipUsed2permit.js +127 -0
  14. package/lib/chevre/service/offer/event/authorize/processStartReserve4chevre.js +12 -32
  15. package/lib/chevre/service/offer/event/importFromCOA/factory.d.ts +3 -1
  16. package/lib/chevre/service/order/sendOrder.js +9 -5
  17. package/lib/chevre/service/payment/any/verifyTicketTokenAsNeeded.d.ts +0 -2
  18. package/lib/chevre/service/payment/any/verifyTicketTokenAsNeeded.js +18 -21
  19. package/lib/chevre/service/payment/any.d.ts +0 -2
  20. package/lib/chevre/service/report/ownershipInfo.d.ts +3 -1
  21. package/lib/chevre/service/task/authorizePayment.js +0 -2
  22. package/lib/chevre/service/task/onAuthorizationCreated.js +1 -1
  23. package/lib/chevre/service/transaction/moneyTransfer.js +5 -1
  24. package/lib/chevre/service/transaction/placeOrder/confirm/validation.d.ts +1 -1
  25. package/lib/chevre/service/transaction/placeOrder/confirm/validation.js +36 -2
  26. package/lib/chevre/service/transaction/placeOrder/confirm.js +1 -1
  27. package/package.json +3 -3
@@ -8,12 +8,12 @@ import { chevre } from '../../../lib/index';
8
8
  async function main() {
9
9
  await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
10
10
 
11
- const reservationRepo = await chevre.repository.Reservation.createInstance(mongoose.connection);
12
- const result = await reservationRepo.projectFieldsById(
11
+ const ownershipInfoRepo = await chevre.repository.OwnershipInfo.createInstance(mongoose.connection);
12
+ const result = await ownershipInfoRepo.projectFieldsById(
13
13
  {
14
- id: '948926445022844-0',
15
- inclusion: ['reservationStatus', 'reservationFor.id']
14
+ id: 'd9080760-1bdb-49cf-86eb-50f98fab0010'
16
15
  }
16
+ // ['id', 'typeOfGood']
17
17
  );
18
18
  // tslint:disable-next-line:no-null-keyword
19
19
  console.dir(result, { depth: null });
@@ -36,7 +36,9 @@ export declare class AuthorizationRepo {
36
36
  };
37
37
  id: string;
38
38
  }): Promise<Pick<IFindValidOneResult, 'object'>>;
39
- search(params: factory.authorization.ISearchConditions): Promise<factory.authorization.IAuthorization[]>;
39
+ projectFields(params: factory.authorization.ISearchConditions): Promise<(factory.authorization.IAuthorization & {
40
+ id: string;
41
+ })[]>;
40
42
  /**
41
43
  * 有効期限を一定期間過ぎた承認を削除する
42
44
  */
@@ -114,14 +114,17 @@ class AuthorizationRepo {
114
114
  code: { $eq: String(params.code) },
115
115
  validFrom: { $lte: now },
116
116
  validUntil: { $gte: now }
117
- }, { object: 1, _id: 1, typeOf: 1, audience: 1, issuedBy: 1 })
118
- // projection的にleanで十分
119
- // .lean<Pick<factory.authorization.IAuthorization, 'object'>>()
117
+ }, {
118
+ _id: 0,
119
+ id: { $toString: '$_id' },
120
+ object: 1, typeOf: 1, audience: 1, issuedBy: 1
121
+ })
122
+ .lean()
120
123
  .exec();
121
124
  if (doc === null) {
122
125
  throw new factory.errors.NotFound(this.authorizationModel.modelName);
123
126
  }
124
- const { id, object, typeOf, audience, issuedBy } = doc.toObject();
127
+ const { id, object, typeOf, audience, issuedBy } = doc;
125
128
  return Object.assign(Object.assign({ id, object, typeOf }, (typeof (issuedBy === null || issuedBy === void 0 ? void 0 : issuedBy.id) === 'string') ? { issuedBy } : undefined), (typeof (audience === null || audience === void 0 ? void 0 : audience.id) === 'string') ? { audience } : undefined);
126
129
  });
127
130
  }
@@ -145,14 +148,22 @@ class AuthorizationRepo {
145
148
  return doc;
146
149
  });
147
150
  }
148
- search(params) {
151
+ projectFields(params) {
149
152
  var _a;
150
153
  return __awaiter(this, void 0, void 0, function* () {
151
154
  const conditions = AuthorizationRepo.CREATE_MONGO_CONDITIONS(params);
152
155
  const query = this.authorizationModel.find((conditions.length > 0) ? { $and: conditions } : {}, {
153
- // __v: 0,
154
- // createdAt: 0,
155
- // updatedAt: 0
156
+ _id: 0,
157
+ id: { $toString: '$_id' },
158
+ project: 1,
159
+ typeOf: 1,
160
+ code: 1,
161
+ object: 1,
162
+ validFrom: 1,
163
+ validUntil: 1,
164
+ audience: 1,
165
+ author: 1,
166
+ issuedBy: 1
156
167
  });
157
168
  if (typeof params.limit === 'number' && params.limit > 0) {
158
169
  const page = (typeof params.page === 'number' && params.page > 0) ? params.page : 1;
@@ -165,8 +176,8 @@ class AuthorizationRepo {
165
176
  query.sort({ validFrom: params.sort.validFrom });
166
177
  }
167
178
  return query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
168
- .exec()
169
- .then((docs) => docs.map((doc) => doc.toObject()));
179
+ .lean()
180
+ .exec();
170
181
  });
171
182
  }
172
183
  /**
@@ -45,13 +45,17 @@ export declare class CategoryCodeRepo {
45
45
  /**
46
46
  * 検索
47
47
  */
48
- search(params: factory.categoryCode.ISearchConditions, inclusion: IKeyOfProjection[], exclusion: IKeyOfProjection[]): Promise<factory.categoryCode.ICategoryCode[]>;
48
+ search(params: factory.categoryCode.ISearchConditions, inclusion: IKeyOfProjection[], exclusion: IKeyOfProjection[]): Promise<(factory.categoryCode.ICategoryCode & {
49
+ id: string;
50
+ })[]>;
49
51
  save(params: {
50
52
  id?: string;
51
53
  attributes: factory.categoryCode.ICategoryCode & {
52
54
  $unset?: IUnset;
53
55
  };
54
- }): Promise<factory.categoryCode.ICategoryCode>;
56
+ }): Promise<factory.categoryCode.ICategoryCode & {
57
+ id: string;
58
+ }>;
55
59
  saveManyByCodeValue(params: {
56
60
  attributes: factory.categoryCode.ICategoryCode;
57
61
  upsert?: boolean;
@@ -24,7 +24,9 @@
24
24
  /// <reference types="mongoose/types/inferschematype" />
25
25
  import type { Connection } from 'mongoose';
26
26
  import * as factory from '../factory';
27
- export type IOwnershipInfo = factory.ownershipInfo.IOwnershipInfo<factory.ownershipInfo.IGood>;
27
+ export type IOwnershipInfoWithId = factory.ownershipInfo.IOwnershipInfo<factory.ownershipInfo.IGood> & {
28
+ id: string;
29
+ };
28
30
  /**
29
31
  * 所有権リポジトリ
30
32
  */
@@ -35,14 +37,16 @@ export declare class OwnershipInfoRepo {
35
37
  /**
36
38
  * なければ作成する
37
39
  */
38
- createIfNotExistByIdentifier(ownershipInfo: IOwnershipInfo): Promise<IOwnershipInfo>;
39
- findById(params: {
40
+ createIfNotExistByIdentifier(ownershipInfo: Omit<IOwnershipInfoWithId, 'id'>): Promise<{
40
41
  id: string;
41
- }, projection?: any): Promise<IOwnershipInfo>;
42
+ }>;
43
+ projectFieldsById(params: {
44
+ id: string;
45
+ }, inclusion?: (keyof IOwnershipInfoWithId)[]): Promise<IOwnershipInfoWithId>;
42
46
  /**
43
47
  * 所有権を検索する
44
48
  */
45
- search(params: factory.ownershipInfo.ISearchConditions, projection?: any): Promise<IOwnershipInfo[]>;
49
+ search(params: factory.ownershipInfo.ISearchConditions, projection?: any): Promise<IOwnershipInfoWithId[]>;
46
50
  /**
47
51
  * 識別子から所有期限を変更する
48
52
  * 存在しない場合undefinedを返す
@@ -53,7 +57,7 @@ export declare class OwnershipInfoRepo {
53
57
  };
54
58
  identifier: string;
55
59
  ownedThrough: Date;
56
- }): Promise<IOwnershipInfo | undefined>;
60
+ }): Promise<IOwnershipInfoWithId | undefined>;
57
61
  /**
58
62
  * 所有者の所有権を全て削除する
59
63
  */
@@ -233,11 +233,14 @@ class OwnershipInfoRepo {
233
233
  new: true,
234
234
  upsert: true,
235
235
  projection: {
236
- __v: 0,
237
- createdAt: 0,
238
- updatedAt: 0
236
+ _id: 0,
237
+ id: { $toString: '$_id' }
238
+ // __v: 0,
239
+ // createdAt: 0,
240
+ // updatedAt: 0
239
241
  }
240
242
  })
243
+ .lean()
241
244
  .exec();
242
245
  }
243
246
  catch (error) {
@@ -254,26 +257,50 @@ class OwnershipInfoRepo {
254
257
  if (duplicate) {
255
258
  // 重複の場合、再度取得
256
259
  doc = yield this.ownershipInfoModel.findOne({ identifier: { $eq: ownershipInfo.identifier } }, {
257
- __v: 0,
258
- createdAt: 0,
259
- updatedAt: 0
260
+ _id: 0,
261
+ id: { $toString: '$_id' }
262
+ // __v: 0,
263
+ // createdAt: 0,
264
+ // updatedAt: 0
260
265
  })
266
+ .lean()
261
267
  .exec();
262
268
  }
263
269
  if (doc === undefined || doc === null) {
264
270
  throw new factory.errors.NotFound(this.ownershipInfoModel.modelName);
265
271
  }
266
- return doc.toObject();
272
+ return { id: doc.id };
273
+ // return <IOwnershipInfo>doc.toObject();
267
274
  });
268
275
  }
269
- findById(params, projection) {
276
+ projectFieldsById(params, inclusion) {
270
277
  return __awaiter(this, void 0, void 0, function* () {
271
- const doc = yield this.ownershipInfoModel.findById(params.id, Object.assign({ __v: 0, createdAt: 0, updatedAt: 0 }, projection))
278
+ let projection = {
279
+ _id: 0,
280
+ id: { $toString: '$_id' },
281
+ project: 1,
282
+ typeOf: 1,
283
+ identifier: 1,
284
+ ownedBy: 1,
285
+ acquiredFrom: 1,
286
+ ownedFrom: 1,
287
+ ownedThrough: 1,
288
+ typeOfGood: 1
289
+ };
290
+ const positiveProjectionFields = (Array.isArray(inclusion))
291
+ ? inclusion.filter((key) => key !== 'id' && String(key) !== '_id')
292
+ : undefined;
293
+ if (Array.isArray(positiveProjectionFields)) {
294
+ projection = Object.assign({ _id: 0, id: { $toString: '$_id' } }, Object.fromEntries(positiveProjectionFields.map((key) => ([key, 1]))));
295
+ }
296
+ const doc = yield this.ownershipInfoModel.findOne({ _id: { $eq: params.id } }, projection)
297
+ .lean() // lean(2024-08-15~)
272
298
  .exec();
273
299
  if (doc === null) {
274
300
  throw new factory.errors.NotFound(this.ownershipInfoModel.modelName);
275
301
  }
276
- return doc.toObject();
302
+ return doc;
303
+ // return doc.toObject();
277
304
  });
278
305
  }
279
306
  /**
@@ -74,7 +74,7 @@ function createStartParams(params) {
74
74
  else if (params.paymentServiceType === factory.service.paymentService.PaymentServiceType.CreditCard) {
75
75
  const creditCardPaymentServiceOutput = (_l = params.paymentService) === null || _l === void 0 ? void 0 : _l.serviceOutput;
76
76
  const invoiceAsServiceOutput = (Array.isArray(creditCardPaymentServiceOutput))
77
- ? creditCardPaymentServiceOutput.find((output) => output.typeOf === 'Invoice')
77
+ ? creditCardPaymentServiceOutput.find((output) => (output === null || output === void 0 ? void 0 : output.typeOf) === 'Invoice')
78
78
  : creditCardPaymentServiceOutput;
79
79
  // カード通貨区分が存在すれば適用
80
80
  if ((invoiceAsServiceOutput === null || invoiceAsServiceOutput === void 0 ? void 0 : invoiceAsServiceOutput.typeOf) === 'Invoice') {
@@ -24,7 +24,7 @@ function createStartParams(params) {
24
24
  if (((_g = params.paymentService) === null || _g === void 0 ? void 0 : _g.typeOf) === factory.service.paymentService.PaymentServiceType.CreditCard) {
25
25
  // カード通貨区分の存在する決済サービスを考慮(2023-08-09~)
26
26
  const invoiceAsServiceOutput = (Array.isArray(params.paymentService.serviceOutput))
27
- ? params.paymentService.serviceOutput.find((output) => output.typeOf === 'Invoice')
27
+ ? params.paymentService.serviceOutput.find((output) => (output === null || output === void 0 ? void 0 : output.typeOf) === 'Invoice')
28
28
  : params.paymentService.serviceOutput;
29
29
  let paymentServiceOutputAmountCurrency;
30
30
  if ((invoiceAsServiceOutput === null || invoiceAsServiceOutput === void 0 ? void 0 : invoiceAsServiceOutput.typeOf) === 'Invoice') {
@@ -53,6 +53,7 @@ function createSubReservations(params) {
53
53
  });
54
54
  const programMembershipUsed = yield validateProgramMembershipUsed({
55
55
  acceptedOffer,
56
+ availableOffer: ticketType,
56
57
  project: { id: params.event.project.id }
57
58
  })(repos);
58
59
  // チケット作成
@@ -271,61 +272,94 @@ function validateAdvanceBookingRequirement(params) {
271
272
  }
272
273
  }
273
274
  function validateProgramMembershipUsed(params) {
274
- // tslint:disable-next-line:max-func-body-length
275
+ // tslint:disable-next-line:cyclomatic-complexity max-func-body-length
275
276
  return (repos) => __awaiter(this, void 0, void 0, function* () {
276
- var _a, _b, _c;
277
+ var _a, _b, _c, _d, _e, _f, _g, _h;
277
278
  const now = new Date();
278
279
  let programMembershipUsed;
279
280
  const requestedProgramMembershipUsed = (_b = (_a = params.acceptedOffer.itemOffered) === null || _a === void 0 ? void 0 : _a.serviceOutput) === null || _b === void 0 ? void 0 : _b.programMembershipUsed;
280
281
  if (typeof requestedProgramMembershipUsed === 'string') {
281
- throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', 'must be object');
282
+ throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', 'must be permit');
283
+ }
284
+ if ((requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.typeOf) === 'Ticket') {
285
+ throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', 'must be permit');
282
286
  }
283
287
  const programMembershipUsedIdentifier = requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.identifier;
284
- const issuedThroughId = (_c = requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.issuedThrough) === null || _c === void 0 ? void 0 : _c.id;
285
- if (typeof programMembershipUsedIdentifier === 'string' && programMembershipUsedIdentifier.length > 0) {
286
- if (typeof issuedThroughId !== 'string' || issuedThroughId.length === 0) {
287
- throw new factory.errors.ArgumentNull('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed.issuedThrough.id');
288
- }
288
+ const issuedThroughTypeOf = (_c = requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.issuedThrough) === null || _c === void 0 ? void 0 : _c.typeOf;
289
+ if (typeof programMembershipUsedIdentifier === 'string') {
289
290
  let permitIssuedThrough;
290
291
  // まずメンバーシップを検索して、存在しなければCreditCardを検索(どちらが発行元サービスか不明なので)
291
- permitIssuedThrough = (yield repos.product.searchProducts({
292
- limit: 1,
293
- page: 1,
294
- id: { $eq: issuedThroughId },
295
- typeOf: { $eq: factory.product.ProductType.MembershipService }
296
- }, ['_id', 'typeOf', 'project', 'serviceType', 'serviceOutput'], [])).shift();
297
- if (permitIssuedThrough === undefined) {
292
+ if (issuedThroughTypeOf === factory.product.ProductType.MembershipService) {
293
+ const issuedThroughId = (_d = requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.issuedThrough) === null || _d === void 0 ? void 0 : _d.id;
294
+ if (typeof issuedThroughId !== 'string' || issuedThroughId === '') {
295
+ throw new factory.errors.ArgumentNull('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed.issuedThrough.id');
296
+ }
297
+ permitIssuedThrough = (yield repos.product.searchProducts({
298
+ limit: 1,
299
+ page: 1,
300
+ id: { $eq: issuedThroughId },
301
+ typeOf: { $eq: factory.product.ProductType.MembershipService }
302
+ }, ['_id', 'typeOf', 'project', 'serviceType', 'serviceOutput'], [])).shift();
303
+ if (permitIssuedThrough === undefined) {
304
+ throw new factory.errors.NotFound(factory.product.ProductType.MembershipService);
305
+ }
306
+ }
307
+ else if (issuedThroughTypeOf === factory.service.paymentService.PaymentServiceType.CreditCard) {
308
+ const issuedThroughId = (_e = requestedProgramMembershipUsed === null || requestedProgramMembershipUsed === void 0 ? void 0 : requestedProgramMembershipUsed.issuedThrough) === null || _e === void 0 ? void 0 : _e.id;
309
+ if (typeof issuedThroughId !== 'string' || issuedThroughId === '') {
310
+ throw new factory.errors.ArgumentNull('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed.issuedThrough.id');
311
+ }
298
312
  permitIssuedThrough = (yield repos.paymentService.searchPaymentServices({
299
313
  limit: 1,
300
314
  page: 1,
301
315
  id: { $eq: issuedThroughId },
302
316
  typeOf: { $eq: factory.service.paymentService.PaymentServiceType.CreditCard }
303
317
  }, ['_id', 'typeOf', 'project', 'serviceType', 'serviceOutput'], [])).shift();
318
+ if (permitIssuedThrough === undefined) {
319
+ throw new factory.errors.NotFound(factory.service.paymentService.PaymentServiceType.CreditCard);
320
+ }
321
+ }
322
+ else if (issuedThroughTypeOf === factory.service.paymentService.PaymentServiceType.FaceToFace) {
323
+ // プロダクトは存在しないので特に検証なし
324
+ permitIssuedThrough = {
325
+ typeOf: factory.service.paymentService.PaymentServiceType.FaceToFace
326
+ };
304
327
  }
305
- if (typeof (permitIssuedThrough === null || permitIssuedThrough === void 0 ? void 0 : permitIssuedThrough.typeOf) !== 'string') {
306
- throw new factory.errors.NotFound(`Permit issuer service [${issuedThroughId}]`);
328
+ else {
329
+ throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', `invalid issuedThrough.typeOf: ${issuedThroughTypeOf}`);
307
330
  }
308
- // permitIssuedThrough =
309
- // await repos.product.findById({ id: issuedThroughId }, ['_id', 'typeOf', 'project', 'serviceType', 'serviceOutput'], []);
310
331
  switch (permitIssuedThrough.typeOf) {
332
+ case factory.service.paymentService.PaymentServiceType.FaceToFace:
333
+ // 適用メンバーシップ条件有のオファーであれば、問答無用に受け入れる
334
+ const eligibleMembershipType = (_g = (_f = params.availableOffer.eligibleMembershipType) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.codeValue;
335
+ if (typeof eligibleMembershipType === 'string') {
336
+ programMembershipUsed = {
337
+ typeOf: factory.permit.PermitType.Permit,
338
+ identifier: programMembershipUsedIdentifier,
339
+ issuedThrough: {
340
+ serviceType: { codeValue: eligibleMembershipType },
341
+ typeOf: permitIssuedThrough.typeOf
342
+ }
343
+ };
344
+ }
345
+ break;
311
346
  // 発行サービスがCreditCardのケースに対応(2023-09-01~)
312
347
  case factory.service.paymentService.PaymentServiceType.CreditCard:
313
348
  // 決済サービスのserviceOutputにPermitが存在すれば、設定されたメンバーシップ区分のPermitをprogramMembershipUsedとして適用する
314
349
  let issuedThroughServiceType;
315
350
  if (Array.isArray(permitIssuedThrough.serviceOutput)) {
316
- const serviceOutputAsPermit = permitIssuedThrough.serviceOutput.find((output) => output.typeOf === factory.permit.PermitType.Permit);
351
+ const serviceOutputAsPermit = permitIssuedThrough.serviceOutput.find((output) => (output === null || output === void 0 ? void 0 : output.typeOf) === factory.permit.PermitType.Permit);
317
352
  if ((serviceOutputAsPermit === null || serviceOutputAsPermit === void 0 ? void 0 : serviceOutputAsPermit.typeOf) === factory.permit.PermitType.Permit) {
318
353
  issuedThroughServiceType = serviceOutputAsPermit.issuedThrough.serviceType;
319
354
  }
320
355
  }
321
- if ((issuedThroughServiceType === null || issuedThroughServiceType === void 0 ? void 0 : issuedThroughServiceType.typeOf) === 'CategoryCode') {
356
+ if (typeof (issuedThroughServiceType === null || issuedThroughServiceType === void 0 ? void 0 : issuedThroughServiceType.codeValue) === 'string') {
322
357
  programMembershipUsed = {
323
- project: permitIssuedThrough.project,
324
358
  typeOf: factory.permit.PermitType.Permit,
325
359
  identifier: programMembershipUsedIdentifier,
326
360
  issuedThrough: {
327
361
  id: permitIssuedThrough.id,
328
- serviceType: issuedThroughServiceType,
362
+ serviceType: { codeValue: issuedThroughServiceType.codeValue },
329
363
  typeOf: permitIssuedThrough.typeOf
330
364
  }
331
365
  };
@@ -336,7 +370,7 @@ function validateProgramMembershipUsed(params) {
336
370
  break;
337
371
  case factory.product.ProductType.MembershipService:
338
372
  // requestedProgramMembershipUsedの発行サービスIDから外部連携設定を取得する
339
- const permitService = yield createPermitService({ issuedThrough: { id: issuedThroughId } })(repos);
373
+ const permitService = yield createPermitService({ issuedThrough: { id: permitIssuedThrough.id } })(repos);
340
374
  // メンバーシップの存在確認
341
375
  const serviceOutput = yield permitService.findByIdentifier({
342
376
  project: { id: params.project.id },
@@ -354,12 +388,17 @@ function validateProgramMembershipUsed(params) {
354
388
  .isBefore(moment(now))) {
355
389
  throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', 'unavailable programMembership');
356
390
  }
357
- programMembershipUsed = {
358
- project: serviceOutput.project,
359
- typeOf: serviceOutput.typeOf,
360
- identifier: serviceOutput.identifier,
361
- issuedThrough: serviceOutput.issuedThrough
362
- };
391
+ if (((_h = permitIssuedThrough.serviceType) === null || _h === void 0 ? void 0 : _h.typeOf) === 'CategoryCode') {
392
+ programMembershipUsed = {
393
+ typeOf: serviceOutput.typeOf,
394
+ identifier: programMembershipUsedIdentifier,
395
+ issuedThrough: {
396
+ id: permitIssuedThrough.id,
397
+ serviceType: { codeValue: permitIssuedThrough.serviceType.codeValue },
398
+ typeOf: permitIssuedThrough.typeOf
399
+ }
400
+ };
401
+ }
363
402
  break;
364
403
  default:
365
404
  throw new factory.errors.Argument('acceptedOffer.itemOffered.serviceOutput.programMembershipUsed', `${permitIssuedThrough.typeOf} not implemented`);
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateAppliesToMovieTicket = exports.createReservedTicket = exports.createReservation = exports.createAdditionalTicketText = exports.createAdditionalProperty = void 0;
4
+ const createDebug = require("debug");
4
5
  const moment = require("moment");
5
6
  const util = require("util");
6
7
  const factory = require("../../../../../factory");
7
8
  const price_1 = require("./price");
9
+ const debug = createDebug('chevre-domain:service:assetTransaction');
8
10
  function createTicketIdentifier(params) {
9
11
  var _a, _b, _c, _d;
10
12
  // チケット識別子の規定値を作成
@@ -193,15 +195,23 @@ function validateEligibleSubReservation(params) {
193
195
  }
194
196
  }
195
197
  function validateEligibleMembershipType(params) {
198
+ debug('validateEligibleMembershipType: validating...', JSON.stringify(params.programMembershipUsed), JSON.stringify(params.availableOffer.eligibleMembershipType));
196
199
  const programMembershipUsed = params.programMembershipUsed;
197
200
  // 使用メンバーシップがeligibleMembershipに含まれればよい
198
201
  const eligibleMembershipType = params.availableOffer.eligibleMembershipType;
199
202
  if (Array.isArray(eligibleMembershipType)) {
200
- if (typeof (programMembershipUsed === null || programMembershipUsed === void 0 ? void 0 : programMembershipUsed.typeOf) !== 'string' || programMembershipUsed.typeOf.length === 0) {
203
+ if ((programMembershipUsed === null || programMembershipUsed === void 0 ? void 0 : programMembershipUsed.typeOf) !== factory.permit.PermitType.Permit) {
201
204
  throw new factory.errors.Argument('programMembershipUsed', 'programMembership required');
202
205
  }
206
+ const { identifier, issuedThrough } = programMembershipUsed;
207
+ if (typeof identifier !== 'string' || identifier === '') {
208
+ throw new factory.errors.Argument('programMembershipUsed', 'programMembership.identifier required');
209
+ }
203
210
  // programMembershipUsed.issuedThrough.serviceTypeで検証する
204
- const isEligible = eligibleMembershipType.some((membershipType) => { var _a, _b; return membershipType.codeValue === ((_b = (_a = programMembershipUsed.issuedThrough) === null || _a === void 0 ? void 0 : _a.serviceType) === null || _b === void 0 ? void 0 : _b.codeValue); });
211
+ const isEligible = eligibleMembershipType.some((membershipType) =>
212
+ // FaceToFaceについては問答無用に受け入れる(2024-08-14~)
213
+ issuedThrough.typeOf === factory.service.paymentService.PaymentServiceType.FaceToFace
214
+ || membershipType.codeValue === issuedThrough.serviceType.codeValue);
205
215
  if (!isEligible) {
206
216
  throw new factory.errors.Argument('programMembershipUsed', `${programMembershipUsed.identifier} is not eligible for the offer ${params.availableOffer.id}`);
207
217
  }
@@ -137,15 +137,31 @@ function acceptedOffers2amount(params) {
137
137
  return amount;
138
138
  }
139
139
  exports.acceptedOffers2amount = acceptedOffers2amount;
140
+ function acceptedOffers2programMembershipUsed(params) {
141
+ const programMembershipUsed = [];
142
+ const permitIdentifiers = [];
143
+ params.acceptedOffers.forEach(({ itemOffered }) => {
144
+ var _a;
145
+ if (((_a = itemOffered.programMembershipUsed) === null || _a === void 0 ? void 0 : _a.typeOf) === factory.permit.PermitType.Permit) {
146
+ // メンバーシップコードに対してユニークに集計
147
+ if (!permitIdentifiers.includes(itemOffered.programMembershipUsed.identifier)) {
148
+ permitIdentifiers.push(itemOffered.programMembershipUsed.identifier);
149
+ programMembershipUsed.push(itemOffered.programMembershipUsed);
150
+ }
151
+ }
152
+ });
153
+ return programMembershipUsed;
154
+ }
140
155
  function acceptedOffers2authorizeResult(params) {
141
156
  const { acceptedOffers, acceptedOffers4result, noOfferSpecified, ticketOffers } = params;
142
- // const priceCurrency = acceptedOffers[0]?.priceSpecification?.priceCurrency;
143
157
  const priceCurrency = factory.priceCurrency.JPY; // fix(2024-07-03~)
144
158
  // redefine as typeOf: AggregateOffer(2024-06-18~)
145
159
  let offers;
146
160
  let price;
161
+ let programMembershipUsed = [];
147
162
  if (!noOfferSpecified) {
148
163
  price = acceptedOffers2amount({ acceptedOffers: acceptedOffers4result }); // オファー指定の場合のみ金額計算(2023-11-27~)
164
+ programMembershipUsed = acceptedOffers2programMembershipUsed({ acceptedOffers: acceptedOffers4result });
149
165
  // オファーIDごとに集計
150
166
  const offerIds = [...new Set(acceptedOffers.map((o) => o.id))];
151
167
  offers = offerIds.map((offerId) => {
@@ -153,10 +169,6 @@ function acceptedOffers2authorizeResult(params) {
153
169
  if (acceptedOffer === undefined) {
154
170
  throw new factory.errors.Internal(`acceptedOffer not found [id:${offerId}]`);
155
171
  }
156
- // const acceptedOffer = acceptedOffers.find(({ id }) => id === offerId);
157
- // if (acceptedOffer === undefined) {
158
- // throw new factory.errors.Internal(`acceptedOffer not found [id:${offerId}]`);
159
- // }
160
172
  const amountOfThisGood = acceptedOffers.filter(({ id }) => id === offerId).length;
161
173
  const { acceptedPaymentMethod, priceSpecification } = acceptedOffer;
162
174
  const unitPriceSpec = priceSpecification.priceComponent.find((spec) => spec.typeOf === factory.priceSpecificationType.UnitPriceSpecification
@@ -169,7 +181,9 @@ function acceptedOffers2authorizeResult(params) {
169
181
  return Object.assign({ id: offerId, includesObject: { amountOfThisGood }, typeOf: factory.offerType.Offer, priceSpecification: Object.assign(Object.assign({}, (eligibleQuantity !== undefined) ? { eligibleQuantity } : undefined), (eligibleTransactionVolume !== undefined) ? { eligibleTransactionVolume } : undefined) }, (acceptedPaymentMethod !== undefined) ? { acceptedPaymentMethod } : undefined);
170
182
  });
171
183
  }
172
- return Object.assign(Object.assign({ typeOf: factory.offerType.AggregateOffer, priceCurrency, amount: [] }, (typeof price === 'number') ? { price } : undefined), (Array.isArray(offers)) ? { offers } : undefined);
184
+ return Object.assign(Object.assign({ typeOf: factory.offerType.AggregateOffer, priceCurrency, amount: [], itemOffered: {
185
+ serviceOutput: { programMembershipUsed } // add programMembershipUsed required(2024-08-15~)
186
+ } }, (typeof price === 'number') ? { price } : undefined), (Array.isArray(offers)) ? { offers } : undefined);
173
187
  }
174
188
  exports.acceptedOffers2authorizeResult = acceptedOffers2authorizeResult;
175
189
  function responseBody2acceptedOffers4result(params) {
@@ -0,0 +1,24 @@
1
+ import * as factory from '../../../../../factory';
2
+ import type { JWTCredentials } from '../../../../../credentials/jwt';
3
+ import type { ActionRepo } from '../../../../../repo/action';
4
+ import type { AuthorizationRepo } from '../../../../../repo/authorization';
5
+ import type { TicketRepo } from '../../../../../repo/ticket';
6
+ /**
7
+ * チケット化された適用メンバーシップをPermitに変換する
8
+ */
9
+ declare function requestedProgramMembershipUsed2permit(params: {
10
+ project: {
11
+ id: string;
12
+ };
13
+ programMembershipUsed?: factory.assetTransaction.reserve.IAcceptedProgramMembershipUsed;
14
+ placeOrder: {
15
+ id: string;
16
+ };
17
+ }): (repos: {
18
+ action: ActionRepo;
19
+ authorization: AuthorizationRepo;
20
+ ticket: TicketRepo;
21
+ }, credentials: {
22
+ jwt: JWTCredentials;
23
+ }) => Promise<factory.assetTransaction.reserve.IPermitIssuedThroughFaceToFace | factory.assetTransaction.reserve.IPermitIssuedThroughMembershipService | undefined>;
24
+ export { requestedProgramMembershipUsed2permit };
@@ -0,0 +1,127 @@
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.requestedProgramMembershipUsed2permit = void 0;
13
+ const factory = require("../../../../../factory");
14
+ const CodeService = require("../../../../code");
15
+ /**
16
+ * チケット化された適用メンバーシップをPermitに変換する
17
+ */
18
+ function requestedProgramMembershipUsed2permit(params) {
19
+ // tslint:disable-next-line:cyclomatic-complexity max-func-body-length
20
+ return (repos, credentials) => __awaiter(this, void 0, void 0, function* () {
21
+ var _a, _b, _c, _d;
22
+ let programMembershipUsedAsPermit;
23
+ const { programMembershipUsed, placeOrder } = params;
24
+ // トークン化されたメンバーシップがリクエストされた場合、実メンバーシップ情報へ変換する
25
+ if (typeof programMembershipUsed === 'string') {
26
+ const { authorizedObject } = yield CodeService.verifyToken({
27
+ project: { id: params.project.id },
28
+ agent: { id: params.project.id, typeOf: factory.organizationType.Project },
29
+ token: String(programMembershipUsed)
30
+ })(repos, credentials);
31
+ const permitOwnershipInfo = authorizedObject;
32
+ if (Array.isArray(permitOwnershipInfo)) {
33
+ throw new factory.errors.NotImplemented('programMembershipUsed as an array not implemented');
34
+ }
35
+ if (permitOwnershipInfo.typeOf !== 'OwnershipInfo') {
36
+ throw new factory.errors.Argument('programMembershipUsed', 'must be OwnershipInfo');
37
+ }
38
+ const typeOfGood = permitOwnershipInfo.typeOfGood;
39
+ if (typeOfGood.typeOf !== factory.permit.PermitType.Permit) {
40
+ throw new factory.errors.Argument('programMembershipUsed', 'must be Permit');
41
+ }
42
+ const issuedThroughTypeOf = (_a = typeOfGood.issuedThrough) === null || _a === void 0 ? void 0 : _a.typeOf;
43
+ if (issuedThroughTypeOf !== factory.product.ProductType.MembershipService) {
44
+ throw new factory.errors.Argument('programMembershipUsed', 'must be issued through MembershipService');
45
+ }
46
+ if (typeof ((_b = typeOfGood.issuedThrough) === null || _b === void 0 ? void 0 : _b.id) !== 'string') {
47
+ throw new factory.errors.NotFound('itemOffered.serviceOutput.programMembershipUsed.issuedThrough.id');
48
+ }
49
+ if (issuedThroughTypeOf === factory.product.ProductType.MembershipService) {
50
+ programMembershipUsedAsPermit = {
51
+ identifier: typeOfGood.identifier,
52
+ issuedThrough: { id: typeOfGood.issuedThrough.id, typeOf: issuedThroughTypeOf },
53
+ typeOf: factory.permit.PermitType.Permit
54
+ };
55
+ }
56
+ else {
57
+ throw new factory.errors.Argument('programMembershipUsed', `invalid issuedThrough.typeOf: ${issuedThroughTypeOf}`);
58
+ }
59
+ }
60
+ else if ((programMembershipUsed === null || programMembershipUsed === void 0 ? void 0 : programMembershipUsed.typeOf) === 'Ticket') {
61
+ const { ticketToken } = programMembershipUsed;
62
+ if (typeof ticketToken === 'string') {
63
+ const ticket = (yield repos.ticket.search({
64
+ limit: 1,
65
+ page: 1,
66
+ project: { id: { $eq: params.project.id } },
67
+ ticketToken: { $eq: ticketToken }
68
+ })).shift();
69
+ if (ticket === undefined) {
70
+ throw new factory.errors.NotFound('Ticket');
71
+ }
72
+ // 承認を参照
73
+ const { audience, object } = yield repos.authorization.findValidOneByCode({
74
+ project: { id: params.project.id },
75
+ code: ticket.ticketToken
76
+ });
77
+ if (object.typeOf !== 'OwnershipInfo') {
78
+ throw new factory.errors.Argument('programMembershipUsed', 'invalid authorization');
79
+ }
80
+ // const ownershipInfoId = object.id;
81
+ // const permitOwnershipInfo = (await repos.ownershipInfo.search({
82
+ // limit: 1,
83
+ // page: 1,
84
+ // project: { id: { $eq: params.project.id } },
85
+ // ids: [ownershipInfoId],
86
+ // ownedFrom: now,
87
+ // ownedThrough: now
88
+ // })).shift();
89
+ // if (permitOwnershipInfo === undefined) {
90
+ // throw new factory.errors.NotFound('OwnershipInfo');
91
+ // }
92
+ // audience検証
93
+ if ((audience === null || audience === void 0 ? void 0 : audience.typeOf) !== factory.transactionType.PlaceOrder || audience.id !== placeOrder.id) {
94
+ throw new factory.errors.Argument('programMembershipUsed', 'audience not matched with placeOrder');
95
+ }
96
+ const permitOwnershipInfo = object;
97
+ if (permitOwnershipInfo.typeOfGood.typeOf !== factory.permit.PermitType.Permit) {
98
+ throw new factory.errors.Argument('programMembershipUsed', 'ownershipInfo.typeOfGood.typeOf must be Permit');
99
+ }
100
+ const issuedThroughTypeOf = (_c = permitOwnershipInfo.typeOfGood.issuedThrough) === null || _c === void 0 ? void 0 : _c.typeOf;
101
+ if (issuedThroughTypeOf === factory.service.paymentService.PaymentServiceType.FaceToFace) {
102
+ programMembershipUsedAsPermit = {
103
+ identifier: permitOwnershipInfo.typeOfGood.identifier,
104
+ issuedThrough: { typeOf: issuedThroughTypeOf },
105
+ typeOf: factory.permit.PermitType.Permit
106
+ };
107
+ }
108
+ else if (issuedThroughTypeOf === factory.product.ProductType.MembershipService
109
+ || issuedThroughTypeOf === factory.service.paymentService.PaymentServiceType.CreditCard) {
110
+ if (typeof ((_d = permitOwnershipInfo.typeOfGood.issuedThrough) === null || _d === void 0 ? void 0 : _d.id) !== 'string') {
111
+ throw new factory.errors.Argument('programMembershipUsed', 'ownershipInfo.typeOfGood.issuedThrough.id undefined');
112
+ }
113
+ programMembershipUsedAsPermit = {
114
+ identifier: permitOwnershipInfo.typeOfGood.identifier,
115
+ issuedThrough: { id: permitOwnershipInfo.typeOfGood.issuedThrough.id, typeOf: issuedThroughTypeOf },
116
+ typeOf: factory.permit.PermitType.Permit
117
+ };
118
+ }
119
+ else {
120
+ throw new factory.errors.Argument('programMembershipUsed', `invalid issuedThrough.typeOf: ${issuedThroughTypeOf}`);
121
+ }
122
+ }
123
+ }
124
+ return programMembershipUsedAsPermit;
125
+ });
126
+ }
127
+ exports.requestedProgramMembershipUsed2permit = requestedProgramMembershipUsed2permit;
@@ -12,8 +12,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.processStartReserve4chevre = void 0;
13
13
  const factory = require("../../../../factory");
14
14
  const ReserveTransactionService = require("../../../assetTransaction/reserve");
15
- const CodeService = require("../../../code");
16
15
  const factory_1 = require("./factory");
16
+ const requestedProgramMembershipUsed2permit_1 = require("./processStartReserve4chevre/requestedProgramMembershipUsed2permit");
17
17
  function processStartReserve4chevre(params, options) {
18
18
  return (repos, credentials) => __awaiter(this, void 0, void 0, function* () {
19
19
  const { event, transaction, transactionNumber } = params;
@@ -23,7 +23,7 @@ function processStartReserve4chevre(params, options) {
23
23
  // object: <IObjectWithDetail>action.object,
24
24
  acceptedOffers: params.acceptedOffers, event: { id: event.id }, transaction,
25
25
  transactionNumber }, (params.broker !== undefined) ? { broker: params.broker } : undefined));
26
- const startParamObject = yield validateObjectWithoutDetail(startParams)(repos, credentials);
26
+ const startParamObject = yield validateObjectWithoutDetail(startParams, { id: params.transaction.id })(repos, credentials);
27
27
  const startReserveTransactionResult = yield ReserveTransactionService.start(Object.assign(Object.assign({}, startParams), { object: startParamObject,
28
28
  // discontinue preSearchedEvent(2024-07-17~)
29
29
  // preSearchedEvent: event,
@@ -44,41 +44,21 @@ function processStartReserve4chevre(params, options) {
44
44
  });
45
45
  }
46
46
  exports.processStartReserve4chevre = processStartReserve4chevre;
47
- function validateObjectWithoutDetail(params) {
47
+ function validateObjectWithoutDetail(params, placeOrder) {
48
48
  return (repos, credentials) => __awaiter(this, void 0, void 0, function* () {
49
- var _a, _b, _c, _d;
49
+ var _a, _b, _c;
50
50
  const objectWithoutDetail = params.object;
51
51
  if (Array.isArray(objectWithoutDetail.acceptedOffer)) {
52
52
  const validatedAcceptedOffersWithoutDetail = [];
53
53
  for (let acceptedOffer of objectWithoutDetail.acceptedOffer) {
54
- let programMembershipUsed = (_b = (_a = acceptedOffer.itemOffered) === null || _a === void 0 ? void 0 : _a.serviceOutput) === null || _b === void 0 ? void 0 : _b.programMembershipUsed;
55
- // トークン化されたメンバーシップがリクエストされた場合、実メンバーシップ情報へ変換する
56
- if (typeof programMembershipUsed === 'string' && programMembershipUsed.length > 0) {
57
- const { authorizedObject } = yield CodeService.verifyToken({
58
- project: params.project,
59
- agent: params.project,
60
- token: String(programMembershipUsed)
61
- })(repos, credentials);
62
- const permitOwnershipInfo = authorizedObject;
63
- if (Array.isArray(permitOwnershipInfo)) {
64
- throw new factory.errors.NotImplemented('programMembershipUsed as an array not implemented');
65
- }
66
- if (permitOwnershipInfo.typeOf !== 'OwnershipInfo') {
67
- throw new factory.errors.Argument('programMembershipUsed', 'must be OwnershipInfo');
68
- }
69
- if (permitOwnershipInfo.typeOfGood.typeOf !== factory.permit.PermitType.Permit) {
70
- throw new factory.errors.Argument('programMembershipUsed', 'must be Permit');
71
- }
72
- const typeOfGood = permitOwnershipInfo.typeOfGood;
73
- const issuedThroughId = (_c = typeOfGood.issuedThrough) === null || _c === void 0 ? void 0 : _c.id;
74
- if (typeof issuedThroughId !== 'string' || issuedThroughId.length === 0) {
75
- throw new factory.errors.NotFound('itemOffered.serviceOutput.programMembershipUsed.issuedThrough.id');
76
- }
77
- programMembershipUsed = {
78
- identifier: String(typeOfGood.identifier),
79
- issuedThrough: { id: issuedThroughId }
80
- };
81
- acceptedOffer = Object.assign(Object.assign({}, acceptedOffer), { itemOffered: Object.assign(Object.assign({}, acceptedOffer.itemOffered), { serviceOutput: Object.assign(Object.assign({}, (_d = acceptedOffer.itemOffered) === null || _d === void 0 ? void 0 : _d.serviceOutput), { typeOf: factory.reservationType.EventReservation, programMembershipUsed }) }) });
54
+ const programMembershipUsedAsPermit = yield (0, requestedProgramMembershipUsed2permit_1.requestedProgramMembershipUsed2permit)({
55
+ project: { id: params.project.id },
56
+ programMembershipUsed: (_b = (_a = acceptedOffer.itemOffered) === null || _a === void 0 ? void 0 : _a.serviceOutput) === null || _b === void 0 ? void 0 : _b.programMembershipUsed,
57
+ placeOrder: { id: placeOrder.id }
58
+ })(repos, credentials);
59
+ // 適用メンバーシップがあればacceptedOfferを強制的に上書き
60
+ if (programMembershipUsedAsPermit !== undefined) {
61
+ acceptedOffer = Object.assign(Object.assign({}, acceptedOffer), { itemOffered: Object.assign(Object.assign({}, acceptedOffer.itemOffered), { serviceOutput: Object.assign(Object.assign({}, (_c = acceptedOffer.itemOffered) === null || _c === void 0 ? void 0 : _c.serviceOutput), { typeOf: factory.reservationType.EventReservation, programMembershipUsed: programMembershipUsedAsPermit }) }) });
82
62
  }
83
63
  validatedAcceptedOffersWithoutDetail.push(acceptedOffer);
84
64
  }
@@ -4,6 +4,8 @@ declare function coaTicket2offer(params: {
4
4
  theaterCode: string;
5
5
  ticketResult: COA.factory.master.ITicketResult;
6
6
  defaultCurrencyType?: factory.categoryCode.ICategoryCode;
7
- defaultMembershipType?: factory.categoryCode.ICategoryCode;
7
+ defaultMembershipType?: factory.categoryCode.ICategoryCode & {
8
+ id: string;
9
+ };
8
10
  }): factory.aggregateOffer.ISubOffer;
9
11
  export { coaTicket2offer };
@@ -86,7 +86,8 @@ function sendOrder(params) {
86
86
  typeOf: factory.actionType.SendAction
87
87
  };
88
88
  const action = yield repos.action.start(sendOrderActionAttributes);
89
- let ownershipInfos = [];
89
+ let creatingOwnershipInfos = [];
90
+ let createdOwnershipInfos = [];
90
91
  let allOffersDelivered = false;
91
92
  let acceptedOffers;
92
93
  // 所有権生成を最小化(2024-03-01~)
@@ -111,12 +112,15 @@ function sendOrder(params) {
111
112
  debug('delivering...', order.orderNumber, acceptedOffers.map((offer) => `${offer.itemOffered.id}`), params.object.acceptedOffers, 'offerIndexBase:', offerIndexBase);
112
113
  // 所有権作成
113
114
  if (createOwnerships) {
114
- ownershipInfos = (0, factory_1.createOwnershipInfosFromOrder)({
115
+ creatingOwnershipInfos = (0, factory_1.createOwnershipInfosFromOrder)({
115
116
  order: Object.assign(Object.assign({}, order), { acceptedOffers }),
116
117
  offerIndexBase
117
118
  });
118
- ownershipInfos = yield Promise.all(ownershipInfos.map((ownershipInfo) => __awaiter(this, void 0, void 0, function* () {
119
- return repos.ownershipInfo.createIfNotExistByIdentifier(ownershipInfo);
119
+ createdOwnershipInfos = yield Promise.all(creatingOwnershipInfos.map((creatingOwnershipInfo) => __awaiter(this, void 0, void 0, function* () {
120
+ const { id } = yield repos.ownershipInfo.createIfNotExistByIdentifier(creatingOwnershipInfo);
121
+ return Object.assign({ id }, (typeof creatingOwnershipInfo.identifier === 'string')
122
+ ? { identifier: creatingOwnershipInfo.identifier }
123
+ : undefined);
120
124
  })));
121
125
  }
122
126
  // const deliveredCount = limit * page;
@@ -140,7 +144,7 @@ function sendOrder(params) {
140
144
  }
141
145
  throw error;
142
146
  }
143
- const result = ownershipInfos;
147
+ const result = createdOwnershipInfos;
144
148
  yield repos.action.completeWithVoid({ typeOf: sendOrderActionAttributes.typeOf, id: action.id, result: result });
145
149
  debug('allOffersDelivered?:', allOffersDelivered, order.orderNumber);
146
150
  if (params.useOnOrderStatusChanged) {
@@ -1,6 +1,5 @@
1
1
  import * as factory from '../../../factory';
2
2
  import type { AuthorizationRepo } from '../../../repo/authorization';
3
- import type { OwnershipInfoRepo } from '../../../repo/ownershipInfo';
4
3
  import type { TicketRepo } from '../../../repo/ticket';
5
4
  type IObjectWithoutDetail = factory.action.authorize.paymentMethod.any.IObjectWithoutDetail & {
6
5
  ticketToken?: string;
@@ -14,7 +13,6 @@ declare function verifyTicketTokenAsNeeded(params: {
14
13
  purpose: factory.action.authorize.paymentMethod.any.IPurpose;
15
14
  }): (repos: {
16
15
  authorization: AuthorizationRepo;
17
- ownershipInfo: OwnershipInfoRepo;
18
16
  ticket: TicketRepo;
19
17
  }) => Promise<{
20
18
  permit: Pick<factory.ownershipInfo.IPermitAsGood, 'identifier'> | undefined;
@@ -13,7 +13,7 @@ exports.verifyTicketTokenAsNeeded = void 0;
13
13
  const factory = require("../../../factory");
14
14
  function verifyTicketTokenAsNeeded(params) {
15
15
  return (repos) => __awaiter(this, void 0, void 0, function* () {
16
- var _a;
16
+ var _a, _b;
17
17
  const { paymentServiceType, object, project } = params;
18
18
  const { ticketToken } = object;
19
19
  let permit;
@@ -41,32 +41,29 @@ function verifyTicketTokenAsNeeded(params) {
41
41
  if (authorizedObject.typeOf !== 'OwnershipInfo') {
42
42
  throw new factory.errors.Argument('ticketToken', 'must be OwnershipInfo');
43
43
  }
44
- const ownershipInfoId = authorizedObject.id;
45
- const permitOwnershipInfo = (yield repos.ownershipInfo.search({
46
- limit: 1,
47
- page: 1,
48
- project: { id: { $eq: params.project.id } },
49
- ids: [ownershipInfoId]
50
- })).shift();
51
- if (permitOwnershipInfo === undefined) {
52
- throw new factory.errors.NotFound('OwnershipInfo');
44
+ // audience検証
45
+ if (((_a = validAuthorization.audience) === null || _a === void 0 ? void 0 : _a.typeOf) !== factory.transactionType.PlaceOrder
46
+ || validAuthorization.audience.id !== params.purpose.id) {
47
+ throw new factory.errors.Argument('ticketToken', 'audience not matched with placeOrder');
53
48
  }
54
- const { ownedBy, typeOfGood } = permitOwnershipInfo;
49
+ const permitOwnershipInfo = authorizedObject;
50
+ // const ownershipInfoId = authorizedObject.id;
51
+ // const permitOwnershipInfo = (await repos.ownershipInfo.search({
52
+ // limit: 1,
53
+ // page: 1,
54
+ // project: { id: { $eq: params.project.id } },
55
+ // ids: [ownershipInfoId]
56
+ // })).shift();
57
+ // if (permitOwnershipInfo === undefined) {
58
+ // throw new factory.errors.NotFound('OwnershipInfo');
59
+ // }
60
+ const { typeOfGood } = permitOwnershipInfo;
55
61
  if (typeOfGood.typeOf !== factory.permit.PermitType.Permit) {
56
62
  throw new factory.errors.Argument('ticketToken', 'must be Permit');
57
63
  }
58
- if (((_a = typeOfGood.issuedThrough) === null || _a === void 0 ? void 0 : _a.typeOf) !== paymentServiceType) {
64
+ if (((_b = typeOfGood.issuedThrough) === null || _b === void 0 ? void 0 : _b.typeOf) !== paymentServiceType) {
59
65
  throw new factory.errors.Argument('ticketToken', 'paymentServiceType not matched');
60
66
  }
61
- if (!Array.isArray(ownedBy)) {
62
- throw new factory.errors.Argument('ticketToken', 'ownershipInfo.ownedBy must be Array');
63
- }
64
- if (ownedBy[0].typeOf !== factory.transactionType.PlaceOrder) {
65
- throw new factory.errors.Argument('ticketToken', 'ownershipInfo.ownedBy.typeOf must be PlaceOrder');
66
- }
67
- if (ownedBy[0].id !== params.purpose.id) {
68
- throw new factory.errors.Argument('ticketToken', 'ownershipInfo.ownedBy.id not matched');
69
- }
70
67
  permit = { identifier: typeOfGood.identifier };
71
68
  }
72
69
  break;
@@ -10,7 +10,6 @@ import type { AssetTransactionRepo } from '../../repo/assetTransaction';
10
10
  import type { AuthorizationRepo } from '../../repo/authorization';
11
11
  import type { ConfirmationNumberRepo } from '../../repo/confirmationNumber';
12
12
  import type { EventRepo } from '../../repo/event';
13
- import type { OwnershipInfoRepo } from '../../repo/ownershipInfo';
14
13
  import type { PaymentServiceRepo } from '../../repo/paymentService';
15
14
  import type { PaymentServiceProviderRepo } from '../../repo/paymentServiceProvider';
16
15
  import type { ProductRepo } from '../../repo/product';
@@ -80,7 +79,6 @@ interface IAuthorizeRepos {
80
79
  authorization: AuthorizationRepo;
81
80
  confirmationNumber: ConfirmationNumberRepo;
82
81
  event: EventRepo;
83
- ownershipInfo: OwnershipInfoRepo;
84
82
  paymentAccepted: SellerPaymentAcceptedRepo;
85
83
  paymentService: PaymentServiceRepo;
86
84
  paymentServiceProvider: PaymentServiceProviderRepo;
@@ -21,5 +21,7 @@ export interface IOwnershipInfoReport {
21
21
  };
22
22
  }
23
23
  export declare function ownershipInfo2report(params: {
24
- ownershipInfo: factory.ownershipInfo.IOwnershipInfo<factory.ownershipInfo.IGood>;
24
+ ownershipInfo: factory.ownershipInfo.IOwnershipInfo<factory.ownershipInfo.IGood> & {
25
+ id: string;
26
+ };
25
27
  }): IOwnershipInfoReport;
@@ -17,7 +17,6 @@ const assetTransaction_1 = require("../../repo/assetTransaction");
17
17
  const authorization_1 = require("../../repo/authorization");
18
18
  const confirmationNumber_1 = require("../../repo/confirmationNumber");
19
19
  const event_1 = require("../../repo/event");
20
- const ownershipInfo_1 = require("../../repo/ownershipInfo");
21
20
  const paymentService_1 = require("../../repo/paymentService");
22
21
  const paymentServiceProvider_1 = require("../../repo/paymentServiceProvider");
23
22
  const product_1 = require("../../repo/product");
@@ -55,7 +54,6 @@ function call(params) {
55
54
  authorization: new authorization_1.AuthorizationRepo(connection),
56
55
  confirmationNumber: new confirmationNumber_1.ConfirmationNumberRepo(redisClient),
57
56
  event: new event_1.EventRepo(connection),
58
- ownershipInfo: new ownershipInfo_1.OwnershipInfoRepo(connection),
59
57
  paymentAccepted: new sellerPaymentAccepted_1.SellerPaymentAcceptedRepo(connection),
60
58
  paymentService: new paymentService_1.PaymentServiceRepo(connection),
61
59
  paymentServiceProvider: new paymentServiceProvider_1.PaymentServiceProviderRepo(connection),
@@ -70,7 +70,7 @@ function onAuthorizationCreated(params) {
70
70
  // 所有権検索
71
71
  const ownershipInfoId = authorization.object.id;
72
72
  if (typeof ownershipInfoId === 'string' && ownershipInfoId.length > 0) {
73
- const ownershipInfo = yield repos.ownershipInfo.findById({ id: ownershipInfoId });
73
+ const ownershipInfo = yield repos.ownershipInfo.projectFieldsById({ id: ownershipInfoId }, ['typeOfGood']);
74
74
  // 座席予約に対する所有権であれば発券
75
75
  if (ownershipInfo.typeOfGood.typeOf === factory.reservationType.EventReservation
76
76
  || ownershipInfo.typeOfGood.typeOf === factory.reservationType.BusReservation) {
@@ -368,6 +368,7 @@ function processMoneyTransferTransaction(params) {
368
368
  return pendingTransaction;
369
369
  });
370
370
  }
371
+ // tslint:disable-next-line:max-func-body-length
371
372
  function validateFromLocation(project, fromLocationBeforeStart, issuedThrough) {
372
373
  return (repos, credentials) => __awaiter(this, void 0, void 0, function* () {
373
374
  var _a, _b, _c;
@@ -389,10 +390,13 @@ function validateFromLocation(project, fromLocationBeforeStart, issuedThrough) {
389
390
  if (paymentCardOwnershipInfo.typeOfGood.typeOf !== factory.permit.PermitType.Permit) {
390
391
  throw new factory.errors.Argument('fromLocation', 'must be Permit');
391
392
  }
393
+ if (((_a = paymentCardOwnershipInfo.typeOfGood.issuedThrough) === null || _a === void 0 ? void 0 : _a.typeOf) !== factory.product.ProductType.PaymentCard) {
394
+ throw new factory.errors.Argument('fromLocation', 'must be issued through PaymentCard');
395
+ }
392
396
  fromLocation = {
393
397
  typeOf: paymentCardOwnershipInfo.typeOfGood.typeOf,
394
398
  identifier: paymentCardOwnershipInfo.typeOfGood.identifier,
395
- issuedThrough: { id: String((_a = paymentCardOwnershipInfo.typeOfGood.issuedThrough) === null || _a === void 0 ? void 0 : _a.id) }
399
+ issuedThrough: { id: paymentCardOwnershipInfo.typeOfGood.issuedThrough.id }
396
400
  };
397
401
  }
398
402
  else {
@@ -41,7 +41,7 @@ export declare function validatePaymentMethods(params: {
41
41
  * 興行オファー適用条件確認
42
42
  */
43
43
  export declare function validateEventOffers(params: {
44
- order: factory.transaction.placeOrder.IOrderAsResult;
44
+ order: Pick<factory.transaction.placeOrder.IOrderAsResult, 'price'>;
45
45
  paymentMethods: factory.order.IReferencedInvoice[];
46
46
  authorizeEventServiceOfferActions: Pick<IAuthorizeEventServiceOffer, 'id' | 'instrument' | 'object' | 'result'>[];
47
47
  }): void;
@@ -350,11 +350,12 @@ exports.validatePaymentMethods = validatePaymentMethods;
350
350
  // tslint:disable-next-line:max-func-body-length
351
351
  function validateEventOffers(params) {
352
352
  var _a, _b;
353
- const firstCreditCardPaymentMethodIdentifier = (_b = (_a = params.paymentMethods.find((referenceInvoice) => {
353
+ const { paymentMethods } = params;
354
+ const firstCreditCardPaymentMethodIdentifier = (_b = (_a = paymentMethods.find((referenceInvoice) => {
354
355
  return referenceInvoice.issuedThrough.typeOf === factory.service.paymentService.PaymentServiceType.CreditCard
355
356
  || referenceInvoice.issuedThrough.typeOf === factory.service.paymentService.PaymentServiceType.FaceToFace;
356
357
  })) === null || _a === void 0 ? void 0 : _a.paymentMethod) === null || _b === void 0 ? void 0 : _b.identifier;
357
- const numCreditCardOrFaceToFacePaymentMethod = params.paymentMethods.filter((referenceInvoice) => {
358
+ const numCreditCardOrFaceToFacePaymentMethod = paymentMethods.filter((referenceInvoice) => {
358
359
  return referenceInvoice.issuedThrough.typeOf === factory.service.paymentService.PaymentServiceType.CreditCard
359
360
  || referenceInvoice.issuedThrough.typeOf === factory.service.paymentService.PaymentServiceType.FaceToFace;
360
361
  }).length;
@@ -411,5 +412,38 @@ function validateEventOffers(params) {
411
412
  });
412
413
  }
413
414
  });
415
+ // check programMembershipUsed(2024-08-15~)
416
+ const programMembershipRequired = params.authorizeEventServiceOfferActions.reduce((a, b) => {
417
+ var _a, _b;
418
+ const programMembershipUsedfromResult = (_b = (_a = b.result) === null || _a === void 0 ? void 0 : _a.itemOffered) === null || _b === void 0 ? void 0 : _b.serviceOutput.programMembershipUsed;
419
+ if (Array.isArray(programMembershipUsedfromResult)) {
420
+ a.push(...programMembershipUsedfromResult);
421
+ }
422
+ return a;
423
+ }, []);
424
+ const satisfyProgramMembershipRequirement = programMembershipRequired.every(({ identifier, issuedThrough }) => {
425
+ let satisfyThisRequirement = false;
426
+ switch (issuedThrough.typeOf) {
427
+ case factory.product.ProductType.MembershipService:
428
+ // 検証の必要なし
429
+ satisfyThisRequirement = true;
430
+ break;
431
+ case factory.service.paymentService.PaymentServiceType.CreditCard:
432
+ satisfyThisRequirement = paymentMethods.some((paymentMethod) => paymentMethod.paymentMethodId === identifier
433
+ && paymentMethod.issuedThrough.id === issuedThrough.id
434
+ && paymentMethod.issuedThrough.typeOf === issuedThrough.typeOf);
435
+ break;
436
+ case factory.service.paymentService.PaymentServiceType.FaceToFace:
437
+ satisfyThisRequirement = paymentMethods.some((paymentMethod) => paymentMethod.paymentMethodId === identifier
438
+ && paymentMethod.issuedThrough.typeOf === issuedThrough.typeOf);
439
+ break;
440
+ default:
441
+ // no op
442
+ }
443
+ return satisfyThisRequirement;
444
+ });
445
+ if (!satisfyProgramMembershipRequirement) {
446
+ throw new factory.errors.Argument('Transaction', `programMembershipUsed requirement not satisfied`);
447
+ }
414
448
  }
415
449
  exports.validateEventOffers = validateEventOffers;
@@ -293,7 +293,7 @@ function createResult(params, options) {
293
293
  price
294
294
  });
295
295
  (0, validation_1.validateEventOffers)({
296
- order: orderAsResult,
296
+ order: { price },
297
297
  paymentMethods,
298
298
  authorizeEventServiceOfferActions: params.authorizeEventServiceOfferActions
299
299
  });
package/package.json CHANGED
@@ -9,8 +9,8 @@
9
9
  }
10
10
  ],
11
11
  "dependencies": {
12
- "@chevre/factory": "4.381.0-alpha.1",
13
- "@cinerino/sdk": "10.5.0-alpha.0",
12
+ "@chevre/factory": "4.381.0-alpha.7",
13
+ "@cinerino/sdk": "10.5.0-alpha.2",
14
14
  "@motionpicture/coa-service": "9.4.0",
15
15
  "@motionpicture/gmo-service": "5.3.0",
16
16
  "@sendgrid/mail": "6.4.0",
@@ -110,5 +110,5 @@
110
110
  "postversion": "git push origin --tags",
111
111
  "prepublishOnly": "npm run clean && npm run build && npm test && npm run doc"
112
112
  },
113
- "version": "22.2.0-alpha.0"
113
+ "version": "22.2.0-alpha.10"
114
114
  }