@chevre/domain 21.2.0-alpha.60 → 21.2.0-alpha.62

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.
@@ -1,4 +1,5 @@
1
1
  // tslint:disable:no-console
2
+ import * as moment from 'moment';
2
3
  import * as mongoose from 'mongoose';
3
4
 
4
5
  import { chevre } from '../../../lib/index';
@@ -6,13 +7,19 @@ import { chevre } from '../../../lib/index';
6
7
  // const project = { id: String(process.env.PROJECT_ID) };
7
8
 
8
9
  async function main() {
9
- await mongoose.connect(<string>process.env.MONGOLAB_URI);
10
+ await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
10
11
 
11
12
  const taskRepo = new chevre.repository.Task(mongoose.connection);
12
13
 
13
14
  const result = await taskRepo.deleteByName({
14
- name: chevre.factory.taskName.DeleteOrder,
15
+ name: chevre.factory.taskName.DeleteAssetTransaction,
15
16
  status: { $eq: chevre.factory.taskStatus.Ready }
17
+ // runsAt: {
18
+ // $gte: moment('2023-05-20T00:00:00Z')
19
+ // .toDate(),
20
+ // $lte: moment('2023-12-20T00:00:00Z')
21
+ // .toDate()
22
+ // }
16
23
  });
17
24
 
18
25
  console.log('deleted', result);
@@ -10,11 +10,11 @@ async function main() {
10
10
 
11
11
  const orderRepo = new chevre.repository.Order(mongoose.connection);
12
12
 
13
- const reservationNumbers = await orderRepo.searchReservationNumbersByOrderNumbers({
14
- orderNumber: { $in: ['CIN5-8118459-9364668', 'CIN7-9119652-8987979', 'SSK1-3992448-6733563'] }
13
+ const reservatioForIds = await orderRepo.searchReservationForIdsByOrderNumbers({
14
+ orderNumber: { $in: ['TTT9-4703865-8892744', 'TTT9-4703865-8398074', 'SSK9-4703865-4744524'] }
15
15
  });
16
- console.log('reservationNumbers found', reservationNumbers);
17
- console.log(reservationNumbers.length, 'reservationNumbers found');
16
+ console.log('reservatioForIds found', reservatioForIds);
17
+ console.log(reservatioForIds.length, 'reservatioForIds found');
18
18
  }
19
19
 
20
20
  main()
@@ -55,19 +55,19 @@ declare const schema: Schema<any, import("mongoose").Model<any, any, any, any, a
55
55
  typeOf?: string | undefined;
56
56
  project?: any;
57
57
  identifier?: string | undefined;
58
- itemOfferded?: any;
58
+ itemOffered?: any;
59
59
  }, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<{
60
60
  name?: any;
61
61
  typeOf?: string | undefined;
62
62
  project?: any;
63
63
  identifier?: string | undefined;
64
- itemOfferded?: any;
64
+ itemOffered?: any;
65
65
  }>> & Omit<import("mongoose").FlatRecord<{
66
66
  name?: any;
67
67
  typeOf?: string | undefined;
68
68
  project?: any;
69
69
  identifier?: string | undefined;
70
- itemOfferded?: any;
70
+ itemOffered?: any;
71
71
  }> & {
72
72
  _id: import("mongoose").Types.ObjectId;
73
73
  }, never>>;
@@ -13,7 +13,7 @@ const schema = new mongoose_1.Schema({
13
13
  identifier: String,
14
14
  typeOf: String,
15
15
  name: mongoose_1.SchemaTypes.Mixed,
16
- itemOfferded: mongoose_1.SchemaTypes.Mixed
16
+ itemOffered: mongoose_1.SchemaTypes.Mixed
17
17
  }, {
18
18
  collection: 'offerItemConditions',
19
19
  id: true,
@@ -3,35 +3,18 @@ import * as factory from '../factory';
3
3
  interface IProjection {
4
4
  [key: string]: 0 | 1;
5
5
  }
6
- interface IOfferItemCondition {
7
- id?: string;
8
- identifier: string;
9
- itemOfferded: {
10
- typeOf: factory.product.ProductType.EventService;
11
- serviceOutput?: {
12
- typeOf: factory.reservationType.EventReservation;
13
- reservationFor: any;
14
- };
15
- };
16
- name: factory.multilingualString;
17
- project: {
18
- id: string;
19
- typeOf: factory.organizationType.Project;
20
- };
21
- typeOf: 'OfferItemCondition';
22
- }
23
6
  /**
24
7
  * アイテムコンディションリポジトリ
25
8
  */
26
9
  export declare class MongoRepository {
27
10
  private readonly offerItemConditionModel;
28
11
  constructor(connection: Connection);
29
- static CREATE_MONGO_CONDITIONS(params: any): any[];
12
+ static CREATE_MONGO_CONDITIONS(params: factory.offerItemCondition.ISearchConditions): any[];
30
13
  findById(params: {
31
14
  id: string;
32
- }): Promise<IOfferItemCondition>;
33
- search(params: any, projection?: IProjection): Promise<IOfferItemCondition[]>;
34
- save(params: IOfferItemCondition): Promise<IOfferItemCondition>;
15
+ }): Promise<factory.offerItemCondition.IOfferItemCondition>;
16
+ search(params: factory.offerItemCondition.ISearchConditions, projection?: IProjection): Promise<factory.offerItemCondition.IOfferItemCondition[]>;
17
+ save(params: factory.offerItemCondition.IOfferItemCondition): Promise<factory.offerItemCondition.IOfferItemCondition>;
35
18
  deleteById(params: {
36
19
  id: string;
37
20
  }): Promise<void>;
@@ -31,17 +31,25 @@ class MongoRepository {
31
31
  this.offerItemConditionModel = connection.model(offerItemCondition_1.modelName, offerItemCondition_1.schema);
32
32
  }
33
33
  static CREATE_MONGO_CONDITIONS(params) {
34
- var _a, _b, _c, _d;
34
+ var _a, _b, _c, _d, _e, _f;
35
35
  const andConditions = [];
36
36
  const projectIdEq = (_b = (_a = params.project) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.$eq;
37
37
  if (typeof projectIdEq === 'string') {
38
38
  andConditions.push({ 'project.id': { $eq: projectIdEq } });
39
39
  }
40
- const identifierEq = (_c = params.identifier) === null || _c === void 0 ? void 0 : _c.$eq;
40
+ const idEq = (_c = params.id) === null || _c === void 0 ? void 0 : _c.$eq;
41
+ if (typeof idEq === 'string') {
42
+ andConditions.push({ _id: { $eq: idEq } });
43
+ }
44
+ const idIn = (_d = params.id) === null || _d === void 0 ? void 0 : _d.$in;
45
+ if (Array.isArray(idIn)) {
46
+ andConditions.push({ _id: { $in: idIn } });
47
+ }
48
+ const identifierEq = (_e = params.identifier) === null || _e === void 0 ? void 0 : _e.$eq;
41
49
  if (typeof identifierEq === 'string') {
42
50
  andConditions.push({ identifier: { $eq: identifierEq } });
43
51
  }
44
- const identifierIn = (_d = params.identifier) === null || _d === void 0 ? void 0 : _d.$in;
52
+ const identifierIn = (_f = params.identifier) === null || _f === void 0 ? void 0 : _f.$in;
45
53
  if (Array.isArray(identifierIn)) {
46
54
  andConditions.push({ identifier: { $in: identifierIn } });
47
55
  }
@@ -110,5 +110,13 @@ export declare class MongoRepository {
110
110
  $in: string[];
111
111
  };
112
112
  }): Promise<(string)[]>;
113
+ /**
114
+ * 注文に含まれるイベントIDを検索する
115
+ */
116
+ searchReservationForIdsByOrderNumbers(params: {
117
+ orderNumber: {
118
+ $in: string[];
119
+ };
120
+ }): Promise<string[]>;
113
121
  getCursor(conditions: any, projection: any): import("mongoose").Cursor<any, import("mongoose").QueryOptions<any>>;
114
122
  }
@@ -1010,6 +1010,22 @@ class MongoRepository {
1010
1010
  return [...new Set(reservationNumbers)];
1011
1011
  });
1012
1012
  }
1013
+ /**
1014
+ * 注文に含まれるイベントIDを検索する
1015
+ */
1016
+ searchReservationForIdsByOrderNumbers(params) {
1017
+ return __awaiter(this, void 0, void 0, function* () {
1018
+ if (!Array.isArray(params.orderNumber.$in) || params.orderNumber.$in.length === 0) {
1019
+ return [];
1020
+ }
1021
+ return this.orderModel.distinct('acceptedOffers.itemOffered.reservationFor.id', {
1022
+ 'acceptedOffers.itemOffered.reservationFor.id': { $exists: true },
1023
+ orderNumber: params.orderNumber.$in
1024
+ })
1025
+ .setOptions({ maxTimeMS: 10000 })
1026
+ .exec();
1027
+ });
1028
+ }
1013
1029
  getCursor(conditions, projection) {
1014
1030
  return this.orderModel.find(conditions, projection)
1015
1031
  .sort({ orderDate: factory.sortType.Descending })
@@ -96,6 +96,10 @@ export declare class MongoRepository {
96
96
  status?: {
97
97
  $eq?: factory.taskStatus;
98
98
  };
99
+ runsAt?: {
100
+ $gte: Date;
101
+ $lte: Date;
102
+ };
99
103
  }): Promise<import("mongodb").DeleteResult>;
100
104
  countDelayedTasks(params: {
101
105
  delayInSeconds: number;
@@ -411,9 +411,13 @@ class MongoRepository {
411
411
  });
412
412
  }
413
413
  deleteByName(params) {
414
- var _a;
414
+ var _a, _b;
415
415
  return __awaiter(this, void 0, void 0, function* () {
416
- return this.taskModel.deleteMany(Object.assign({ name: { $eq: params.name } }, (typeof ((_a = params.status) === null || _a === void 0 ? void 0 : _a.$eq) === 'string') ? { status: { $eq: params.status.$eq } } : undefined))
416
+ return this.taskModel.deleteMany(Object.assign(Object.assign({ name: { $eq: params.name } }, (typeof ((_a = params.status) === null || _a === void 0 ? void 0 : _a.$eq) === 'string') ? { status: { $eq: params.status.$eq } } : undefined), (((_b = params.runsAt) === null || _b === void 0 ? void 0 : _b.$gte) instanceof Date)
417
+ ? {
418
+ runsAt: { $gte: params.runsAt.$gte, $lte: params.runsAt.$lte }
419
+ }
420
+ : undefined))
417
421
  .exec();
418
422
  });
419
423
  }
@@ -88,7 +88,13 @@ function deleteTransaction(params) {
88
88
  deleteActionResult = yield repos.action.deleteByPurpose({
89
89
  project: { id: transaction.project.id },
90
90
  purpose: { id: transaction.id, typeOf: transaction.typeOf },
91
- typeOf: { $in: [factory.actionType.AuthorizeAction, factory.actionType.OrderAction] }
91
+ typeOf: {
92
+ $in: [
93
+ factory.actionType.AuthorizeAction,
94
+ factory.actionType.InformAction,
95
+ factory.actionType.OrderAction
96
+ ]
97
+ }
92
98
  });
93
99
  // 取引削除
94
100
  yield repos.transaction.findByIdAndDelete({ id: transaction.id });
@@ -1,15 +1,19 @@
1
1
  import * as factory from '../../factory';
2
2
  import { MongoRepository as EmailMessageRepo } from '../../repo/emailMessage';
3
+ import { MongoRepository as EventRepo } from '../../repo/event';
3
4
  import { MongoRepository as MerchantReturnPolicyRepo } from '../../repo/merchantReturnPolicy';
4
5
  import { MongoRepository as OfferRepo } from '../../repo/offer';
6
+ import { MongoRepository as OfferItemConditionRepo } from '../../repo/offerItemCondition';
5
7
  import { MongoRepository as OrderRepo } from '../../repo/order';
6
8
  import { MongoRepository as ReservationRepo } from '../../repo/reservation';
7
9
  import { MongoRepository as SellerRepo } from '../../repo/seller';
8
10
  import { MongoRepository as TaskRepo } from '../../repo/task';
9
11
  import { MongoRepository as TransactionRepo } from '../../repo/transaction';
10
12
  export interface IStartOperationRepos {
13
+ event: EventRepo;
11
14
  merchantReturnPolicy: MerchantReturnPolicyRepo;
12
15
  offer: OfferRepo;
16
+ offerItemCondition: OfferItemConditionRepo;
13
17
  order: OrderRepo;
14
18
  reservation: ReservationRepo;
15
19
  seller: SellerRepo;
@@ -22,9 +22,10 @@ const errorHandler_1 = require("../../errorHandler");
22
22
  * 返品取引開始
23
23
  */
24
24
  function start(params) {
25
+ // tslint:disable-next-line:max-func-body-length
25
26
  return (repos) => __awaiter(this, void 0, void 0, function* () {
26
27
  const now = new Date();
27
- const { orders, offerIds } = yield fixOrders(params)(repos);
28
+ const { eventIds, offerIds, orders } = yield fixOrders(params)(repos);
28
29
  // sellerはorderから自動取得
29
30
  const seller = yield repos.seller.findById({ id: String(orders[0].seller.id) }, { additionalProperty: 0, paymentAccepted: 0 });
30
31
  yield validateOrder({ orders })(repos);
@@ -36,12 +37,38 @@ function start(params) {
36
37
  }
37
38
  // tslint:disable-next-line:no-console
38
39
  // console.log('validating ', offers.length, 'offers before starting returnOrder... offerIds:', offerIds);
40
+ // イベント開始日時取得
41
+ let events = [];
42
+ if (eventIds.length > 0) {
43
+ events = yield repos.event.search({
44
+ id: { $in: eventIds },
45
+ typeOf: factory.eventType.ScreeningEvent
46
+ }, {
47
+ startDate: 1
48
+ });
49
+ }
50
+ let returnPolicies = seller.hasMerchantReturnPolicy;
51
+ if (!Array.isArray(returnPolicies)) {
52
+ returnPolicies = [];
53
+ }
54
+ // アイテムコンディション取得
55
+ let offerItemConditions = [];
56
+ const itemConditionIds = returnPolicies
57
+ .filter((returnPolicy) => { var _a; return typeof ((_a = returnPolicy.itemCondition) === null || _a === void 0 ? void 0 : _a.id) === 'string'; })
58
+ .map((returnPolicy) => { var _a; return String((_a = returnPolicy.itemCondition) === null || _a === void 0 ? void 0 : _a.id); });
59
+ if (itemConditionIds.length > 0) {
60
+ offerItemConditions = yield repos.offerItemCondition.search({
61
+ id: { $in: itemConditionIds }
62
+ });
63
+ }
39
64
  const policiesByOffer = yield searchPoliciesByOffer({ offers })(repos);
40
65
  const appliedReturnPolicy = findApplicableReturnPolicy({
66
+ events,
67
+ offerItemConditions,
41
68
  orders,
42
69
  returningDate: now,
43
70
  reason: params.object.reason,
44
- seller,
71
+ returnPolicies,
45
72
  offers,
46
73
  policiesByOffer
47
74
  });
@@ -115,7 +142,8 @@ function fixOrders(params) {
115
142
  // 不要な属性は参照しない
116
143
  acceptedOffers: 0,
117
144
  customer: 0,
118
- orderedItem: 0
145
+ orderedItem: 0,
146
+ paymentMethods: 0
119
147
  });
120
148
  if (orders.length !== params.object.order.length) {
121
149
  throw new factory.errors.NotFound('Order');
@@ -125,7 +153,10 @@ function fixOrders(params) {
125
153
  confirmationNumbers: [params.object.order[0].confirmationNumber],
126
154
  orderNumbers: [params.object.order[0].orderNumber]
127
155
  });
128
- return { orders, offerIds };
156
+ const eventIds = yield repos.order.searchReservationForIdsByOrderNumbers({
157
+ orderNumber: { $in: [params.object.order[0].orderNumber] }
158
+ });
159
+ return { eventIds, offerIds, orders };
129
160
  });
130
161
  }
131
162
  function validateOrder(params) {
@@ -186,6 +217,7 @@ function searchPoliciesByOffer(params) {
186
217
  /**
187
218
  * 販売者の返品ポリシーを確認する
188
219
  */
220
+ // tslint:disable-next-line:max-func-body-length
189
221
  function findApplicableReturnPolicy(params) {
190
222
  if (params.reason === factory.transaction.returnOrder.Reason.Seller) {
191
223
  // 販売者都合の場合、手数料なしの返金返品ポリシーを適用
@@ -194,14 +226,22 @@ function findApplicableReturnPolicy(params) {
194
226
  returnFees: factory.merchantReturnPolicy.ReturnFeesEnumeration.FreeReturn
195
227
  };
196
228
  }
197
- let returnPolicies = params.seller.hasMerchantReturnPolicy;
198
- if (!Array.isArray(returnPolicies)) {
199
- returnPolicies = [];
200
- }
229
+ const returnPolicies = params.returnPolicies;
201
230
  const returningDate = moment(params.returningDate);
202
- const applicalbleReturnPolicies = [];
231
+ let applicalbleReturnPolicies = [];
203
232
  if (params.reason === factory.transaction.returnOrder.Reason.Customer) {
204
- returnPolicies.forEach((returnPolicy) => {
233
+ // 適用可能なポリシーにフィルター
234
+ applicalbleReturnPolicies = returnPolicies.filter((returnPolicy) => {
235
+ var _a, _b, _c, _d, _e;
236
+ let satisfyMerchantReturnDays = false;
237
+ let offerItemCondition;
238
+ const itemConditionId = (_a = returnPolicy.itemCondition) === null || _a === void 0 ? void 0 : _a.id;
239
+ if (typeof itemConditionId === 'string') {
240
+ offerItemCondition = params.offerItemConditions.find((o) => o.id === itemConditionId);
241
+ if (offerItemCondition === undefined) {
242
+ throw new factory.errors.NotFound('OfferItemCondition');
243
+ }
244
+ }
205
245
  const merchantReturnDays = returnPolicy.merchantReturnDays;
206
246
  if (typeof merchantReturnDays === 'number') {
207
247
  // 返品適用日数を確認する
@@ -212,14 +252,57 @@ function findApplicableReturnPolicy(params) {
212
252
  });
213
253
  // 全注文について日数の確認ができれば適用
214
254
  if (everyOrderApplicable) {
215
- applicalbleReturnPolicies.push(returnPolicy);
255
+ satisfyMerchantReturnDays = true;
216
256
  }
217
257
  }
218
258
  else {
219
259
  // 日数制限なし
220
- applicalbleReturnPolicies.push(returnPolicy);
260
+ satisfyMerchantReturnDays = true;
221
261
  }
262
+ // イベント開始猶予を検証する(2023-05-22~)
263
+ let satisfyItemCondition = true;
264
+ if (offerItemCondition !== undefined) {
265
+ let satisfyGracePeriodMaxValue = true;
266
+ let satisfyGracePeriodMinValue = true;
267
+ // 全イベントについて猶予の確認ができれば適用
268
+ const gracePeriodMaxValue = (_c = (_b = offerItemCondition.itemOffered.serviceOutput) === null || _b === void 0 ? void 0 : _b.reservationFor.gracePeriodBeforeStart) === null || _c === void 0 ? void 0 : _c.maxValue;
269
+ const gracePeriodMinValue = (_e = (_d = offerItemCondition.itemOffered.serviceOutput) === null || _d === void 0 ? void 0 : _d.reservationFor.gracePeriodBeforeStart) === null || _e === void 0 ? void 0 : _e.minValue;
270
+ if (typeof gracePeriodMaxValue === 'number') {
271
+ satisfyGracePeriodMaxValue = params.events.every((event) => {
272
+ return moment(event.startDate)
273
+ .isSameOrBefore(moment(params.returningDate)
274
+ .add(gracePeriodMaxValue, 'seconds'));
275
+ });
276
+ }
277
+ if (typeof gracePeriodMinValue === 'number') {
278
+ satisfyGracePeriodMinValue = params.events.every((event) => {
279
+ return moment(event.startDate)
280
+ .isSameOrAfter(moment(params.returningDate)
281
+ .add(gracePeriodMinValue, 'seconds'));
282
+ });
283
+ }
284
+ satisfyItemCondition = satisfyGracePeriodMaxValue && satisfyGracePeriodMinValue;
285
+ }
286
+ return satisfyMerchantReturnDays && satisfyItemCondition;
222
287
  });
288
+ // returnPolicies.forEach((returnPolicy) => {
289
+ // const merchantReturnDays = returnPolicy.merchantReturnDays;
290
+ // if (typeof merchantReturnDays === 'number') {
291
+ // // 返品適用日数を確認する
292
+ // const everyOrderApplicable = params.orders.every((order) => {
293
+ // const mustBeReturnedUntil = moment(order.orderDate)
294
+ // .add(merchantReturnDays, 'days');
295
+ // return mustBeReturnedUntil.isSameOrAfter(returningDate);
296
+ // });
297
+ // // 全注文について日数の確認ができれば適用
298
+ // if (everyOrderApplicable) {
299
+ // applicalbleReturnPolicies.push(returnPolicy);
300
+ // }
301
+ // } else {
302
+ // // 日数制限なし
303
+ // applicalbleReturnPolicies.push(returnPolicy);
304
+ // }
305
+ // });
223
306
  }
224
307
  // 販売者にポリシーが存在しなければ返品不可
225
308
  if (applicalbleReturnPolicies.length === 0) {
@@ -227,9 +310,20 @@ function findApplicableReturnPolicy(params) {
227
310
  }
228
311
  // オファーの返品ポリシーから返品手数料タイプを決定する
229
312
  const { returnFees } = validateOffersReturnPolicy({ offers: params.offers, policiesByOffer: params.policiesByOffer });
313
+ // restockingFeeが最低のポリシーを自動選択
314
+ let appliedReturnPolicy = applicalbleReturnPolicies[0];
315
+ applicalbleReturnPolicies.forEach((returnPolicy) => {
316
+ const appliedReturnPolicyRestockingFee = (typeof appliedReturnPolicy.restockingFee === 'number')
317
+ ? appliedReturnPolicy.restockingFee
318
+ : 0;
319
+ const restockingFee = (typeof returnPolicy.restockingFee === 'number') ? returnPolicy.restockingFee : 0;
320
+ if (restockingFee < appliedReturnPolicyRestockingFee) {
321
+ appliedReturnPolicy = returnPolicy;
322
+ }
323
+ });
230
324
  return {
231
- merchantReturnDays: applicalbleReturnPolicies[0].merchantReturnDays,
232
- restockingFee: applicalbleReturnPolicies[0].restockingFee,
325
+ merchantReturnDays: appliedReturnPolicy.merchantReturnDays,
326
+ restockingFee: appliedReturnPolicy.restockingFee,
233
327
  returnFees,
234
328
  typeOf: 'MerchantReturnPolicy'
235
329
  };
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "dependencies": {
12
- "@chevre/factory": "4.313.0-alpha.4",
12
+ "@chevre/factory": "4.313.0-alpha.5",
13
13
  "@cinerino/sdk": "3.156.0",
14
14
  "@motionpicture/coa-service": "9.2.0",
15
15
  "@motionpicture/gmo-service": "5.2.0",
@@ -117,5 +117,5 @@
117
117
  "postversion": "git push origin --tags",
118
118
  "prepublishOnly": "npm run clean && npm run build && npm test && npm run doc"
119
119
  },
120
- "version": "21.2.0-alpha.60"
120
+ "version": "21.2.0-alpha.62"
121
121
  }