@chevre/domain 23.1.0-alpha.1 → 23.1.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/example/src/chevre/assetTransaction/processReserve.ts +9 -3
- package/example/src/chevre/authorizeEventServiceOffer.ts +8 -5
- package/example/src/chevre/eventOffer/adminEventOffers.ts +67 -0
- package/example/src/chevre/member/migrateMemberIdentifier.ts +99 -0
- package/example/src/chevre/reIndex.ts +2 -2
- package/lib/chevre/repo/eventOffer.d.ts +52 -0
- package/lib/chevre/repo/eventOffer.js +191 -0
- package/lib/chevre/repo/member.d.ts +18 -1
- package/lib/chevre/repo/member.js +14 -8
- package/lib/chevre/repo/mongoose/schemas/eventOffer.d.ts +10 -0
- package/lib/chevre/repo/mongoose/schemas/eventOffer.js +102 -0
- package/lib/chevre/repo/mongoose/schemas/member.js +10 -0
- package/lib/chevre/repository.d.ts +5 -0
- package/lib/chevre/repository.js +15 -2
- package/lib/chevre/service/assetTransaction/reserve/start.d.ts +8 -0
- package/lib/chevre/service/assetTransaction/reserve/start.js +6 -1
- package/lib/chevre/service/assetTransaction/reserve/validateStartRequest/fixExtendedEventOffer.d.ts +22 -0
- package/lib/chevre/service/assetTransaction/reserve/validateStartRequest/fixExtendedEventOffer.js +63 -0
- package/lib/chevre/service/assetTransaction/reserve/validateStartRequest/validateIssuedOfferIfExists.d.ts +7 -2
- package/lib/chevre/service/assetTransaction/reserve/validateStartRequest/validateIssuedOfferIfExists.js +30 -30
- package/lib/chevre/service/assetTransaction/reserve/validateStartRequest/validateMemberTierIfExists.d.ts +1 -1
- package/lib/chevre/service/assetTransaction/reserve/validateStartRequest/validateMemberTierIfExists.js +10 -26
- package/lib/chevre/service/assetTransaction/reserve/validateStartRequest/verifyTicketTokenAsNeeded.d.ts +23 -0
- package/lib/chevre/service/assetTransaction/reserve/validateStartRequest/verifyTicketTokenAsNeeded.js +62 -0
- package/lib/chevre/service/assetTransaction/reserve/validateStartRequest.d.ts +38 -1
- package/lib/chevre/service/assetTransaction/reserve/validateStartRequest.js +39 -19
- package/lib/chevre/service/offer/event/authorize/factory.d.ts +0 -3
- package/lib/chevre/service/offer/event/authorize/factory.js +4 -3
- package/lib/chevre/service/offer/event/authorize/processStartReserve4chevre/requestedProgramMembershipUsed2permit.js +42 -25
- package/lib/chevre/service/offer/event/authorize/processStartReserve4chevre.d.ts +6 -0
- package/lib/chevre/service/offer/event/authorize/processStartReserve4chevre.js +4 -4
- package/lib/chevre/service/offer/event/authorize.d.ts +5 -0
- package/lib/chevre/service/offer/event/authorize.js +10 -5
- package/lib/chevre/service/offer/event/issueEventOfferTicket.d.ts +48 -0
- package/lib/chevre/service/offer/event/issueEventOfferTicket.js +123 -0
- package/lib/chevre/service/offer/event.d.ts +2 -1
- package/lib/chevre/service/offer/event.js +3 -1
- package/lib/chevre/service/offer/onEventChanged.js +29 -13
- package/lib/chevre/service/payment/any/verifyTicketTokenAsNeeded.js +29 -23
- package/package.json +3 -3
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.modelName = exports.indexes = void 0;
|
|
4
|
+
exports.createSchema = createSchema;
|
|
5
|
+
const mongoose_1 = require("mongoose");
|
|
6
|
+
const settings_1 = require("../../../settings");
|
|
7
|
+
const writeConcern_1 = require("../writeConcern");
|
|
8
|
+
const modelName = 'EventOffer';
|
|
9
|
+
exports.modelName = modelName;
|
|
10
|
+
const schemaDefinition = {
|
|
11
|
+
project: { type: mongoose_1.SchemaTypes.Mixed, required: true },
|
|
12
|
+
seller: { type: mongoose_1.SchemaTypes.Mixed, required: true },
|
|
13
|
+
typeOf: { type: String, required: true },
|
|
14
|
+
identifier: { type: String, required: true },
|
|
15
|
+
itemOffered: { type: mongoose_1.SchemaTypes.Mixed, required: true },
|
|
16
|
+
validFrom: { type: Date, required: true },
|
|
17
|
+
validThrough: { type: Date, required: true },
|
|
18
|
+
availableAtOrFrom: { type: mongoose_1.SchemaTypes.Mixed, required: true },
|
|
19
|
+
offeredBy: { type: mongoose_1.SchemaTypes.Mixed, required: false }
|
|
20
|
+
// availability: { type: String, required: true }
|
|
21
|
+
};
|
|
22
|
+
const schemaOptions = {
|
|
23
|
+
autoIndex: settings_1.MONGO_AUTO_INDEX,
|
|
24
|
+
autoCreate: false,
|
|
25
|
+
collection: 'eventOffers',
|
|
26
|
+
id: true,
|
|
27
|
+
read: settings_1.MONGO_READ_PREFERENCE,
|
|
28
|
+
writeConcern: writeConcern_1.writeConcern,
|
|
29
|
+
strict: true,
|
|
30
|
+
strictQuery: false,
|
|
31
|
+
timestamps: false,
|
|
32
|
+
versionKey: false,
|
|
33
|
+
toJSON: {
|
|
34
|
+
getters: false,
|
|
35
|
+
virtuals: false,
|
|
36
|
+
minimize: false,
|
|
37
|
+
versionKey: false
|
|
38
|
+
},
|
|
39
|
+
toObject: {
|
|
40
|
+
getters: false,
|
|
41
|
+
virtuals: true,
|
|
42
|
+
minimize: false,
|
|
43
|
+
versionKey: false
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const indexes = [
|
|
47
|
+
[
|
|
48
|
+
{ validFrom: 1 },
|
|
49
|
+
{ name: 'validFrom' }
|
|
50
|
+
],
|
|
51
|
+
[
|
|
52
|
+
{ validThrough: 1, validFrom: 1 },
|
|
53
|
+
{ name: 'validThrough' }
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
{
|
|
57
|
+
'project.id': 1,
|
|
58
|
+
'itemOffered.id': 1,
|
|
59
|
+
identifier: 1
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'uniqueByItemOfferedAndIdentifier',
|
|
63
|
+
unique: true
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
{ 'project.id': 1, validFrom: 1 },
|
|
68
|
+
{ name: 'projectId' }
|
|
69
|
+
],
|
|
70
|
+
[
|
|
71
|
+
{ 'seller.id': 1, validFrom: 1 },
|
|
72
|
+
{ name: 'sellerId' }
|
|
73
|
+
],
|
|
74
|
+
[
|
|
75
|
+
{ identifier: 1, validFrom: 1 },
|
|
76
|
+
{ name: 'identifier' }
|
|
77
|
+
],
|
|
78
|
+
[
|
|
79
|
+
{ 'itemOffered.id': 1, validFrom: 1 },
|
|
80
|
+
{ name: 'itemOfferedId' }
|
|
81
|
+
],
|
|
82
|
+
[
|
|
83
|
+
{ 'availableAtOrFrom.identifier': 1, validFrom: 1 },
|
|
84
|
+
{ name: 'availableAtOrFrom' }
|
|
85
|
+
]
|
|
86
|
+
];
|
|
87
|
+
exports.indexes = indexes;
|
|
88
|
+
/**
|
|
89
|
+
* 拡張イベントオファースキーマ
|
|
90
|
+
*/
|
|
91
|
+
let schema;
|
|
92
|
+
function createSchema() {
|
|
93
|
+
if (schema === undefined) {
|
|
94
|
+
schema = new mongoose_1.Schema(schemaDefinition, schemaOptions);
|
|
95
|
+
if (settings_1.MONGO_AUTO_INDEX) {
|
|
96
|
+
indexes.forEach((indexParams) => {
|
|
97
|
+
schema === null || schema === void 0 ? void 0 : schema.index(...indexParams);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return schema;
|
|
102
|
+
}
|
|
@@ -61,6 +61,16 @@ const indexes = [
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
],
|
|
64
|
+
[
|
|
65
|
+
{ 'project.id': 1, 'member.identifier': 1 }, // アプリケーションコード追加(2025-11-17~)
|
|
66
|
+
{
|
|
67
|
+
name: 'uniqueByMemberIdentifier',
|
|
68
|
+
unique: true,
|
|
69
|
+
partialFilterExpression: {
|
|
70
|
+
'member.identifier': { $exists: true }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
],
|
|
64
74
|
[
|
|
65
75
|
{ 'project.id': 1, 'member.id': 1, 'member.memberOf.id': 1 },
|
|
66
76
|
{
|
|
@@ -23,6 +23,7 @@ import type { CustomerRepo } from './repo/customer';
|
|
|
23
23
|
import type { CustomerTypeRepo } from './repo/customerType';
|
|
24
24
|
import type { EmailMessageRepo } from './repo/emailMessage';
|
|
25
25
|
import type { EventRepo } from './repo/event';
|
|
26
|
+
import type { EventOfferRepo } from './repo/eventOffer';
|
|
26
27
|
import type { EventSellerMakesOfferRepo } from './repo/eventSellerMakesOffer';
|
|
27
28
|
import type { EventSeriesRepo } from './repo/eventSeries';
|
|
28
29
|
import type { IdentityRepo } from './repo/identity';
|
|
@@ -181,6 +182,10 @@ export type Event = EventRepo;
|
|
|
181
182
|
export declare namespace Event {
|
|
182
183
|
function createInstance(...params: ConstructorParameters<typeof EventRepo>): Promise<EventRepo>;
|
|
183
184
|
}
|
|
185
|
+
export type EventOffer = EventOfferRepo;
|
|
186
|
+
export declare namespace EventOffer {
|
|
187
|
+
function createInstance(...params: ConstructorParameters<typeof EventOfferRepo>): Promise<EventOfferRepo>;
|
|
188
|
+
}
|
|
184
189
|
export type EventSellerMakesOffer = EventSellerMakesOfferRepo;
|
|
185
190
|
export declare namespace EventSellerMakesOffer {
|
|
186
191
|
function createInstance(...params: ConstructorParameters<typeof EventSellerMakesOfferRepo>): Promise<EventSellerMakesOfferRepo>;
|
package/lib/chevre/repository.js
CHANGED
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
exports.WebSite = exports.rateLimit = exports.Trip = exports.TransactionProcess = exports.TransactionNumber = exports.Transaction = exports.Ticket = exports.Telemetry = exports.Task = exports.StockHolder = exports.setting = exports.Setting = exports.ServiceOutputIdentifier = exports.ServiceOutput = exports.ServiceAvailableHour = exports.SellerReturnPolicy = exports.SellerPaymentAccepted = exports.SellerMakesOffer = exports.Seller = exports.Schedule = exports.Role = exports.ReserveInterface = exports.Reservation = exports.ProjectMakesOffer = exports.Project = exports.ProductOffer = exports.ProductModel = exports.ProductHasOfferCatalog = exports.Product = exports.PriceSpecification = exports.PotentialAction = exports.place = exports.Permit = void 0;
|
|
12
|
+
exports.paymentMethod = exports.PendingReservation = exports.PaymentServiceProvider = exports.PaymentServiceChannel = exports.PaymentService = exports.Passport = exports.OwnershipInfo = exports.OrderNumber = exports.OrderInTransaction = exports.Order = exports.Offer = exports.OfferItemCondition = exports.OfferCatalogItem = exports.OfferCatalog = exports.NoteAboutOrder = exports.Note = exports.MovieTicketType = exports.Message = exports.MerchantReturnPolicy = exports.MemberProgram = exports.Member = exports.Issuer = exports.IdentityProvider = exports.Identity = exports.EventSeries = exports.EventSellerMakesOffer = exports.EventOffer = exports.Event = exports.EmailMessage = exports.CustomerType = exports.Customer = exports.Credentials = exports.CreativeWork = exports.ConfirmationNumber = exports.Comment = exports.Authorization = exports.CategoryCode = exports.AssetTransaction = exports.Aggregation = exports.AggregateReservation = exports.AggregateOrder = exports.AggregateOffer = exports.AdvanceBookingRequirement = exports.AdditionalProperty = exports.Action = exports.AccountTransaction = exports.AccountTitle = exports.AccountingReport = exports.Account = exports.AcceptedOffer = void 0;
|
|
13
|
+
exports.WebSite = exports.rateLimit = exports.Trip = exports.TransactionProcess = exports.TransactionNumber = exports.Transaction = exports.Ticket = exports.Telemetry = exports.Task = exports.StockHolder = exports.setting = exports.Setting = exports.ServiceOutputIdentifier = exports.ServiceOutput = exports.ServiceAvailableHour = exports.SellerReturnPolicy = exports.SellerPaymentAccepted = exports.SellerMakesOffer = exports.Seller = exports.Schedule = exports.Role = exports.ReserveInterface = exports.Reservation = exports.ProjectMakesOffer = exports.Project = exports.ProductOffer = exports.ProductModel = exports.ProductHasOfferCatalog = exports.Product = exports.PriceSpecification = exports.PotentialAction = exports.place = exports.Permit = exports.Person = void 0;
|
|
14
14
|
var AcceptedOffer;
|
|
15
15
|
(function (AcceptedOffer) {
|
|
16
16
|
let repo;
|
|
@@ -310,6 +310,19 @@ var Event;
|
|
|
310
310
|
}
|
|
311
311
|
Event.createInstance = createInstance;
|
|
312
312
|
})(Event || (exports.Event = Event = {}));
|
|
313
|
+
var EventOffer;
|
|
314
|
+
(function (EventOffer) {
|
|
315
|
+
let repo;
|
|
316
|
+
function createInstance(...params) {
|
|
317
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
318
|
+
if (repo === undefined) {
|
|
319
|
+
repo = (yield Promise.resolve().then(() => require('./repo/eventOffer'))).EventOfferRepo;
|
|
320
|
+
}
|
|
321
|
+
return new repo(...params);
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
EventOffer.createInstance = createInstance;
|
|
325
|
+
})(EventOffer || (exports.EventOffer = EventOffer = {}));
|
|
313
326
|
var EventSellerMakesOffer;
|
|
314
327
|
(function (EventSellerMakesOffer) {
|
|
315
328
|
let repo;
|
|
@@ -2,9 +2,12 @@ import * as factory from '../../../factory';
|
|
|
2
2
|
import { Settings } from '../../../settings';
|
|
3
3
|
import type { AdvanceBookingRequirementRepo } from '../../../repo/advanceBookingRequirement';
|
|
4
4
|
import type { AssetTransactionRepo } from '../../../repo/assetTransaction';
|
|
5
|
+
import type { AuthorizationRepo } from '../../../repo/authorization';
|
|
5
6
|
import type { EventRepo } from '../../../repo/event';
|
|
7
|
+
import type { EventOfferRepo } from '../../../repo/eventOffer';
|
|
6
8
|
import type { EventSeriesRepo } from '../../../repo/eventSeries';
|
|
7
9
|
import type { IssuerRepo } from '../../../repo/issuer';
|
|
10
|
+
import type { MemberRepo } from '../../../repo/member';
|
|
8
11
|
import type { MemberProgramRepo } from '../../../repo/memberProgram';
|
|
9
12
|
import type { OfferRepo } from '../../../repo/offer/unitPriceInCatalog';
|
|
10
13
|
import type { OfferCatalogRepo } from '../../../repo/offerCatalog';
|
|
@@ -19,12 +22,16 @@ import type { OfferRateLimitRepo } from '../../../repo/rateLimit/offer';
|
|
|
19
22
|
import type { SettingRepo } from '../../../repo/setting';
|
|
20
23
|
import type { StockHolderRepo } from '../../../repo/stockHolder';
|
|
21
24
|
import type { TaskRepo } from '../../../repo/task';
|
|
25
|
+
import type { TicketRepo } from '../../../repo/ticket';
|
|
22
26
|
interface IStartOperationRepos {
|
|
23
27
|
advanceBookingRequirement: AdvanceBookingRequirementRepo;
|
|
28
|
+
authorization: AuthorizationRepo;
|
|
24
29
|
stockHolder: StockHolderRepo;
|
|
25
30
|
event: EventRepo;
|
|
31
|
+
eventOffer: EventOfferRepo;
|
|
26
32
|
eventSeries: EventSeriesRepo;
|
|
27
33
|
issuer: IssuerRepo;
|
|
34
|
+
member: MemberRepo;
|
|
28
35
|
memberProgram: MemberProgramRepo;
|
|
29
36
|
offer: OfferRepo;
|
|
30
37
|
offerCatalog: OfferCatalogRepo;
|
|
@@ -38,6 +45,7 @@ interface IStartOperationRepos {
|
|
|
38
45
|
seat: SeatRepo;
|
|
39
46
|
setting: SettingRepo;
|
|
40
47
|
task: TaskRepo;
|
|
48
|
+
ticket: TicketRepo;
|
|
41
49
|
assetTransaction: AssetTransactionRepo;
|
|
42
50
|
}
|
|
43
51
|
type IStartOperation<T> = (repos: IStartOperationRepos, settings: Settings) => Promise<T>;
|
|
@@ -41,15 +41,20 @@ function start(params, options) {
|
|
|
41
41
|
// validationを承認アクション開始前から移行(2023-01-27~)
|
|
42
42
|
yield (0, validateStartRequest_1.validateStartRequest)({
|
|
43
43
|
object: params.object,
|
|
44
|
+
instrument: params.instrument,
|
|
44
45
|
event,
|
|
45
46
|
validateEventOfferPeriod: params.validateEventOfferPeriod,
|
|
46
47
|
validateEvent: params.validateEvent,
|
|
47
48
|
now,
|
|
48
49
|
store: { id: (_a = params.availableAtOrFrom) === null || _a === void 0 ? void 0 : _a.id }
|
|
49
50
|
})({
|
|
51
|
+
authorization: repos.authorization,
|
|
52
|
+
eventOffer: repos.eventOffer,
|
|
50
53
|
issuer: repos.issuer,
|
|
54
|
+
member: repos.member,
|
|
51
55
|
memberProgram: repos.memberProgram,
|
|
52
|
-
productOffer: repos.productOffer
|
|
56
|
+
productOffer: repos.productOffer,
|
|
57
|
+
ticket: repos.ticket
|
|
53
58
|
});
|
|
54
59
|
// objectに必要な情報をそろえる
|
|
55
60
|
const { acceptedOffers4transactionObject, objectSubReservations } = yield createObjectAttributes({
|
package/lib/chevre/service/assetTransaction/reserve/validateStartRequest/fixExtendedEventOffer.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as factory from '../../../../factory';
|
|
2
|
+
import { IMinimizedIndividualEvent } from '../../../../factory/event';
|
|
3
|
+
import type { EventOfferRepo } from '../../../../repo/eventOffer';
|
|
4
|
+
import type { MemberRepo } from '../../../../repo/member';
|
|
5
|
+
/**
|
|
6
|
+
* リクエストから拡張イベントオファーを決定する
|
|
7
|
+
*/
|
|
8
|
+
declare function fixExtendedEventOffer(params: {
|
|
9
|
+
event: Pick<IMinimizedIndividualEvent, 'offers' | 'id' | 'project' | 'identifier'>;
|
|
10
|
+
now: Date;
|
|
11
|
+
availableAt: {
|
|
12
|
+
/**
|
|
13
|
+
* 販売アプリケーションID
|
|
14
|
+
*/
|
|
15
|
+
id: string;
|
|
16
|
+
};
|
|
17
|
+
acceptedEventOffer?: factory.authorization.IOfferAsObject;
|
|
18
|
+
}): (repos: {
|
|
19
|
+
eventOffer: EventOfferRepo;
|
|
20
|
+
member: MemberRepo;
|
|
21
|
+
}) => Promise<Pick<factory.eventOffer.IEventOffer, "identifier" | "itemOffered" | "typeOf" | "offeredBy" | "validFrom" | "validThrough" | "id">>;
|
|
22
|
+
export { fixExtendedEventOffer };
|
package/lib/chevre/service/assetTransaction/reserve/validateStartRequest/fixExtendedEventOffer.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
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.fixExtendedEventOffer = fixExtendedEventOffer;
|
|
13
|
+
const moment = require("moment");
|
|
14
|
+
const factory = require("../../../../factory");
|
|
15
|
+
/**
|
|
16
|
+
* リクエストから拡張イベントオファーを決定する
|
|
17
|
+
*/
|
|
18
|
+
function fixExtendedEventOffer(params) {
|
|
19
|
+
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
var _a;
|
|
21
|
+
const { event, availableAt } = params;
|
|
22
|
+
const acceptedDate = moment(params.now);
|
|
23
|
+
// リクエストによるオファーコード指定が必須
|
|
24
|
+
const eventOfferIdMustBe = (_a = params.acceptedEventOffer) === null || _a === void 0 ? void 0 : _a.id;
|
|
25
|
+
if (typeof eventOfferIdMustBe !== 'string' || eventOfferIdMustBe === '') {
|
|
26
|
+
throw new factory.errors.ArgumentNull('ticket as instrument');
|
|
27
|
+
}
|
|
28
|
+
// アプリケーションIDからアプリケーションコードを参照
|
|
29
|
+
const existingCustomerMember = (yield repos.member.searchCustomerMembers({
|
|
30
|
+
project: { id: event.project.id },
|
|
31
|
+
limit: 1,
|
|
32
|
+
page: 1,
|
|
33
|
+
member: {
|
|
34
|
+
id: { $eq: availableAt.id }
|
|
35
|
+
}
|
|
36
|
+
})).shift();
|
|
37
|
+
if (existingCustomerMember === undefined) {
|
|
38
|
+
throw new factory.errors.NotFound(`Member: ${availableAt.id}`);
|
|
39
|
+
}
|
|
40
|
+
// tslint:disable-next-line:no-console
|
|
41
|
+
console.log('existingCustomerMember found:', JSON.stringify(existingCustomerMember));
|
|
42
|
+
const applicationIdentifier = existingCustomerMember.member.identifier;
|
|
43
|
+
if (typeof applicationIdentifier !== 'string') {
|
|
44
|
+
throw new factory.errors.NotFound(`member.identifier of ${availableAt.id}`);
|
|
45
|
+
}
|
|
46
|
+
// アプリケーションコードで利用可能な拡張オファーを検索
|
|
47
|
+
const existingEventOffer = (yield repos.eventOffer.findEventOffers({
|
|
48
|
+
limit: 1,
|
|
49
|
+
page: 1,
|
|
50
|
+
project: { id: { $eq: event.project.id } }, // プロジェクト
|
|
51
|
+
validFrom: { $lte: acceptedDate.toDate() },
|
|
52
|
+
validThrough: { $gte: acceptedDate.toDate() },
|
|
53
|
+
itemOffered: { id: { $eq: event.id } }, // 対象イベント
|
|
54
|
+
id: { $eq: eventOfferIdMustBe }, // オファーID
|
|
55
|
+
// identifier: { $eq: eventOfferIdentifierMustBe }, // オファーコード
|
|
56
|
+
availableAtOrFrom: { identifier: { $eq: applicationIdentifier } } // アプリケーションコード
|
|
57
|
+
}, ['identifier', 'itemOffered', 'offeredBy', 'typeOf', 'validFrom', 'validThrough'])).shift();
|
|
58
|
+
if (existingEventOffer === undefined) {
|
|
59
|
+
throw new factory.errors.NotFound(`valid eventOffer: ${eventOfferIdMustBe}`);
|
|
60
|
+
}
|
|
61
|
+
return existingEventOffer;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -7,8 +7,13 @@ import type { IssuerRepo } from '../../../../repo/issuer';
|
|
|
7
7
|
declare function validateIssuedOfferIfExists(params: {
|
|
8
8
|
event: Pick<IMinimizedIndividualEvent, 'offers' | 'id' | 'project' | 'identifier'>;
|
|
9
9
|
now: Date;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
eventOffer: Pick<factory.eventOffer.IEventOffer, 'identifier' | 'itemOffered' | 'offeredBy' | 'validFrom' | 'validThrough' | 'id'>;
|
|
11
|
+
acceptedEventOffer?: factory.authorization.IOfferAsObject;
|
|
12
|
+
/**
|
|
13
|
+
* オファー承認時の予約数
|
|
14
|
+
* 0であれば特に何も検証されない
|
|
15
|
+
*/
|
|
16
|
+
numAcceptedOffers: number;
|
|
12
17
|
}): (repos: {
|
|
13
18
|
issuer: IssuerRepo;
|
|
14
19
|
}) => Promise<void>;
|
|
@@ -37,10 +37,10 @@ function verifyOfferToken(params) {
|
|
|
37
37
|
catch (error) {
|
|
38
38
|
// JWTエラーをハンドリング
|
|
39
39
|
if (error instanceof jwt.TokenExpiredError) {
|
|
40
|
-
throw new factory.errors.Argument('
|
|
40
|
+
throw new factory.errors.Argument('ticketedOffer.token', `invalid token. [${error.message} expiredAt:${error.expiredAt}]`);
|
|
41
41
|
}
|
|
42
42
|
else if (error instanceof jwt.JsonWebTokenError) {
|
|
43
|
-
throw new factory.errors.Argument('
|
|
43
|
+
throw new factory.errors.Argument('ticketedOffer.token', `invalid token. [${error.message}]`);
|
|
44
44
|
}
|
|
45
45
|
throw error;
|
|
46
46
|
}
|
|
@@ -50,31 +50,31 @@ function verifyOfferToken(params) {
|
|
|
50
50
|
const OFFER_TOKEN_DATE_FORMAT = 'YYYY-MM-DDTHH:mm:ssZ';
|
|
51
51
|
function validateOfferToken(params) {
|
|
52
52
|
return () => __awaiter(this, void 0, void 0, function* () {
|
|
53
|
-
var _a
|
|
54
|
-
const { event, acceptedDate, verifiedOffer,
|
|
53
|
+
var _a;
|
|
54
|
+
const { event, acceptedDate, verifiedOffer, eventOffer, numAcceptedOffers } = params;
|
|
55
55
|
// イベント識別子一致検証
|
|
56
56
|
const itemOfferedIdentifier = verifiedOffer.itemOffered.identifier;
|
|
57
57
|
if (typeof itemOfferedIdentifier !== 'string' || itemOfferedIdentifier === '') {
|
|
58
|
-
throw new factory.errors.Argument('
|
|
58
|
+
throw new factory.errors.Argument('ticketedOffer.token', 'itemOffered.identifier must be string');
|
|
59
59
|
}
|
|
60
60
|
const itemOfferedIdentifierMustBe = event.identifier;
|
|
61
61
|
if (typeof itemOfferedIdentifierMustBe !== 'string') {
|
|
62
62
|
throw new factory.errors.NotFound('identifier', 'the event must have an identifier');
|
|
63
63
|
}
|
|
64
64
|
if (itemOfferedIdentifier !== itemOfferedIdentifierMustBe) {
|
|
65
|
-
throw new factory.errors.Argument('
|
|
65
|
+
throw new factory.errors.Argument('ticketedOffer.token', 'itemOffered.identifier not matched');
|
|
66
66
|
}
|
|
67
67
|
// アプリケーションオファーコード一致検証
|
|
68
68
|
const applicationOfferIdentifier = verifiedOffer.identifier;
|
|
69
69
|
if (typeof applicationOfferIdentifier !== 'string' || applicationOfferIdentifier === '') {
|
|
70
|
-
throw new factory.errors.Argument('
|
|
70
|
+
throw new factory.errors.Argument('ticketedOffer.token', 'identifier must be string');
|
|
71
71
|
}
|
|
72
|
-
const applicationOfferIdentifierMustBe =
|
|
72
|
+
const applicationOfferIdentifierMustBe = eventOffer.identifier;
|
|
73
73
|
if (typeof applicationOfferIdentifierMustBe !== 'string') {
|
|
74
74
|
throw new factory.errors.NotFound('makesOffer.identifier');
|
|
75
75
|
}
|
|
76
76
|
if (applicationOfferIdentifier !== applicationOfferIdentifierMustBe) {
|
|
77
|
-
throw new factory.errors.Argument('
|
|
77
|
+
throw new factory.errors.Argument('ticketedOffer.token', 'identifier not matched');
|
|
78
78
|
}
|
|
79
79
|
// 有効期間検証
|
|
80
80
|
let validThroughMoment;
|
|
@@ -82,26 +82,26 @@ function validateOfferToken(params) {
|
|
|
82
82
|
validThroughMoment = moment(verifiedOffer.validThrough, OFFER_TOKEN_DATE_FORMAT, true);
|
|
83
83
|
validFromMoment = moment(verifiedOffer.validFrom, OFFER_TOKEN_DATE_FORMAT, true);
|
|
84
84
|
if (!validThroughMoment.isValid()) {
|
|
85
|
-
throw new factory.errors.Argument('
|
|
85
|
+
throw new factory.errors.Argument('ticketedOffer.token', 'invalid validThrough');
|
|
86
86
|
}
|
|
87
87
|
if (!validFromMoment.isValid()) {
|
|
88
|
-
throw new factory.errors.Argument('
|
|
88
|
+
throw new factory.errors.Argument('ticketedOffer.token', 'invalid validFrom');
|
|
89
89
|
}
|
|
90
90
|
if (acceptedDate.isBefore(validFromMoment)) {
|
|
91
|
-
throw new factory.errors.Argument('
|
|
91
|
+
throw new factory.errors.Argument('ticketedOffer.token', `the offer id valid from ${validFromMoment}`);
|
|
92
92
|
}
|
|
93
93
|
if (acceptedDate.isAfter(validThroughMoment)) {
|
|
94
|
-
throw new factory.errors.Argument('
|
|
94
|
+
throw new factory.errors.Argument('ticketedOffer.token', `the offer id valid through ${validThroughMoment}`);
|
|
95
95
|
}
|
|
96
96
|
// maxValueを検証
|
|
97
97
|
const maxValue = (_a = verifiedOffer === null || verifiedOffer === void 0 ? void 0 : verifiedOffer.eligibleQuantity) === null || _a === void 0 ? void 0 : _a.maxValue;
|
|
98
98
|
if (typeof maxValue !== 'number') {
|
|
99
|
-
throw new factory.errors.Argument('
|
|
99
|
+
throw new factory.errors.Argument('ticketedOffer.token', 'eligibleQuantity.maxValue must be number');
|
|
100
100
|
}
|
|
101
101
|
if (maxValue > NUM_ACCEPTED_OFFERS_MAX_VALUE) {
|
|
102
|
-
throw new factory.errors.Argument('
|
|
102
|
+
throw new factory.errors.Argument('ticketedOffer.token', `eligibleQuantity.maxValue must be <= ${NUM_ACCEPTED_OFFERS_MAX_VALUE}`);
|
|
103
103
|
}
|
|
104
|
-
const numAcceptedOffers =
|
|
104
|
+
// const numAcceptedOffers = params.object.acceptedOffer?.length;
|
|
105
105
|
if (typeof numAcceptedOffers === 'number' && numAcceptedOffers > 0) {
|
|
106
106
|
if (numAcceptedOffers > maxValue) {
|
|
107
107
|
throw new factory.errors.Argument('reservationFor.id', `Maximum number of offers exceeded`);
|
|
@@ -114,26 +114,26 @@ function validateOfferToken(params) {
|
|
|
114
114
|
*/
|
|
115
115
|
function validateIssuedOfferIfExists(params) {
|
|
116
116
|
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
117
|
-
var _a, _b, _c
|
|
118
|
-
const { event,
|
|
117
|
+
var _a, _b, _c;
|
|
118
|
+
const { event, eventOffer, numAcceptedOffers } = params;
|
|
119
119
|
const acceptedDate = moment(params.now);
|
|
120
|
-
const offerTokenIssuer = (_a =
|
|
120
|
+
const offerTokenIssuer = (_a = eventOffer.offeredBy) === null || _a === void 0 ? void 0 : _a.identifier;
|
|
121
121
|
const offerTokenRequired = typeof offerTokenIssuer === 'string';
|
|
122
122
|
if (offerTokenRequired) {
|
|
123
|
-
const
|
|
124
|
-
const offerToken = (
|
|
125
|
-
if (typeof
|
|
126
|
-
throw new factory.errors.
|
|
123
|
+
const offerIdMustBe = (_b = params.acceptedEventOffer) === null || _b === void 0 ? void 0 : _b.id;
|
|
124
|
+
const offerToken = (_c = params.acceptedEventOffer) === null || _c === void 0 ? void 0 : _c.token;
|
|
125
|
+
if (typeof offerIdMustBe !== 'string' || offerIdMustBe === '') {
|
|
126
|
+
throw new factory.errors.NotFound('ticketedOffer.id');
|
|
127
127
|
}
|
|
128
128
|
if (typeof offerToken !== 'string' || offerToken === '') {
|
|
129
129
|
throw new factory.errors.ArgumentNull('object.reservationFor.offers.token');
|
|
130
130
|
}
|
|
131
|
-
if (typeof
|
|
132
|
-
throw new factory.errors.NotFound('
|
|
131
|
+
if (typeof eventOffer.identifier !== 'string' || eventOffer.identifier === '') {
|
|
132
|
+
throw new factory.errors.NotFound('eventOffer.identifier');
|
|
133
133
|
}
|
|
134
|
-
//
|
|
135
|
-
if (
|
|
136
|
-
throw new factory.errors.Argument('object.reservationFor.offers.identifier', '
|
|
134
|
+
// イベントオファーID一致検証
|
|
135
|
+
if (eventOffer.id !== offerIdMustBe) {
|
|
136
|
+
throw new factory.errors.Argument('object.reservationFor.offers.identifier', 'eventOffer.identifier not matched');
|
|
137
137
|
}
|
|
138
138
|
const issuer = yield repos.issuer.findByIdentifier({
|
|
139
139
|
project: { id: event.project.id },
|
|
@@ -151,8 +151,8 @@ function validateIssuedOfferIfExists(params) {
|
|
|
151
151
|
event,
|
|
152
152
|
acceptedDate,
|
|
153
153
|
verifiedOffer,
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
eventOffer,
|
|
155
|
+
numAcceptedOffers
|
|
156
156
|
})();
|
|
157
157
|
}
|
|
158
158
|
});
|
|
@@ -6,8 +6,8 @@ import type { ProductOfferRepo } from '../../../../repo/productOffer';
|
|
|
6
6
|
declare function validateMemberTierIfExists(params: {
|
|
7
7
|
event: Pick<IMinimizedIndividualEvent, 'offers' | 'id' | 'project'>;
|
|
8
8
|
now: Date;
|
|
9
|
-
object: factory.assetTransaction.reserve.IObjectWithoutDetail;
|
|
10
9
|
makesOfferOnApplication: factory.event.screeningEvent.ISellerMakesOffer;
|
|
10
|
+
acceptedEventOffer?: factory.authorization.IOfferAsObject;
|
|
11
11
|
}): (repos: {
|
|
12
12
|
issuer: IssuerRepo;
|
|
13
13
|
memberProgram: MemberProgramRepo;
|
|
@@ -20,13 +20,13 @@ function validateMemberTier(params) {
|
|
|
20
20
|
const tierIdentifier = (_b = (_a = verifiedValidForMemberTier.member) === null || _a === void 0 ? void 0 : _a.memberOf) === null || _b === void 0 ? void 0 : _b.identifier;
|
|
21
21
|
const memberProgramIdentifier = (_e = (_d = (_c = verifiedValidForMemberTier.member) === null || _c === void 0 ? void 0 : _c.memberOf) === null || _d === void 0 ? void 0 : _d.isTierOf) === null || _e === void 0 ? void 0 : _e.identifier;
|
|
22
22
|
if (typeof tierIdentifier !== 'string') {
|
|
23
|
-
throw new factory.errors.Argument('
|
|
23
|
+
throw new factory.errors.Argument('ticketedOffer.validForMemberTier', 'tier identifier must be string');
|
|
24
24
|
}
|
|
25
25
|
if (typeof memberProgramIdentifier !== 'string') {
|
|
26
|
-
throw new factory.errors.Argument('
|
|
26
|
+
throw new factory.errors.Argument('ticketedOffer.validForMemberTier', 'member program must be string');
|
|
27
27
|
}
|
|
28
28
|
if (memberProgramIdentifier !== memberProgramIdentifierMustBe) {
|
|
29
|
-
throw new factory.errors.Argument('
|
|
29
|
+
throw new factory.errors.Argument('ticketedOffer.validForMemberTier', 'member program not matched');
|
|
30
30
|
}
|
|
31
31
|
const sellerId = event.offers.seller.id;
|
|
32
32
|
if (typeof sellerId !== 'string' || sellerId === '') {
|
|
@@ -47,22 +47,6 @@ function validateMemberTier(params) {
|
|
|
47
47
|
if (productOfferForMemberTier === undefined) {
|
|
48
48
|
throw new factory.errors.NotFound(factory.offerType.Offer, 'valid product offers for member tier not found');
|
|
49
49
|
}
|
|
50
|
-
// let validThroughMoment: moment.Moment;
|
|
51
|
-
// let validFromMoment: moment.Moment;
|
|
52
|
-
// validThroughMoment = moment(productOfferForMemberTier.validThrough, ROLE_DATE_FORMAT, true);
|
|
53
|
-
// validFromMoment = moment(productOfferForMemberTier.validFrom, ROLE_DATE_FORMAT, true);
|
|
54
|
-
// if (acceptedDate.isBefore(validFromMoment)) {
|
|
55
|
-
// throw new factory.errors.Argument(
|
|
56
|
-
// 'reservationFor.offers.validForMemberTier',
|
|
57
|
-
// `the offer id valid from ${validFromMoment}`
|
|
58
|
-
// );
|
|
59
|
-
// }
|
|
60
|
-
// if (acceptedDate.isAfter(validThroughMoment)) {
|
|
61
|
-
// throw new factory.errors.Argument(
|
|
62
|
-
// 'reservationFor.offers.validForMemberTier',
|
|
63
|
-
// `the offer id valid through ${validThroughMoment}`
|
|
64
|
-
// );
|
|
65
|
-
// }
|
|
66
50
|
});
|
|
67
51
|
}
|
|
68
52
|
function verifyMemberTierToken(params) {
|
|
@@ -88,10 +72,10 @@ function verifyMemberTierToken(params) {
|
|
|
88
72
|
catch (error) {
|
|
89
73
|
// JWTエラーをハンドリング
|
|
90
74
|
if (error instanceof jwt.TokenExpiredError) {
|
|
91
|
-
throw new factory.errors.Argument('
|
|
75
|
+
throw new factory.errors.Argument('ticketedOffer.validForMemberTier', `invalid token. [${error.message} expiredAt:${error.expiredAt}]`);
|
|
92
76
|
}
|
|
93
77
|
else if (error instanceof jwt.JsonWebTokenError) {
|
|
94
|
-
throw new factory.errors.Argument('
|
|
78
|
+
throw new factory.errors.Argument('ticketedOffer.validForMemberTier', `invalid token. [${error.message}]`);
|
|
95
79
|
}
|
|
96
80
|
throw error;
|
|
97
81
|
}
|
|
@@ -101,7 +85,7 @@ function verifyMemberTierToken(params) {
|
|
|
101
85
|
function validateMemberTierIfExists(params) {
|
|
102
86
|
// tslint:disable-next-line:cyclomatic-complexity max-func-body-length
|
|
103
87
|
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
104
|
-
var _a, _b, _c
|
|
88
|
+
var _a, _b, _c;
|
|
105
89
|
const { event, makesOfferOnApplication } = params;
|
|
106
90
|
const acceptedDate = moment(params.now);
|
|
107
91
|
const eventOffers = event.offers;
|
|
@@ -109,16 +93,16 @@ function validateMemberTierIfExists(params) {
|
|
|
109
93
|
// support validForMemberTier(2025-05-14~)
|
|
110
94
|
const validForMemberTierExists = ((_a = makesOfferOnApplication.validForMemberTier) === null || _a === void 0 ? void 0 : _a.typeOf) === 'MemberProgramTier';
|
|
111
95
|
if (validForMemberTierExists) {
|
|
112
|
-
const tokenizedMemberProgramTier = (
|
|
96
|
+
const tokenizedMemberProgramTier = (_b = params.acceptedEventOffer) === null || _b === void 0 ? void 0 : _b.validForMemberTier;
|
|
113
97
|
const validForMemberTierToken = tokenizedMemberProgramTier === null || tokenizedMemberProgramTier === void 0 ? void 0 : tokenizedMemberProgramTier.token;
|
|
114
|
-
const memberProgramIdentifierMustBe = (
|
|
98
|
+
const memberProgramIdentifierMustBe = (_c = tokenizedMemberProgramTier === null || tokenizedMemberProgramTier === void 0 ? void 0 : tokenizedMemberProgramTier.isTierOf) === null || _c === void 0 ? void 0 : _c.identifier;
|
|
115
99
|
// ティアトークンが必須
|
|
116
100
|
if (typeof validForMemberTierToken !== 'string' || validForMemberTierToken === '') {
|
|
117
|
-
throw new factory.errors.ArgumentNull('
|
|
101
|
+
throw new factory.errors.ArgumentNull('ticketedOffer.validForMemberTier.token');
|
|
118
102
|
}
|
|
119
103
|
// メンバープログラムコード指定が必須
|
|
120
104
|
if (typeof memberProgramIdentifierMustBe !== 'string' || memberProgramIdentifierMustBe === '') {
|
|
121
|
-
throw new factory.errors.ArgumentNull('
|
|
105
|
+
throw new factory.errors.ArgumentNull('ticketedOffer.validForMemberTier.isTierOf.identifier');
|
|
122
106
|
}
|
|
123
107
|
// 有効メンバープログラムティアが存在する場合、オファーコレクションコードが必須
|
|
124
108
|
const aggregateOfferIdentifier = eventOffers.identifier;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as factory from '../../../../factory';
|
|
2
|
+
import { IMinimizedIndividualEvent } from '../../../../factory/event';
|
|
3
|
+
import type { AuthorizationRepo } from '../../../../repo/authorization';
|
|
4
|
+
import type { TicketRepo } from '../../../../repo/ticket';
|
|
5
|
+
type IPermitOrInvoice = Pick<factory.ownershipInfo.IPermitAsGood, 'identifier' | 'typeOf'> | Pick<factory.invoice.IInvoice, 'paymentMethodId' | 'typeOf'>;
|
|
6
|
+
declare function verifyTicketTokenAsNeeded(params: {
|
|
7
|
+
event: Pick<IMinimizedIndividualEvent, 'offers' | 'id' | 'project' | 'identifier'>;
|
|
8
|
+
now: Date;
|
|
9
|
+
availableAt: {
|
|
10
|
+
/**
|
|
11
|
+
* 販売アプリケーションID
|
|
12
|
+
*/
|
|
13
|
+
id: string;
|
|
14
|
+
};
|
|
15
|
+
object: factory.assetTransaction.reserve.IObjectWithoutDetail;
|
|
16
|
+
instrument: factory.assetTransaction.reserve.IInstrument[];
|
|
17
|
+
}): (repos: {
|
|
18
|
+
authorization: AuthorizationRepo;
|
|
19
|
+
ticket: TicketRepo;
|
|
20
|
+
}) => Promise<{
|
|
21
|
+
acceptedEventOffer?: factory.authorization.IOfferAsObject;
|
|
22
|
+
}>;
|
|
23
|
+
export { IPermitOrInvoice, verifyTicketTokenAsNeeded };
|