@unchainedshop/core-quotations 4.3.4 → 4.4.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 +4 -5
- package/lib/module/configureQuotationsModule.js +6 -12
- 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 +11 -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,7 +1,7 @@
|
|
|
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.
|
|
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
5
|
export interface QuotationQuery extends mongodb.Filter<Quotation> {
|
|
6
6
|
userId?: string;
|
|
7
7
|
queryString?: string;
|
|
@@ -46,4 +46,3 @@ export declare const configureQuotationsModule: ({ db, migrationRepository, opti
|
|
|
46
46
|
}) => Promise<mongodb.WithId<Quotation> | null>;
|
|
47
47
|
}>;
|
|
48
48
|
export type QuotationsModule = Awaited<ReturnType<typeof configureQuotationsModule>>;
|
|
49
|
-
//# sourceMappingURL=configureQuotationsModule.d.ts.map
|
|
@@ -1,10 +1,10 @@
|
|
|
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
9
|
export const buildFindSelector = ({ userId, queryString, ...rest } = {}) => {
|
|
10
10
|
const selector = { ...rest };
|
|
@@ -18,7 +18,6 @@ export const buildFindSelector = ({ userId, queryString, ...rest } = {}) => {
|
|
|
18
18
|
return selector;
|
|
19
19
|
};
|
|
20
20
|
export const configureQuotationsModule = async ({ db, migrationRepository, options: quotationsOptions = {}, }) => {
|
|
21
|
-
// Migration v3 -> v4
|
|
22
21
|
renameCurrencyCode(migrationRepository);
|
|
23
22
|
registerEvents(QUOTATION_EVENTS);
|
|
24
23
|
quotationsSettings.configureSettings(quotationsOptions);
|
|
@@ -43,13 +42,12 @@ export const configureQuotationsModule = async ({ db, migrationRepository, optio
|
|
|
43
42
|
updated: new Date(),
|
|
44
43
|
};
|
|
45
44
|
switch (status) {
|
|
46
|
-
// explicitly use fallthrough here!
|
|
47
45
|
case QuotationStatus.FULLFILLED:
|
|
48
46
|
if (!quotation.fullfilled) {
|
|
49
47
|
$set.fullfilled = date;
|
|
50
48
|
}
|
|
51
49
|
$set.expires = date;
|
|
52
|
-
case QuotationStatus.PROCESSING:
|
|
50
|
+
case QuotationStatus.PROCESSING:
|
|
53
51
|
if (!quotation.quotationNumber) {
|
|
54
52
|
$set.quotationNumber = await findNewQuotationNumber(quotation);
|
|
55
53
|
}
|
|
@@ -90,7 +88,6 @@ export const configureQuotationsModule = async ({ db, migrationRepository, optio
|
|
|
90
88
|
return quotation;
|
|
91
89
|
};
|
|
92
90
|
return {
|
|
93
|
-
// Queries
|
|
94
91
|
count: async (query) => {
|
|
95
92
|
const quotationCount = await Quotations.countDocuments(buildFindSelector(query));
|
|
96
93
|
return quotationCount;
|
|
@@ -114,7 +111,6 @@ export const configureQuotationsModule = async ({ db, migrationRepository, optio
|
|
|
114
111
|
});
|
|
115
112
|
return quotations.toArray();
|
|
116
113
|
},
|
|
117
|
-
// Transformations
|
|
118
114
|
normalizedStatus: (quotation) => {
|
|
119
115
|
return quotation.status === null
|
|
120
116
|
? QuotationStatus.REQUESTED
|
|
@@ -131,7 +127,6 @@ export const configureQuotationsModule = async ({ db, migrationRepository, optio
|
|
|
131
127
|
isProposalValid(quotation) {
|
|
132
128
|
return quotation.status === QuotationStatus.PROPOSED && !this.isExpired(quotation);
|
|
133
129
|
},
|
|
134
|
-
// Mutations
|
|
135
130
|
create: async ({ countryCode, currencyCode, ...quotationData }) => {
|
|
136
131
|
const { insertedId: quotationId } = await Quotations.insertOne({
|
|
137
132
|
_id: generateDbObjectId(),
|
|
@@ -159,4 +154,3 @@ export const configureQuotationsModule = async ({ db, migrationRepository, optio
|
|
|
159
154
|
updateStatus,
|
|
160
155
|
};
|
|
161
156
|
};
|
|
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/core-quotations",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"main": "lib/quotations-index.js",
|
|
5
5
|
"types": "lib/quotations-index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"build": "tsc -b",
|
|
10
10
|
"prepublishOnly": "npm run clean && npm run build",
|
|
11
11
|
"watch": "tsc -w",
|
|
12
|
-
"test": "
|
|
13
|
-
"test:watch": "
|
|
12
|
+
"test": "node --test",
|
|
13
|
+
"test:watch": "node --test --watch"
|
|
14
14
|
},
|
|
15
15
|
"repository": {
|
|
16
16
|
"type": "git",
|
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
"core"
|
|
23
23
|
],
|
|
24
24
|
"authors": [
|
|
25
|
-
"
|
|
26
|
-
"
|
|
25
|
+
"Pascal Kaufmann",
|
|
26
|
+
"Mikael Araya",
|
|
27
|
+
"Vedran Rudelj",
|
|
28
|
+
"Joël Meiller"
|
|
27
29
|
],
|
|
28
30
|
"license": "EUPL-1.2",
|
|
29
31
|
"bugs": {
|
|
@@ -31,13 +33,12 @@
|
|
|
31
33
|
},
|
|
32
34
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
33
35
|
"dependencies": {
|
|
34
|
-
"@unchainedshop/events": "^4.
|
|
35
|
-
"@unchainedshop/logger": "^4.
|
|
36
|
-
"@unchainedshop/utils": "^4.
|
|
36
|
+
"@unchainedshop/events": "^4.4.0",
|
|
37
|
+
"@unchainedshop/logger": "^4.4.0",
|
|
38
|
+
"@unchainedshop/utils": "^4.4.0"
|
|
37
39
|
},
|
|
38
40
|
"devDependencies": {
|
|
39
|
-
"@types/node": "^
|
|
40
|
-
"tsx": "^4.20.3",
|
|
41
|
+
"@types/node": "^25.0.0",
|
|
41
42
|
"typescript": "^5.8.3"
|
|
42
43
|
}
|
|
43
44
|
}
|
|
@@ -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
|
-
};
|