@unchainedshop/core-quotations 4.3.4 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -3
- package/lib/db/QuotationsCollection.d.ts +9 -9
- package/lib/db/QuotationsCollection.js +8 -11
- package/lib/migrations/20250502111800-currency-code.d.ts +1 -2
- package/lib/migrations/20250502111800-currency-code.js +1 -2
- package/lib/module/configureQuotationsModule.d.ts +7 -7
- package/lib/module/configureQuotationsModule.js +11 -14
- package/lib/quotations-index.d.ts +3 -4
- package/lib/quotations-index.js +3 -4
- package/lib/quotations-settings.d.ts +1 -2
- package/lib/quotations-settings.js +0 -1
- package/package.json +12 -10
- package/lib/db/QuotationsCollection.d.ts.map +0 -1
- package/lib/db/QuotationsCollection.js.map +0 -1
- package/lib/migrations/20250502111800-currency-code.d.ts.map +0 -1
- package/lib/migrations/20250502111800-currency-code.js.map +0 -1
- package/lib/module/configureQuotationsModule.d.ts.map +0 -1
- package/lib/module/configureQuotationsModule.js.map +0 -1
- package/lib/quotations-index.d.ts.map +0 -1
- package/lib/quotations-index.js.map +0 -1
- package/lib/quotations-settings.d.ts.map +0 -1
- package/lib/quotations-settings.js.map +0 -1
- package/src/db/QuotationsCollection.ts +0 -83
- package/src/migrations/20250502111800-currency-code.ts +0 -18
- package/src/module/configureQuotationsModule.ts +0 -230
- package/src/module/quotations-index.test.ts +0 -27
- package/src/quotations-index.ts +0 -4
- package/src/quotations-settings.ts +0 -16
- package/tsconfig.json +0 -10
package/README.md
CHANGED
|
@@ -1,5 +1,102 @@
|
|
|
1
|
-
|
|
1
|
+
[](https://npmjs.com/package/@unchainedshop/core-quotations)
|
|
2
|
+
[](https://opensource.org/licenses/EUPL-1.2)
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
# @unchainedshop/core-quotations
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Quotation management module for the Unchained Engine. Handles quote requests, proposals, and quotation workflows for custom pricing.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @unchainedshop/core-quotations
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { configureQuotationsModule, QuotationStatus } from '@unchainedshop/core-quotations';
|
|
18
|
+
|
|
19
|
+
const quotationsModule = await configureQuotationsModule({ db });
|
|
20
|
+
|
|
21
|
+
// Create a quotation request
|
|
22
|
+
const quotationId = await quotationsModule.create({
|
|
23
|
+
userId: 'user-123',
|
|
24
|
+
productId: 'custom-product-456',
|
|
25
|
+
configuration: [{ key: 'quantity', value: '1000' }],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Propose a quote
|
|
29
|
+
await quotationsModule.propose(quotationId, {
|
|
30
|
+
price: { amount: 5000, currency: 'CHF' },
|
|
31
|
+
expiresAt: new Date('2024-12-31'),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Find quotations
|
|
35
|
+
const quotations = await quotationsModule.findQuotations({
|
|
36
|
+
status: QuotationStatus.PROPOSED,
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API Overview
|
|
41
|
+
|
|
42
|
+
### Module Configuration
|
|
43
|
+
|
|
44
|
+
| Export | Description |
|
|
45
|
+
|--------|-------------|
|
|
46
|
+
| `configureQuotationsModule` | Configure and return the quotations module |
|
|
47
|
+
|
|
48
|
+
### Queries
|
|
49
|
+
|
|
50
|
+
| Method | Description |
|
|
51
|
+
|--------|-------------|
|
|
52
|
+
| `findQuotation` | Find quotation by ID |
|
|
53
|
+
| `findQuotations` | Find quotations with filtering and pagination |
|
|
54
|
+
| `count` | Count quotations matching query |
|
|
55
|
+
| `quotationExists` | Check if quotation exists |
|
|
56
|
+
|
|
57
|
+
### Mutations
|
|
58
|
+
|
|
59
|
+
| Method | Description |
|
|
60
|
+
|--------|-------------|
|
|
61
|
+
| `create` | Create a quotation request |
|
|
62
|
+
| `update` | Update quotation data |
|
|
63
|
+
| `delete` | Delete a quotation |
|
|
64
|
+
| `propose` | Propose a quote |
|
|
65
|
+
| `verify` | Verify a quotation |
|
|
66
|
+
| `reject` | Reject a quotation |
|
|
67
|
+
| `fulfill` | Mark quotation as fulfilled |
|
|
68
|
+
|
|
69
|
+
### Constants
|
|
70
|
+
|
|
71
|
+
| Export | Description |
|
|
72
|
+
|--------|-------------|
|
|
73
|
+
| `QuotationStatus` | Status values (REQUESTED, PROCESSING, PROPOSED, FULLFILLED, REJECTED) |
|
|
74
|
+
|
|
75
|
+
### Settings
|
|
76
|
+
|
|
77
|
+
| Export | Description |
|
|
78
|
+
|--------|-------------|
|
|
79
|
+
| `quotationsSettings` | Access quotation module settings |
|
|
80
|
+
|
|
81
|
+
### Types
|
|
82
|
+
|
|
83
|
+
| Export | Description |
|
|
84
|
+
|--------|-------------|
|
|
85
|
+
| `Quotation` | Quotation document type |
|
|
86
|
+
| `QuotationConfiguration` | Configuration item type |
|
|
87
|
+
| `QuotationsModule` | Module interface type |
|
|
88
|
+
|
|
89
|
+
## Events
|
|
90
|
+
|
|
91
|
+
| Event | Description |
|
|
92
|
+
|-------|-------------|
|
|
93
|
+
| `QUOTATION_CREATE` | Quotation requested |
|
|
94
|
+
| `QUOTATION_UPDATE` | Quotation updated |
|
|
95
|
+
| `QUOTATION_REMOVE` | Quotation deleted |
|
|
96
|
+
| `QUOTATION_PROPOSE` | Quote proposed |
|
|
97
|
+
| `QUOTATION_REJECT` | Quotation rejected |
|
|
98
|
+
| `QUOTATION_FULLFILL` | Quotation fulfilled |
|
|
99
|
+
|
|
100
|
+
## License
|
|
101
|
+
|
|
102
|
+
EUPL-1.2
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { mongodb, TimestampFields, LogFields } from '@unchainedshop/mongodb';
|
|
2
|
-
export declare
|
|
3
|
-
REQUESTED
|
|
4
|
-
PROCESSING
|
|
5
|
-
PROPOSED
|
|
6
|
-
FULLFILLED
|
|
7
|
-
REJECTED
|
|
8
|
-
}
|
|
1
|
+
import { mongodb, type TimestampFields, type LogFields } from '@unchainedshop/mongodb';
|
|
2
|
+
export declare const QuotationStatus: {
|
|
3
|
+
readonly REQUESTED: "REQUESTED";
|
|
4
|
+
readonly PROCESSING: "PROCESSING";
|
|
5
|
+
readonly PROPOSED: "PROPOSED";
|
|
6
|
+
readonly FULLFILLED: "FULLFILLED";
|
|
7
|
+
readonly REJECTED: "REJECTED";
|
|
8
|
+
};
|
|
9
|
+
export type QuotationStatus = (typeof QuotationStatus)[keyof typeof QuotationStatus];
|
|
9
10
|
export interface QuotationProposal {
|
|
10
11
|
price?: number;
|
|
11
12
|
expires?: Date;
|
|
@@ -38,4 +39,3 @@ export type Quotation = {
|
|
|
38
39
|
userId: string;
|
|
39
40
|
} & LogFields & TimestampFields;
|
|
40
41
|
export declare const QuotationsCollection: (db: mongodb.Db) => Promise<mongodb.Collection<Quotation>>;
|
|
41
|
-
//# sourceMappingURL=QuotationsCollection.d.ts.map
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { buildDbIndexes, isDocumentDBCompatModeEnabled, } from '@unchainedshop/mongodb';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
})(QuotationStatus || (QuotationStatus = {}));
|
|
1
|
+
import { mongodb, buildDbIndexes, isDocumentDBCompatModeEnabled, } from '@unchainedshop/mongodb';
|
|
2
|
+
export const QuotationStatus = {
|
|
3
|
+
REQUESTED: 'REQUESTED',
|
|
4
|
+
PROCESSING: 'PROCESSING',
|
|
5
|
+
PROPOSED: 'PROPOSED',
|
|
6
|
+
FULLFILLED: 'FULLFILLED',
|
|
7
|
+
REJECTED: 'REJECTED',
|
|
8
|
+
};
|
|
10
9
|
export const QuotationsCollection = async (db) => {
|
|
11
10
|
const Quotations = db.collection('quotations');
|
|
12
11
|
if (!isDocumentDBCompatModeEnabled()) {
|
|
@@ -34,7 +33,6 @@ export const QuotationsCollection = async (db) => {
|
|
|
34
33
|
},
|
|
35
34
|
]);
|
|
36
35
|
}
|
|
37
|
-
// Quotation Indexes
|
|
38
36
|
await buildDbIndexes(Quotations, [
|
|
39
37
|
{ index: { userId: 1 } },
|
|
40
38
|
{ index: { productId: 1 } },
|
|
@@ -42,4 +40,3 @@ export const QuotationsCollection = async (db) => {
|
|
|
42
40
|
]);
|
|
43
41
|
return Quotations;
|
|
44
42
|
};
|
|
45
|
-
//# sourceMappingURL=QuotationsCollection.js.map
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { MigrationRepository } from '@unchainedshop/mongodb';
|
|
1
|
+
import type { MigrationRepository } from '@unchainedshop/mongodb';
|
|
2
2
|
export default function renameCurrencyCode(repository: MigrationRepository): void;
|
|
3
|
-
//# sourceMappingURL=20250502111800-currency-code.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { QuotationsCollection } from
|
|
1
|
+
import { QuotationsCollection } from "../quotations-index.js";
|
|
2
2
|
export default function renameCurrencyCode(repository) {
|
|
3
3
|
repository?.register({
|
|
4
4
|
id: 20250502113100,
|
|
@@ -11,4 +11,3 @@ export default function renameCurrencyCode(repository) {
|
|
|
11
11
|
},
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
|
-
//# sourceMappingURL=20250502111800-currency-code.js.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { SortOption } from '@unchainedshop/utils';
|
|
2
|
-
import { Quotation, QuotationStatus } from '../db/QuotationsCollection.
|
|
3
|
-
import { mongodb, ModuleInput } from '@unchainedshop/mongodb';
|
|
4
|
-
import { QuotationsSettingsOptions } from '../quotations-settings.
|
|
5
|
-
export interface QuotationQuery
|
|
1
|
+
import { type SortOption } from '@unchainedshop/utils';
|
|
2
|
+
import { type Quotation, QuotationStatus } from '../db/QuotationsCollection.ts';
|
|
3
|
+
import { mongodb, type ModuleInput } from '@unchainedshop/mongodb';
|
|
4
|
+
import { type QuotationsSettingsOptions } from '../quotations-settings.ts';
|
|
5
|
+
export interface QuotationQuery {
|
|
6
6
|
userId?: string;
|
|
7
7
|
queryString?: string;
|
|
8
|
+
quotationIds?: string[];
|
|
8
9
|
}
|
|
9
10
|
export interface QuotationData {
|
|
10
11
|
configuration?: {
|
|
@@ -15,7 +16,7 @@ export interface QuotationData {
|
|
|
15
16
|
productId: string;
|
|
16
17
|
userId: string;
|
|
17
18
|
}
|
|
18
|
-
export declare const buildFindSelector: ({ userId, queryString,
|
|
19
|
+
export declare const buildFindSelector: ({ userId, queryString, quotationIds }?: QuotationQuery) => mongodb.Filter<Quotation>;
|
|
19
20
|
export declare const configureQuotationsModule: ({ db, migrationRepository, options: quotationsOptions, }: ModuleInput<QuotationsSettingsOptions>) => Promise<{
|
|
20
21
|
count: (query: QuotationQuery) => Promise<number>;
|
|
21
22
|
openQuotationWithProduct: ({ productId }: {
|
|
@@ -46,4 +47,3 @@ export declare const configureQuotationsModule: ({ db, migrationRepository, opti
|
|
|
46
47
|
}) => Promise<mongodb.WithId<Quotation> | null>;
|
|
47
48
|
}>;
|
|
48
49
|
export type QuotationsModule = Awaited<ReturnType<typeof configureQuotationsModule>>;
|
|
49
|
-
//# sourceMappingURL=configureQuotationsModule.d.ts.map
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { SortDirection } from '@unchainedshop/utils';
|
|
2
|
-
import { QuotationStatus } from
|
|
2
|
+
import { QuotationStatus } from "../db/QuotationsCollection.js";
|
|
3
3
|
import { emit, registerEvents } from '@unchainedshop/events';
|
|
4
|
-
import { generateDbFilterById, buildSortOptions, generateDbObjectId, assertDocumentDBCompatMode, } from '@unchainedshop/mongodb';
|
|
5
|
-
import { QuotationsCollection } from
|
|
6
|
-
import { quotationsSettings } from
|
|
7
|
-
import renameCurrencyCode from
|
|
4
|
+
import { generateDbFilterById, buildSortOptions, mongodb, generateDbObjectId, assertDocumentDBCompatMode, } from '@unchainedshop/mongodb';
|
|
5
|
+
import { QuotationsCollection } from "../db/QuotationsCollection.js";
|
|
6
|
+
import { quotationsSettings } from "../quotations-settings.js";
|
|
7
|
+
import renameCurrencyCode from "../migrations/20250502111800-currency-code.js";
|
|
8
8
|
const QUOTATION_EVENTS = ['QUOTATION_REQUEST_CREATE', 'QUOTATION_REMOVE', 'QUOTATION_UPDATE'];
|
|
9
|
-
export const buildFindSelector = ({ userId, queryString,
|
|
10
|
-
const selector = {
|
|
9
|
+
export const buildFindSelector = ({ userId, queryString, quotationIds } = {}) => {
|
|
10
|
+
const selector = {};
|
|
11
11
|
if (userId) {
|
|
12
12
|
selector.userId = userId;
|
|
13
13
|
}
|
|
14
|
+
if (quotationIds) {
|
|
15
|
+
selector._id = { $in: quotationIds };
|
|
16
|
+
}
|
|
14
17
|
if (queryString) {
|
|
15
18
|
assertDocumentDBCompatMode();
|
|
16
19
|
selector.$text = { $search: queryString };
|
|
@@ -18,7 +21,6 @@ export const buildFindSelector = ({ userId, queryString, ...rest } = {}) => {
|
|
|
18
21
|
return selector;
|
|
19
22
|
};
|
|
20
23
|
export const configureQuotationsModule = async ({ db, migrationRepository, options: quotationsOptions = {}, }) => {
|
|
21
|
-
// Migration v3 -> v4
|
|
22
24
|
renameCurrencyCode(migrationRepository);
|
|
23
25
|
registerEvents(QUOTATION_EVENTS);
|
|
24
26
|
quotationsSettings.configureSettings(quotationsOptions);
|
|
@@ -43,13 +45,12 @@ export const configureQuotationsModule = async ({ db, migrationRepository, optio
|
|
|
43
45
|
updated: new Date(),
|
|
44
46
|
};
|
|
45
47
|
switch (status) {
|
|
46
|
-
// explicitly use fallthrough here!
|
|
47
48
|
case QuotationStatus.FULLFILLED:
|
|
48
49
|
if (!quotation.fullfilled) {
|
|
49
50
|
$set.fullfilled = date;
|
|
50
51
|
}
|
|
51
52
|
$set.expires = date;
|
|
52
|
-
case QuotationStatus.PROCESSING:
|
|
53
|
+
case QuotationStatus.PROCESSING:
|
|
53
54
|
if (!quotation.quotationNumber) {
|
|
54
55
|
$set.quotationNumber = await findNewQuotationNumber(quotation);
|
|
55
56
|
}
|
|
@@ -90,7 +91,6 @@ export const configureQuotationsModule = async ({ db, migrationRepository, optio
|
|
|
90
91
|
return quotation;
|
|
91
92
|
};
|
|
92
93
|
return {
|
|
93
|
-
// Queries
|
|
94
94
|
count: async (query) => {
|
|
95
95
|
const quotationCount = await Quotations.countDocuments(buildFindSelector(query));
|
|
96
96
|
return quotationCount;
|
|
@@ -114,7 +114,6 @@ export const configureQuotationsModule = async ({ db, migrationRepository, optio
|
|
|
114
114
|
});
|
|
115
115
|
return quotations.toArray();
|
|
116
116
|
},
|
|
117
|
-
// Transformations
|
|
118
117
|
normalizedStatus: (quotation) => {
|
|
119
118
|
return quotation.status === null
|
|
120
119
|
? QuotationStatus.REQUESTED
|
|
@@ -131,7 +130,6 @@ export const configureQuotationsModule = async ({ db, migrationRepository, optio
|
|
|
131
130
|
isProposalValid(quotation) {
|
|
132
131
|
return quotation.status === QuotationStatus.PROPOSED && !this.isExpired(quotation);
|
|
133
132
|
},
|
|
134
|
-
// Mutations
|
|
135
133
|
create: async ({ countryCode, currencyCode, ...quotationData }) => {
|
|
136
134
|
const { insertedId: quotationId } = await Quotations.insertOne({
|
|
137
135
|
_id: generateDbObjectId(),
|
|
@@ -159,4 +157,3 @@ export const configureQuotationsModule = async ({ db, migrationRepository, optio
|
|
|
159
157
|
updateStatus,
|
|
160
158
|
};
|
|
161
159
|
};
|
|
162
|
-
//# sourceMappingURL=configureQuotationsModule.js.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from './db/QuotationsCollection.
|
|
2
|
-
export * from './module/configureQuotationsModule.
|
|
3
|
-
export * from './quotations-settings.
|
|
4
|
-
//# sourceMappingURL=quotations-index.d.ts.map
|
|
1
|
+
export * from './db/QuotationsCollection.ts';
|
|
2
|
+
export * from './module/configureQuotationsModule.ts';
|
|
3
|
+
export * from './quotations-settings.ts';
|
package/lib/quotations-index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
//# sourceMappingURL=quotations-index.js.map
|
|
1
|
+
export * from "./db/QuotationsCollection.js";
|
|
2
|
+
export * from "./module/configureQuotationsModule.js";
|
|
3
|
+
export * from "./quotations-settings.js";
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { Quotation } from './db/QuotationsCollection.
|
|
1
|
+
import type { Quotation } from './db/QuotationsCollection.ts';
|
|
2
2
|
export interface QuotationsSettings {
|
|
3
3
|
quotationNumberHashFn: (quotation: Quotation, index: number) => string;
|
|
4
4
|
configureSettings: (options: QuotationsSettingsOptions) => void;
|
|
5
5
|
}
|
|
6
6
|
export type QuotationsSettingsOptions = Omit<Partial<QuotationsSettings>, 'configureSettings'>;
|
|
7
7
|
export declare const quotationsSettings: QuotationsSettings;
|
|
8
|
-
//# sourceMappingURL=quotations-settings.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/core-quotations",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"main": "lib/quotations-index.js",
|
|
5
5
|
"types": "lib/quotations-index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
7
8
|
"scripts": {
|
|
8
9
|
"clean": "tsc -b --clean",
|
|
9
10
|
"build": "tsc -b",
|
|
10
11
|
"prepublishOnly": "npm run clean && npm run build",
|
|
11
12
|
"watch": "tsc -w",
|
|
12
|
-
"test": "
|
|
13
|
-
"test:watch": "
|
|
13
|
+
"test": "node --test",
|
|
14
|
+
"test:watch": "node --test --watch"
|
|
14
15
|
},
|
|
15
16
|
"repository": {
|
|
16
17
|
"type": "git",
|
|
@@ -22,8 +23,10 @@
|
|
|
22
23
|
"core"
|
|
23
24
|
],
|
|
24
25
|
"authors": [
|
|
25
|
-
"
|
|
26
|
-
"
|
|
26
|
+
"Pascal Kaufmann",
|
|
27
|
+
"Mikael Araya",
|
|
28
|
+
"Vedran Rudelj",
|
|
29
|
+
"Joël Meiller"
|
|
27
30
|
],
|
|
28
31
|
"license": "EUPL-1.2",
|
|
29
32
|
"bugs": {
|
|
@@ -31,13 +34,12 @@
|
|
|
31
34
|
},
|
|
32
35
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
33
36
|
"dependencies": {
|
|
34
|
-
"@unchainedshop/events": "^4.
|
|
35
|
-
"@unchainedshop/logger": "^4.
|
|
36
|
-
"@unchainedshop/utils": "^4.
|
|
37
|
+
"@unchainedshop/events": "^4.5.0",
|
|
38
|
+
"@unchainedshop/logger": "^4.5.0",
|
|
39
|
+
"@unchainedshop/utils": "^4.5.0"
|
|
37
40
|
},
|
|
38
41
|
"devDependencies": {
|
|
39
|
-
"@types/node": "^
|
|
40
|
-
"tsx": "^4.20.3",
|
|
42
|
+
"@types/node": "^25.0.0",
|
|
41
43
|
"typescript": "^5.8.3"
|
|
42
44
|
}
|
|
43
45
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"QuotationsCollection.d.ts","sourceRoot":"","sources":["../../src/db/QuotationsCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAEP,eAAe,EACf,SAAS,EAEV,MAAM,wBAAwB,CAAC;AAEhC,oBAAY,eAAe;IACzB,SAAS,cAAc;IACvB,UAAU,eAAe;IACzB,QAAQ,aAAa;IACrB,UAAU,eAAe;IACzB,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjD;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjD,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,SAAS,GACX,eAAe,CAAC;AAElB,eAAO,MAAM,oBAAoB,GAAU,IAAI,OAAO,CAAC,EAAE,2CAqCxD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"QuotationsCollection.js","sourceRoot":"","sources":["../../src/db/QuotationsCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EAGd,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAEhC,MAAM,CAAN,IAAY,eAMX;AAND,WAAY,eAAe;IACzB,0CAAuB,CAAA;IACvB,4CAAyB,CAAA;IACzB,wCAAqB,CAAA;IACrB,4CAAyB,CAAA;IACzB,wCAAqB,CAAA;AACvB,CAAC,EANW,eAAe,KAAf,eAAe,QAM1B;AA+BD,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,EAAc,EAAE,EAAE;IAC3D,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,CAAY,YAAY,CAAC,CAAC;IAE1D,IAAI,CAAC,6BAA6B,EAAE,EAAE,CAAC;QACrC,MAAM,cAAc,CAAY,UAAU,EAAE;YAC1C;gBACE,KAAK,EAAE;oBACL,GAAG,EAAE,MAAM;oBACX,MAAM,EAAE,MAAM;oBACd,eAAe,EAAE,MAAM;oBACvB,MAAM,EAAE,MAAM;oBACd,mBAAmB,EAAE,MAAM;oBAC3B,sBAAsB,EAAE,MAAM;iBACxB;gBACR,OAAO,EAAE;oBACP,OAAO,EAAE;wBACP,GAAG,EAAE,CAAC;wBACN,MAAM,EAAE,CAAC;wBACT,eAAe,EAAE,CAAC;wBAClB,mBAAmB,EAAE,CAAC;wBACtB,sBAAsB,EAAE,CAAC;wBACzB,MAAM,EAAE,CAAC;qBACV;oBACD,IAAI,EAAE,2BAA2B;iBAClC;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAED,oBAAoB;IACpB,MAAM,cAAc,CAAY,UAAU,EAAE;QAC1C,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;QACxB,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE;QAC3B,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;KACzB,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"20250502111800-currency-code.d.ts","sourceRoot":"","sources":["../../src/migrations/20250502111800-currency-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG7D,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,UAAU,EAAE,mBAAmB,QAczE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"20250502111800-currency-code.js","sourceRoot":"","sources":["../../src/migrations/20250502111800-currency-code.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,UAA+B;IACxE,UAAU,EAAE,QAAQ,CAAC;QACnB,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,qDAAqD;QAC3D,EAAE,EAAE,KAAK,IAAI,EAAE;YACb,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAC7D,MAAM,UAAU,CAAC,UAAU,CACzB,EAAE,EACF;gBACE,OAAO,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE;aACtC,CACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"configureQuotationsModule.d.ts","sourceRoot":"","sources":["../../src/module/configureQuotationsModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAE3E,OAAO,EAGL,OAAO,EAEP,WAAW,EAEZ,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAsB,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAI1F,MAAM,WAAW,cAAe,SAAQ,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AACD,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,eAAO,MAAM,iBAAiB,GAAI,mCAAkC,cAAmB,8BAYtF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAU,0DAI7C,WAAW,CAAC,yBAAyB,CAAC;mBAyFhB,cAAc,KAAG,OAAO,CAAC,MAAM,CAAC;8CAIL;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE;qCAM9B;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,YAAY,OAAO,CAAC,WAAW;wDAWxF,cAAc,GAAG;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;KACrB,YACS,OAAO,CAAC,WAAW,KAC5B,OAAO,CAAC,SAAS,EAAE,CAAC;kCAaO,SAAS,KAAG,eAAe;yBAMpC,SAAS,qBAAqB;QAAE,aAAa,EAAE,IAAI,CAAA;KAAE;+BAQ/C,SAAS,GAAG,OAAO;8DAS3C,aAAa,GAAG;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE;4CAgBG,MAAM;iCA7FqB,MAAM,UAAU,GAAG;kCAAnB,MAAM,UAAU,GAAG;gCAxD/E,MAAM,oBACI;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;EAgKpE,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"configureQuotationsModule.js","sourceRoot":"","sources":["../../src/module/configureQuotationsModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"quotations-index.d.ts","sourceRoot":"","sources":["../src/quotations-index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAE7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,0BAA0B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"quotations-index.js","sourceRoot":"","sources":["../src/quotations-index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAE7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,0BAA0B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"quotations-settings.d.ts","sourceRoot":"","sources":["../src/quotations-settings.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,MAAM,WAAW,kBAAkB;IACjC,qBAAqB,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACvE,iBAAiB,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;CACjE;AAED,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,mBAAmB,CAAC,CAAC;AAE/F,eAAO,MAAM,kBAAkB,EAAE,kBAKhC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"quotations-settings.js","sourceRoot":"","sources":["../src/quotations-settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAU1D,MAAM,CAAC,MAAM,kBAAkB,GAAuB;IACpD,qBAAqB,EAAE,kBAAkB;IACzC,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,GAAG,EAAE;QAC9C,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,IAAI,kBAAkB,CAAC;IAC3E,CAAC;CACF,CAAC"}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
mongodb,
|
|
3
|
-
buildDbIndexes,
|
|
4
|
-
TimestampFields,
|
|
5
|
-
LogFields,
|
|
6
|
-
isDocumentDBCompatModeEnabled,
|
|
7
|
-
} from '@unchainedshop/mongodb';
|
|
8
|
-
|
|
9
|
-
export enum QuotationStatus {
|
|
10
|
-
REQUESTED = 'REQUESTED',
|
|
11
|
-
PROCESSING = 'PROCESSING',
|
|
12
|
-
PROPOSED = 'PROPOSED',
|
|
13
|
-
FULLFILLED = 'FULLFILLED',
|
|
14
|
-
REJECTED = 'REJECTED',
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface QuotationProposal {
|
|
18
|
-
price?: number;
|
|
19
|
-
expires?: Date;
|
|
20
|
-
meta?: any;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface QuotationItemConfiguration {
|
|
24
|
-
quantity?: number;
|
|
25
|
-
configuration: { key: string; value: string }[];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type Quotation = {
|
|
29
|
-
_id: string;
|
|
30
|
-
configuration?: { key: string; value: string }[];
|
|
31
|
-
context?: any;
|
|
32
|
-
countryCode?: string;
|
|
33
|
-
currencyCode?: string;
|
|
34
|
-
expires?: Date;
|
|
35
|
-
fullfilled?: Date;
|
|
36
|
-
meta?: any;
|
|
37
|
-
price?: number;
|
|
38
|
-
productId: string;
|
|
39
|
-
quotationNumber?: string;
|
|
40
|
-
rejected?: Date;
|
|
41
|
-
status: string | null;
|
|
42
|
-
userId: string;
|
|
43
|
-
} & LogFields &
|
|
44
|
-
TimestampFields;
|
|
45
|
-
|
|
46
|
-
export const QuotationsCollection = async (db: mongodb.Db) => {
|
|
47
|
-
const Quotations = db.collection<Quotation>('quotations');
|
|
48
|
-
|
|
49
|
-
if (!isDocumentDBCompatModeEnabled()) {
|
|
50
|
-
await buildDbIndexes<Quotation>(Quotations, [
|
|
51
|
-
{
|
|
52
|
-
index: {
|
|
53
|
-
_id: 'text',
|
|
54
|
-
userId: 'text',
|
|
55
|
-
quotationNumber: 'text',
|
|
56
|
-
status: 'text',
|
|
57
|
-
'contact.telNumber': 'text',
|
|
58
|
-
'contact.emailAddress': 'text',
|
|
59
|
-
} as any,
|
|
60
|
-
options: {
|
|
61
|
-
weights: {
|
|
62
|
-
_id: 8,
|
|
63
|
-
userId: 3,
|
|
64
|
-
quotationNumber: 6,
|
|
65
|
-
'contact.telNumber': 5,
|
|
66
|
-
'contact.emailAddress': 4,
|
|
67
|
-
status: 1,
|
|
68
|
-
},
|
|
69
|
-
name: 'quotation_fulltext_search',
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
]);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Quotation Indexes
|
|
76
|
-
await buildDbIndexes<Quotation>(Quotations, [
|
|
77
|
-
{ index: { userId: 1 } },
|
|
78
|
-
{ index: { productId: 1 } },
|
|
79
|
-
{ index: { status: 1 } },
|
|
80
|
-
]);
|
|
81
|
-
|
|
82
|
-
return Quotations;
|
|
83
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { MigrationRepository } from '@unchainedshop/mongodb';
|
|
2
|
-
import { QuotationsCollection } from '../quotations-index.js';
|
|
3
|
-
|
|
4
|
-
export default function renameCurrencyCode(repository: MigrationRepository) {
|
|
5
|
-
repository?.register({
|
|
6
|
-
id: 20250502113100,
|
|
7
|
-
name: 'Rename quotation.currency to quotation.currencyCode',
|
|
8
|
-
up: async () => {
|
|
9
|
-
const Quotations = await QuotationsCollection(repository.db);
|
|
10
|
-
await Quotations.updateMany(
|
|
11
|
-
{},
|
|
12
|
-
{
|
|
13
|
-
$rename: { currency: 'currencyCode' },
|
|
14
|
-
},
|
|
15
|
-
);
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
}
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import { SortDirection, SortOption } from '@unchainedshop/utils';
|
|
2
|
-
import { Quotation, QuotationStatus } from '../db/QuotationsCollection.js';
|
|
3
|
-
import { emit, registerEvents } from '@unchainedshop/events';
|
|
4
|
-
import {
|
|
5
|
-
generateDbFilterById,
|
|
6
|
-
buildSortOptions,
|
|
7
|
-
mongodb,
|
|
8
|
-
generateDbObjectId,
|
|
9
|
-
ModuleInput,
|
|
10
|
-
assertDocumentDBCompatMode,
|
|
11
|
-
} from '@unchainedshop/mongodb';
|
|
12
|
-
import { QuotationsCollection } from '../db/QuotationsCollection.js';
|
|
13
|
-
import { quotationsSettings, QuotationsSettingsOptions } from '../quotations-settings.js';
|
|
14
|
-
|
|
15
|
-
import renameCurrencyCode from '../migrations/20250502111800-currency-code.js';
|
|
16
|
-
|
|
17
|
-
export interface QuotationQuery extends mongodb.Filter<Quotation> {
|
|
18
|
-
userId?: string;
|
|
19
|
-
queryString?: string;
|
|
20
|
-
}
|
|
21
|
-
export interface QuotationData {
|
|
22
|
-
configuration?: { key: string; value: string }[];
|
|
23
|
-
countryCode?: string;
|
|
24
|
-
productId: string;
|
|
25
|
-
userId: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const QUOTATION_EVENTS: string[] = ['QUOTATION_REQUEST_CREATE', 'QUOTATION_REMOVE', 'QUOTATION_UPDATE'];
|
|
29
|
-
|
|
30
|
-
export const buildFindSelector = ({ userId, queryString, ...rest }: QuotationQuery = {}) => {
|
|
31
|
-
const selector: mongodb.Filter<Quotation> = { ...rest };
|
|
32
|
-
|
|
33
|
-
if (userId) {
|
|
34
|
-
selector.userId = userId;
|
|
35
|
-
}
|
|
36
|
-
if (queryString) {
|
|
37
|
-
assertDocumentDBCompatMode();
|
|
38
|
-
(selector as any).$text = { $search: queryString };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return selector;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export const configureQuotationsModule = async ({
|
|
45
|
-
db,
|
|
46
|
-
migrationRepository,
|
|
47
|
-
options: quotationsOptions = {},
|
|
48
|
-
}: ModuleInput<QuotationsSettingsOptions>) => {
|
|
49
|
-
// Migration v3 -> v4
|
|
50
|
-
renameCurrencyCode(migrationRepository);
|
|
51
|
-
|
|
52
|
-
registerEvents(QUOTATION_EVENTS);
|
|
53
|
-
|
|
54
|
-
quotationsSettings.configureSettings(quotationsOptions);
|
|
55
|
-
|
|
56
|
-
const Quotations = await QuotationsCollection(db);
|
|
57
|
-
|
|
58
|
-
const findNewQuotationNumber = async (quotation: Quotation, index = 0) => {
|
|
59
|
-
const newHashID = quotationsSettings.quotationNumberHashFn(quotation, index);
|
|
60
|
-
if ((await Quotations.countDocuments({ quotationNumber: newHashID }, { limit: 1 })) === 0) {
|
|
61
|
-
return newHashID;
|
|
62
|
-
}
|
|
63
|
-
return findNewQuotationNumber(quotation, index + 1);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const updateStatus = async (
|
|
67
|
-
quotationId: string,
|
|
68
|
-
{ status, info = '' }: { status: QuotationStatus; info?: string },
|
|
69
|
-
) => {
|
|
70
|
-
const selector = generateDbFilterById(quotationId);
|
|
71
|
-
const quotation = await Quotations.findOne(selector, {});
|
|
72
|
-
|
|
73
|
-
if (!quotation) return null;
|
|
74
|
-
|
|
75
|
-
if (quotation.status === status) return quotation;
|
|
76
|
-
|
|
77
|
-
const date = new Date();
|
|
78
|
-
const $set: Partial<Quotation> = {
|
|
79
|
-
status,
|
|
80
|
-
updated: new Date(),
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
switch (status) {
|
|
84
|
-
// explicitly use fallthrough here!
|
|
85
|
-
case QuotationStatus.FULLFILLED:
|
|
86
|
-
if (!quotation.fullfilled) {
|
|
87
|
-
$set.fullfilled = date;
|
|
88
|
-
}
|
|
89
|
-
$set.expires = date;
|
|
90
|
-
case QuotationStatus.PROCESSING: // eslint-disable-line no-fallthrough
|
|
91
|
-
if (!quotation.quotationNumber) {
|
|
92
|
-
$set.quotationNumber = await findNewQuotationNumber(quotation);
|
|
93
|
-
}
|
|
94
|
-
break;
|
|
95
|
-
case QuotationStatus.REJECTED:
|
|
96
|
-
$set.expires = date;
|
|
97
|
-
$set.rejected = date;
|
|
98
|
-
break;
|
|
99
|
-
default:
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const modifier: mongodb.UpdateFilter<Quotation> = {
|
|
104
|
-
$set,
|
|
105
|
-
$push: {
|
|
106
|
-
log: {
|
|
107
|
-
date,
|
|
108
|
-
status,
|
|
109
|
-
info,
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const updatedQuotation = await Quotations.findOneAndUpdate(selector, modifier, {
|
|
115
|
-
returnDocument: 'after',
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
await emit('QUOTATION_UPDATE', { quotation, field: 'status' });
|
|
119
|
-
|
|
120
|
-
return updatedQuotation;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const updateQuotationFields = (fieldKeys: string[]) => async (quotationId: string, values: any) => {
|
|
124
|
-
const quotation = await Quotations.findOneAndUpdate(generateDbFilterById(quotationId), {
|
|
125
|
-
$set: {
|
|
126
|
-
updated: new Date(),
|
|
127
|
-
...fieldKeys.reduce((set, key) => ({ ...set, [key]: values[key] }), {}),
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
if (!quotation) return null;
|
|
131
|
-
await emit('QUOTATION_UPDATE', { quotation, fields: fieldKeys });
|
|
132
|
-
return quotation;
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
// Queries
|
|
137
|
-
count: async (query: QuotationQuery): Promise<number> => {
|
|
138
|
-
const quotationCount = await Quotations.countDocuments(buildFindSelector(query));
|
|
139
|
-
return quotationCount;
|
|
140
|
-
},
|
|
141
|
-
openQuotationWithProduct: async ({ productId }: { productId: string }) => {
|
|
142
|
-
const selector: mongodb.Filter<Quotation> = { productId };
|
|
143
|
-
selector.status = { $in: [QuotationStatus.REQUESTED, QuotationStatus.PROPOSED] };
|
|
144
|
-
return Quotations.findOne(selector);
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
findQuotation: async ({ quotationId }: { quotationId: string }, options?: mongodb.FindOptions) => {
|
|
148
|
-
const selector = generateDbFilterById(quotationId);
|
|
149
|
-
return Quotations.findOne(selector, options);
|
|
150
|
-
},
|
|
151
|
-
|
|
152
|
-
findQuotations: async (
|
|
153
|
-
{
|
|
154
|
-
limit,
|
|
155
|
-
offset,
|
|
156
|
-
sort,
|
|
157
|
-
...query
|
|
158
|
-
}: QuotationQuery & {
|
|
159
|
-
limit?: number;
|
|
160
|
-
offset?: number;
|
|
161
|
-
sort?: SortOption[];
|
|
162
|
-
},
|
|
163
|
-
options?: mongodb.FindOptions,
|
|
164
|
-
): Promise<Quotation[]> => {
|
|
165
|
-
const defaultSortOption: SortOption[] = [{ key: 'created', value: SortDirection.ASC }];
|
|
166
|
-
const quotations = Quotations.find(buildFindSelector(query), {
|
|
167
|
-
limit,
|
|
168
|
-
skip: offset,
|
|
169
|
-
sort: buildSortOptions(sort || defaultSortOption),
|
|
170
|
-
...options,
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
return quotations.toArray();
|
|
174
|
-
},
|
|
175
|
-
|
|
176
|
-
// Transformations
|
|
177
|
-
normalizedStatus: (quotation: Quotation): QuotationStatus => {
|
|
178
|
-
return quotation.status === null
|
|
179
|
-
? QuotationStatus.REQUESTED
|
|
180
|
-
: (quotation.status as QuotationStatus);
|
|
181
|
-
},
|
|
182
|
-
|
|
183
|
-
isExpired(quotation: Quotation, { referenceDate }: { referenceDate: Date }) {
|
|
184
|
-
const relevantDate = referenceDate ? new Date(referenceDate) : new Date();
|
|
185
|
-
if (!quotation.expires) return false;
|
|
186
|
-
const expiryDate = new Date(quotation.expires);
|
|
187
|
-
const isQuotationExpired = relevantDate.getTime() > expiryDate.getTime();
|
|
188
|
-
return isQuotationExpired;
|
|
189
|
-
},
|
|
190
|
-
|
|
191
|
-
isProposalValid(quotation: Quotation): boolean {
|
|
192
|
-
return quotation.status === QuotationStatus.PROPOSED && !this.isExpired(quotation);
|
|
193
|
-
},
|
|
194
|
-
|
|
195
|
-
// Mutations
|
|
196
|
-
create: async ({
|
|
197
|
-
countryCode,
|
|
198
|
-
currencyCode,
|
|
199
|
-
...quotationData
|
|
200
|
-
}: QuotationData & { currencyCode: string }) => {
|
|
201
|
-
const { insertedId: quotationId } = await Quotations.insertOne({
|
|
202
|
-
_id: generateDbObjectId(),
|
|
203
|
-
created: new Date(),
|
|
204
|
-
...quotationData,
|
|
205
|
-
configuration: quotationData.configuration || [],
|
|
206
|
-
countryCode,
|
|
207
|
-
currencyCode,
|
|
208
|
-
log: [],
|
|
209
|
-
status: QuotationStatus.REQUESTED,
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
const quotation = (await Quotations.findOne(generateDbFilterById(quotationId), {})) as Quotation;
|
|
213
|
-
await emit('QUOTATION_REQUEST_CREATE', { quotation });
|
|
214
|
-
return quotation;
|
|
215
|
-
},
|
|
216
|
-
deleteRequestedUserQuotations: async (userId: string) => {
|
|
217
|
-
const { deletedCount } = await Quotations.deleteMany({
|
|
218
|
-
userId,
|
|
219
|
-
status: { $in: [QuotationStatus.REQUESTED, null] },
|
|
220
|
-
});
|
|
221
|
-
return deletedCount;
|
|
222
|
-
},
|
|
223
|
-
updateContext: updateQuotationFields(['context']),
|
|
224
|
-
updateProposal: updateQuotationFields(['price', 'expires', 'meta']),
|
|
225
|
-
|
|
226
|
-
updateStatus,
|
|
227
|
-
};
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
export type QuotationsModule = Awaited<ReturnType<typeof configureQuotationsModule>>;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { describe, it } from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
import { buildFindSelector } from './configureQuotationsModule.js';
|
|
4
|
-
|
|
5
|
-
describe('Quotation', () => {
|
|
6
|
-
describe('buildFindSelector', () => {
|
|
7
|
-
it('Return correct filter object when passed no argument', () => {
|
|
8
|
-
assert.deepStrictEqual(buildFindSelector({}), {});
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('Return correct filter object when passed queryString and userId', () => {
|
|
12
|
-
assert.deepStrictEqual(buildFindSelector({ queryString: 'hello world', userId: 'admin-id' }), {
|
|
13
|
-
userId: 'admin-id',
|
|
14
|
-
$text: { $search: 'hello world' },
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('Return correct filter object when passed userId', () => {
|
|
19
|
-
assert.deepStrictEqual(buildFindSelector({ userId: 'admin-id' }), { userId: 'admin-id' });
|
|
20
|
-
});
|
|
21
|
-
it('Return correct filter object when passed queryString', () => {
|
|
22
|
-
assert.deepStrictEqual(buildFindSelector({ queryString: 'hello world' }), {
|
|
23
|
-
$text: { $search: 'hello world' },
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
});
|
package/src/quotations-index.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { generateRandomHash } from '@unchainedshop/utils';
|
|
2
|
-
import { Quotation } from './db/QuotationsCollection.js';
|
|
3
|
-
|
|
4
|
-
export interface QuotationsSettings {
|
|
5
|
-
quotationNumberHashFn: (quotation: Quotation, index: number) => string;
|
|
6
|
-
configureSettings: (options: QuotationsSettingsOptions) => void;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type QuotationsSettingsOptions = Omit<Partial<QuotationsSettings>, 'configureSettings'>;
|
|
10
|
-
|
|
11
|
-
export const quotationsSettings: QuotationsSettings = {
|
|
12
|
-
quotationNumberHashFn: generateRandomHash,
|
|
13
|
-
configureSettings({ quotationNumberHashFn } = {}) {
|
|
14
|
-
this.quotationNumberHashFn = quotationNumberHashFn || generateRandomHash;
|
|
15
|
-
},
|
|
16
|
-
};
|