@unchainedshop/plugins 4.0.0-rc.18 → 4.0.0-rc.19
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/lib/files/gridfs/adapter.js +4 -4
- package/lib/files/gridfs/adapter.js.map +1 -1
- package/lib/files/minio/index.js +4 -4
- package/lib/files/minio/index.js.map +1 -1
- package/lib/pricing/delivery-swiss-tax.d.ts.map +1 -1
- package/lib/pricing/delivery-swiss-tax.js +6 -15
- package/lib/pricing/delivery-swiss-tax.js.map +1 -1
- package/lib/pricing/product-swiss-tax.d.ts +1 -2
- package/lib/pricing/product-swiss-tax.d.ts.map +1 -1
- package/lib/pricing/product-swiss-tax.js +25 -15
- package/lib/pricing/product-swiss-tax.js.map +1 -1
- package/lib/pricing/tax/ch.d.ts +7 -8
- package/lib/pricing/tax/ch.d.ts.map +1 -1
- package/lib/pricing/tax/ch.js +15 -10
- package/lib/pricing/tax/ch.js.map +1 -1
- package/lib/pricing/utils/isDeliveryAddressInCountry.d.ts +7 -0
- package/lib/pricing/utils/isDeliveryAddressInCountry.d.ts.map +1 -0
- package/lib/pricing/utils/isDeliveryAddressInCountry.js +13 -0
- package/lib/pricing/utils/isDeliveryAddressInCountry.js.map +1 -0
- package/package.json +14 -18
- package/src/files/gridfs/adapter.ts +4 -4
- package/src/files/minio/index.ts +4 -4
- package/src/pricing/delivery-swiss-tax.ts +14 -21
- package/src/pricing/product-swiss-tax.ts +37 -25
- package/src/pricing/tax/ch.test.ts +1 -86
- package/src/pricing/tax/ch.ts +28 -25
- package/src/pricing/utils/isDeliveryAddressInCountry.test.ts +106 -0
- package/src/pricing/utils/isDeliveryAddressInCountry.ts +26 -0
- package/src/pricing/product-swiss-tax.test.ts +0 -54
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Readable, PassThrough } from 'node:stream';
|
|
2
2
|
import { finished, pipeline } from 'node:stream/promises';
|
|
3
|
-
import
|
|
3
|
+
import mime from 'mime/lite';
|
|
4
4
|
import { FileAdapter, FileDirector, buildHashedFilename, resolveExpirationDate, } from '@unchainedshop/file-upload';
|
|
5
5
|
import sign from './sign.js';
|
|
6
6
|
import { filesSettings } from '@unchainedshop/core-files';
|
|
@@ -36,7 +36,7 @@ export const GridFSAdapter = {
|
|
|
36
36
|
directoryName,
|
|
37
37
|
expiryDate,
|
|
38
38
|
fileName,
|
|
39
|
-
type:
|
|
39
|
+
type: mime.getType(fileName),
|
|
40
40
|
putURL,
|
|
41
41
|
url,
|
|
42
42
|
};
|
|
@@ -55,7 +55,7 @@ export const GridFSAdapter = {
|
|
|
55
55
|
}
|
|
56
56
|
const expiryDate = resolveExpirationDate();
|
|
57
57
|
const hashedFilename = await buildHashedFilename(directoryName, fileName, expiryDate);
|
|
58
|
-
const type =
|
|
58
|
+
const type = mime.getType(fileName) || (await Promise.resolve(rawFile)).mimetype;
|
|
59
59
|
const writeStream = await modules.gridfsFileUploads.createWriteStream(directoryName, hashedFilename, fileName, {
|
|
60
60
|
metadata: { 'content-type': type },
|
|
61
61
|
chunkSizeBytes: 1024 * 1024, // 1MB
|
|
@@ -84,7 +84,7 @@ export const GridFSAdapter = {
|
|
|
84
84
|
const response = await fetch(href, { headers });
|
|
85
85
|
if (!response.ok)
|
|
86
86
|
throw new Error(`Unexpected response for ${href}: ${response.statusText}`);
|
|
87
|
-
const type =
|
|
87
|
+
const type = mime.getType(fileName) || response.headers.get('content-type');
|
|
88
88
|
const writeStream = await modules.gridfsFileUploads.createWriteStream(directoryName, hashedFilename, fileName, {
|
|
89
89
|
metadata: { 'content-type': type },
|
|
90
90
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/files/gridfs/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/files/gridfs/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,qBAAqB,GAEtB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAI1D,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;AAEjC,MAAM,cAAc,GAAG,CAAC,MAAW,EAAE,EAAE;IACrC,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAElB,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAItB;IACF,GAAG,EAAE,0CAA0C;IAC/C,KAAK,EAAE,wCAAwC;IAC/C,OAAO,EAAE,OAAO;IAEhB,GAAG,WAAW;IACd,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM;QAClC,qDAAqD;QACrD,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS;YAAE,OAAO,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC;QAErD,MAAM,eAAe,GACnB,MAAM;YACN,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,aAAa,EAAE,wBAAwB,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAE5F,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QACnE,OAAO,GAAG,IAAI,CAAC,GAAG,MAAM,SAAS,MAAM,eAAe,EAAE,CAAC;IAC3D,CAAC;IACD,KAAK,CAAC,eAAe,CAAC,aAAa,EAAE,QAAQ;QAC3C,MAAM,UAAU,GAAG,qBAAqB,EAAE,CAAC;QAC3C,MAAM,cAAc,GAAG,MAAM,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QACtF,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,cAAc,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;QAElF,MAAM,MAAM,GAAG,IAAI,GAAG,CACpB,WAAW,aAAa,IAAI,kBAAkB,CAC5C,QAAQ,CACT,MAAM,UAAU,CAAC,OAAO,EAAE,MAAM,SAAS,EAAE,EAC5C,QAAQ,CACT,CAAC,IAAI,CAAC;QACP,MAAM,GAAG,GAAG,WAAW,aAAa,IAAI,cAAc,EAAE,CAAC;QAEzD,OAAO;YACL,GAAG,EAAE,cAAc;YACnB,aAAa;YACb,UAAU;YACV,QAAQ;YACR,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC5B,MAAM;YACN,GAAG;SACmC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,aAAqB,EAAE,OAAY,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,GAAG,EAAE;QACvF,IAAI,MAAgB,CAAC;QACrB,IAAI,QAAQ,CAAC;QACb,IAAI,OAAO,YAAY,OAAO,EAAE,CAAC;YAC/B,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,gBAAgB,EAAE,GAAG,MAAM,OAAO,CAAC;YACxD,QAAQ,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,UAAU,GAAG,qBAAqB,EAAE,CAAC;QAC3C,MAAM,cAAc,GAAG,MAAM,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QACtF,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;QAEjF,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,iBAAiB,CACnE,aAAa,EACb,cAAc,EACd,QAAQ,EACR;YACE,QAAQ,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;YAClC,cAAc,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM;YACnC,GAAG,OAAO;SACX,CACF,CAAC;QAEF,MAAM,QAAQ,CACZ,MAAM,EACN,IAAI,WAAW,CAAC,EAAE,aAAa,EAAE,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,aAAa;QAClE,WAAW,CACZ,CAAC;QAEF,MAAM,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAEjD,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC;QAC/B,MAAM,GAAG,GAAG,WAAW,aAAa,IAAI,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC;QAE7E,OAAO;YACL,GAAG,EAAE,cAAc;YACnB,aAAa;YACb,UAAU,EAAE,IAAI;YAChB,QAAQ;YACR,IAAI,EAAE,MAAM;YACZ,IAAI;YACJ,GAAG;SACc,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,aAAqB,EACrB,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAO,EACnD,EAAE,OAAO,EAAE;QAEX,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAEpE,MAAM,UAAU,GAAG,qBAAqB,EAAE,CAAC;QAC3C,MAAM,cAAc,GAAG,MAAM,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAEtF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QAC7F,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAE5E,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,iBAAiB,CACnE,aAAa,EACb,cAAc,EACd,QAAQ,EACR;YACE,QAAQ,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;SACnC,CACF,CAAC;QACF,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAA2B,EAAE,IAAI,WAAW,EAAE,EAAE,WAAW,CAAC,CAAC;QACrF,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC;QAC/B,MAAM,GAAG,GAAG,WAAW,aAAa,IAAI,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC;QAE7E,OAAO;YACL,GAAG,EAAE,MAAM,IAAI,cAAc;YAC7B,aAAa;YACb,UAAU,EAAE,IAAI;YAChB,QAAQ;YACR,IAAI,EAAE,MAAM;YACZ,IAAI;YACJ,GAAG;SACc,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,IAAI,EAAE,EAAE,OAAO,EAAO;QAC/C,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACzF,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,OAAO,EAAO;QACvC,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAC9F,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,YAAY,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC"}
|
package/lib/files/minio/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { FileAdapter, FileDirector, buildHashedFilename, resolveExpirationDate, } from '@unchainedshop/file-upload';
|
|
3
|
-
import
|
|
3
|
+
import mime from 'mime/lite';
|
|
4
4
|
import { Client } from 'minio';
|
|
5
5
|
import { AssumeRoleProvider } from 'minio/dist/esm/AssumeRoleProvider.mjs';
|
|
6
6
|
import { expiryOffsetInMs } from '@unchainedshop/file-upload/lib/put-expiration.js';
|
|
@@ -87,7 +87,7 @@ export const MinioAdapter = {
|
|
|
87
87
|
directoryName,
|
|
88
88
|
expiryDate,
|
|
89
89
|
fileName,
|
|
90
|
-
type:
|
|
90
|
+
type: mime.getType(fileName),
|
|
91
91
|
putURL: url,
|
|
92
92
|
url: generateMinioUrl(directoryName, _id),
|
|
93
93
|
};
|
|
@@ -115,7 +115,7 @@ export const MinioAdapter = {
|
|
|
115
115
|
stream = bufferToStream(Buffer.from(rawFile.buffer, 'base64'));
|
|
116
116
|
}
|
|
117
117
|
const _id = await buildHashedFilename(directoryName, fileName, new Date());
|
|
118
|
-
const type =
|
|
118
|
+
const type = mime.getType(fileName) || (await Promise.resolve(rawFile)).mimetype;
|
|
119
119
|
const metaData = {
|
|
120
120
|
'Content-Type': type,
|
|
121
121
|
};
|
|
@@ -139,7 +139,7 @@ export const MinioAdapter = {
|
|
|
139
139
|
const hashedFilename = await buildHashedFilename(directoryName, fileName, new Date());
|
|
140
140
|
const url = new URL(fileLink);
|
|
141
141
|
const response = await fetch(url, { headers });
|
|
142
|
-
const type =
|
|
142
|
+
const type = mime.getType(fileName) || response.headers['content-type'];
|
|
143
143
|
const readable = Readable.fromWeb(response.body);
|
|
144
144
|
const metaData = {
|
|
145
145
|
'Content-Type': type,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/files/minio/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EACL,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,qBAAqB,GAEtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/files/minio/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery-swiss-tax.d.ts","sourceRoot":"","sources":["../../src/pricing/delivery-swiss-tax.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,uBAAuB,EAGxB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"delivery-swiss-tax.d.ts","sourceRoot":"","sources":["../../src/pricing/delivery-swiss-tax.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,uBAAuB,EAGxB,MAAM,qBAAqB,CAAC;AAK7B,eAAO,MAAM,gBAAgB,EAAE,uBAiE9B,CAAC"}
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
import { DeliveryPricingRowCategory, DeliveryPricingAdapter, DeliveryPricingDirector, } from '@unchainedshop/core';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
const taxCategoryFromProvider = provider?.configuration?.find(({ key }) => {
|
|
5
|
-
if (key === 'swiss-tax-category')
|
|
6
|
-
return true;
|
|
7
|
-
return null;
|
|
8
|
-
})?.value;
|
|
9
|
-
const taxCategory = taxCategoryFromProvider
|
|
10
|
-
? SwissTaxCategories[taxCategoryFromProvider] || SwissTaxCategories.DEFAULT
|
|
11
|
-
: SwissTaxCategories.DEFAULT;
|
|
12
|
-
return taxCategory.rate(order?.ordered);
|
|
13
|
-
};
|
|
2
|
+
import { resolveTaxCategoryFromDeliveryProvider, SwissTaxCategories } from './tax/ch.js';
|
|
3
|
+
import isDeliveryAddressInCountry from './utils/isDeliveryAddressInCountry.js';
|
|
14
4
|
export const DeliverySwissTax = {
|
|
15
5
|
...DeliveryPricingAdapter,
|
|
16
6
|
key: 'shop.unchained.pricing.delivery-swiss-tax',
|
|
@@ -22,11 +12,11 @@ export const DeliverySwissTax = {
|
|
|
22
12
|
return false;
|
|
23
13
|
if (!context.orderDelivery)
|
|
24
14
|
return false;
|
|
25
|
-
return
|
|
15
|
+
return isDeliveryAddressInCountry({
|
|
26
16
|
order: context.order,
|
|
27
17
|
orderDelivery: context.orderDelivery,
|
|
28
18
|
countryCode: context.countryCode,
|
|
29
|
-
});
|
|
19
|
+
}, ['CH', 'LI']);
|
|
30
20
|
},
|
|
31
21
|
actions: (params) => {
|
|
32
22
|
const pricingAdapter = DeliveryPricingAdapter.actions(params);
|
|
@@ -34,7 +24,8 @@ export const DeliverySwissTax = {
|
|
|
34
24
|
return {
|
|
35
25
|
...pricingAdapter,
|
|
36
26
|
calculate: async () => {
|
|
37
|
-
const
|
|
27
|
+
const taxCategory = resolveTaxCategoryFromDeliveryProvider(context.provider) || SwissTaxCategories.DEFAULT;
|
|
28
|
+
const taxRate = taxCategory.rate(context.order?.ordered);
|
|
38
29
|
DeliveryPricingAdapter.log(`DeliverySwissTax -> Tax Multiplicator: ${taxRate}`);
|
|
39
30
|
params.calculationSheet.filterBy({ isTaxable: true }).forEach(({ isNetPrice, ...row }) => {
|
|
40
31
|
if (!isNetPrice) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery-swiss-tax.js","sourceRoot":"","sources":["../../src/pricing/delivery-swiss-tax.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAE1B,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"delivery-swiss-tax.js","sourceRoot":"","sources":["../../src/pricing/delivery-swiss-tax.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const getTaxRate: (context: ProductPricingAdapterContext) => number;
|
|
1
|
+
import { IProductPricingAdapter } from '@unchainedshop/core';
|
|
3
2
|
export declare const ProductSwissTax: IProductPricingAdapter;
|
|
4
3
|
//# sourceMappingURL=product-swiss-tax.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-swiss-tax.d.ts","sourceRoot":"","sources":["../../src/pricing/product-swiss-tax.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,
|
|
1
|
+
{"version":3,"file":"product-swiss-tax.d.ts","sourceRoot":"","sources":["../../src/pricing/product-swiss-tax.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,sBAAsB,EAEvB,MAAM,qBAAqB,CAAC;AAS7B,eAAO,MAAM,eAAe,EAAE,sBAqF7B,CAAC"}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { ProductPricingDirector, ProductPricingAdapter, ProductPricingRowCategory, } from '@unchainedshop/core';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
const { product, order } = context;
|
|
5
|
-
const productSpecialTaxTag = product.tags?.find((tag) => tag?.trim().toLowerCase().startsWith('swiss-tax-category:'));
|
|
6
|
-
const taxCategory = Object.values(SwissTaxCategories).find((t) => `swiss-tax-category:${t.value}` === productSpecialTaxTag?.trim().toLowerCase()) || SwissTaxCategories.DEFAULT;
|
|
7
|
-
return taxCategory.rate(order?.ordered);
|
|
8
|
-
};
|
|
2
|
+
import { resolveTaxCategoryFromDeliveryProvider, resolveTaxCategoryFromProduct, SwissTaxCategories, } from './tax/ch.js';
|
|
3
|
+
import isDeliveryAddressInCountry from './utils/isDeliveryAddressInCountry.js';
|
|
9
4
|
export const ProductSwissTax = {
|
|
10
5
|
...ProductPricingAdapter,
|
|
11
6
|
key: 'shop.unchained.pricing.product-swiss-tax',
|
|
@@ -21,17 +16,32 @@ export const ProductSwissTax = {
|
|
|
21
16
|
return {
|
|
22
17
|
...pricingAdapter,
|
|
23
18
|
calculate: async () => {
|
|
24
|
-
|
|
19
|
+
const orderDelivery = context.order?.deliveryId
|
|
20
|
+
? await context.modules.orders.deliveries.findDelivery({
|
|
21
|
+
orderDeliveryId: context.order?.deliveryId,
|
|
22
|
+
})
|
|
23
|
+
: null;
|
|
24
|
+
if (!isDeliveryAddressInCountry({
|
|
25
25
|
...context,
|
|
26
|
-
orderDelivery
|
|
27
|
-
|
|
28
|
-
orderDeliveryId: context.order?.deliveryId,
|
|
29
|
-
})
|
|
30
|
-
: null,
|
|
31
|
-
})) {
|
|
26
|
+
orderDelivery,
|
|
27
|
+
}, ['CH', 'LI'])) {
|
|
32
28
|
return pricingAdapter.calculate();
|
|
33
29
|
}
|
|
34
|
-
|
|
30
|
+
let taxCategory = resolveTaxCategoryFromProduct(context.product);
|
|
31
|
+
if (!taxCategory) {
|
|
32
|
+
// No special tax category found, use default from delivery provider
|
|
33
|
+
const provider = orderDelivery?.deliveryProviderId
|
|
34
|
+
? await context.modules.delivery.findProvider({
|
|
35
|
+
deliveryProviderId: orderDelivery?.deliveryProviderId,
|
|
36
|
+
})
|
|
37
|
+
: null;
|
|
38
|
+
if (provider)
|
|
39
|
+
taxCategory = resolveTaxCategoryFromDeliveryProvider(provider);
|
|
40
|
+
}
|
|
41
|
+
// If still no tax category found, use default
|
|
42
|
+
if (!taxCategory)
|
|
43
|
+
taxCategory = SwissTaxCategories.DEFAULT;
|
|
44
|
+
const taxRate = taxCategory.rate(context.order?.ordered);
|
|
35
45
|
ProductPricingAdapter.log(`ProductSwissTax -> Tax Multiplicator: ${taxRate}`);
|
|
36
46
|
params.calculationSheet.filterBy({ isTaxable: true }).forEach(({ isNetPrice, ...row }) => {
|
|
37
47
|
if (!isNetPrice) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-swiss-tax.js","sourceRoot":"","sources":["../../src/pricing/product-swiss-tax.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"product-swiss-tax.js","sourceRoot":"","sources":["../../src/pricing/product-swiss-tax.ts"],"names":[],"mappings":"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"}
|
package/lib/pricing/tax/ch.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { DeliveryProvider } from '@unchainedshop/core-delivery';
|
|
2
|
+
import { Product } from '@unchainedshop/core-products';
|
|
3
|
+
export interface SwissTaxCategoryResolver {
|
|
3
4
|
value: string;
|
|
4
5
|
rate: (referenceDate?: Date) => number;
|
|
5
|
-
}
|
|
6
|
-
export declare const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
countryCode?: string | null;
|
|
10
|
-
}) => boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const SwissTaxCategories: Record<string, SwissTaxCategoryResolver>;
|
|
8
|
+
export declare const resolveTaxCategoryFromDeliveryProvider: (provider: DeliveryProvider) => SwissTaxCategoryResolver | null;
|
|
9
|
+
export declare const resolveTaxCategoryFromProduct: (product: Product) => SwissTaxCategoryResolver | null;
|
|
11
10
|
//# sourceMappingURL=ch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ch.d.ts","sourceRoot":"","sources":["../../../src/pricing/tax/ch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ch.d.ts","sourceRoot":"","sources":["../../../src/pricing/tax/ch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAMvD,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,IAAI,KAAK,MAAM,CAAC;CACxC;AAED,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CA4BvE,CAAC;AAEF,eAAO,MAAM,sCAAsC,GACjD,UAAU,gBAAgB,KACzB,wBAAwB,GAAG,IAU7B,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAI,SAAS,OAAO,KAAG,wBAAwB,GAAG,IAQ3F,CAAC"}
|
package/lib/pricing/tax/ch.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const startOf2024 = new Date('2024-01-01T00:00:00.000+0100');
|
|
2
|
-
// https://www.estv.admin.ch/estv/en/home/value-added-tax/vat-rates-switzerland.html
|
|
3
2
|
export const SwissTaxCategories = {
|
|
4
3
|
DEFAULT: {
|
|
5
4
|
value: 'default',
|
|
@@ -29,14 +28,20 @@ export const SwissTaxCategories = {
|
|
|
29
28
|
},
|
|
30
29
|
},
|
|
31
30
|
};
|
|
32
|
-
export const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
export const resolveTaxCategoryFromDeliveryProvider = (provider) => {
|
|
32
|
+
const taxCategoryFromProvider = provider?.configuration
|
|
33
|
+
?.find(({ key }) => {
|
|
34
|
+
if (key === 'swiss-tax-category')
|
|
35
|
+
return true;
|
|
36
|
+
return null;
|
|
37
|
+
})
|
|
38
|
+
?.value?.toUpperCase();
|
|
39
|
+
const taxCategory = taxCategoryFromProvider ? SwissTaxCategories[taxCategoryFromProvider] : null;
|
|
40
|
+
return taxCategory;
|
|
41
|
+
};
|
|
42
|
+
export const resolveTaxCategoryFromProduct = (product) => {
|
|
43
|
+
const productSpecialTaxTag = product.tags?.find((tag) => tag?.trim().toLowerCase().startsWith('swiss-tax-category:'));
|
|
44
|
+
const taxCategory = Object.values(SwissTaxCategories).find((t) => `swiss-tax-category:${t.value}` === productSpecialTaxTag?.trim().toLowerCase());
|
|
45
|
+
return taxCategory || null;
|
|
41
46
|
};
|
|
42
47
|
//# sourceMappingURL=ch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ch.js","sourceRoot":"","sources":["../../../src/pricing/tax/ch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ch.js","sourceRoot":"","sources":["../../../src/pricing/tax/ch.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,8BAA8B,CAAC,CAAC;AAS7D,MAAM,CAAC,MAAM,kBAAkB,GAA6C;IAC1E,OAAO,EAAE;QACP,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,CAAC,aAAa,GAAG,IAAI,IAAI,EAAE,EAAE,EAAE;YACnC,IAAI,aAAa,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;gBACpD,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KACF;IACD,OAAO,EAAE;QACP,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,CAAC,aAAa,GAAG,IAAI,IAAI,EAAE,EAAE,EAAE;YACnC,IAAI,aAAa,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;gBACpD,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KACF;IACD,OAAO,EAAE;QACP,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,CAAC,aAAa,GAAG,IAAI,IAAI,EAAE,EAAE,EAAE;YACnC,IAAI,aAAa,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;gBACpD,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KACF;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,sCAAsC,GAAG,CACpD,QAA0B,EACO,EAAE;IACnC,MAAM,uBAAuB,GAAG,QAAQ,EAAE,aAAa;QACrD,EAAE,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;QACjB,IAAI,GAAG,KAAK,oBAAoB;YAAE,OAAO,IAAI,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;QACF,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAEzB,MAAM,WAAW,GAAG,uBAAuB,CAAC,CAAC,CAAC,kBAAkB,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjG,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,OAAgB,EAAmC,EAAE;IACjG,MAAM,oBAAoB,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CACtD,GAAG,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAC5D,CAAC;IACF,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CACxD,CAAC,CAAC,EAAE,EAAE,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,KAAK,oBAAoB,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CACtF,CAAC;IACF,OAAO,WAAW,IAAI,IAAI,CAAC;AAC7B,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Order, OrderDelivery } from '@unchainedshop/core-orders';
|
|
2
|
+
export default function isDeliveryAddressInCountry({ orderDelivery, order, countryCode: forceCountryCode, }: {
|
|
3
|
+
orderDelivery?: OrderDelivery | null;
|
|
4
|
+
order?: Order | null;
|
|
5
|
+
countryCode?: string | null;
|
|
6
|
+
}, allowedCountryCodes: string[]): boolean;
|
|
7
|
+
//# sourceMappingURL=isDeliveryAddressInCountry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isDeliveryAddressInCountry.d.ts","sourceRoot":"","sources":["../../../src/pricing/utils/isDeliveryAddressInCountry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAElE,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAChD,EACE,aAAa,EACb,KAAK,EACL,WAAW,EAAE,gBAAuB,GACrC,EAAE;IACD,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,EACD,mBAAmB,EAAE,MAAM,EAAE,WAa9B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default function isDeliveryAddressInCountry({ orderDelivery, order, countryCode: forceCountryCode = null, }, allowedCountryCodes) {
|
|
2
|
+
let countryCode = forceCountryCode?.toUpperCase().trim() || order?.countryCode;
|
|
3
|
+
if (orderDelivery || order) {
|
|
4
|
+
const address = orderDelivery?.context?.address || order?.billingAddress;
|
|
5
|
+
if (address?.countryCode > '') {
|
|
6
|
+
countryCode = address.countryCode?.toUpperCase().trim();
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
if (!countryCode)
|
|
10
|
+
return false;
|
|
11
|
+
return allowedCountryCodes.includes(countryCode);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=isDeliveryAddressInCountry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isDeliveryAddressInCountry.js","sourceRoot":"","sources":["../../../src/pricing/utils/isDeliveryAddressInCountry.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAChD,EACE,aAAa,EACb,KAAK,EACL,WAAW,EAAE,gBAAgB,GAAG,IAAI,GAKrC,EACD,mBAA6B;IAE7B,IAAI,WAAW,GAAG,gBAAgB,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,EAAE,WAAW,CAAC;IAE/E,IAAI,aAAa,IAAI,KAAK,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,aAAa,EAAE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,cAAc,CAAC;QACzE,IAAI,OAAO,EAAE,WAAW,GAAG,EAAE,EAAE,CAAC;YAC9B,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IAC/B,OAAO,mBAAmB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACnD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/plugins",
|
|
3
|
-
"version": "4.0.0-rc.
|
|
3
|
+
"version": "4.0.0-rc.19",
|
|
4
4
|
"main": "lib/plugins-index.js",
|
|
5
5
|
"types": "lib/plugins-index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -34,18 +34,18 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@unchainedshop/api": "^4.0.0-rc.
|
|
38
|
-
"@unchainedshop/core-delivery": "^4.0.0-rc.
|
|
39
|
-
"@unchainedshop/core-enrollments": "^4.0.0-rc.
|
|
40
|
-
"@unchainedshop/core-orders": "^4.0.0-rc.
|
|
41
|
-
"@unchainedshop/core-payment": "^4.0.0-rc.
|
|
42
|
-
"@unchainedshop/core-products": "^4.0.0-rc.
|
|
43
|
-
"@unchainedshop/core-warehousing": "^4.0.0-rc.
|
|
44
|
-
"@unchainedshop/core-worker": "^4.0.0-rc.
|
|
45
|
-
"@unchainedshop/events": "^4.0.0-rc.
|
|
46
|
-
"@unchainedshop/file-upload": "^4.0.0-rc.
|
|
47
|
-
"@unchainedshop/logger": "^4.0.0-rc.
|
|
48
|
-
"@unchainedshop/utils": "^4.0.0-rc.
|
|
37
|
+
"@unchainedshop/api": "^4.0.0-rc.19",
|
|
38
|
+
"@unchainedshop/core-delivery": "^4.0.0-rc.19",
|
|
39
|
+
"@unchainedshop/core-enrollments": "^4.0.0-rc.19",
|
|
40
|
+
"@unchainedshop/core-orders": "^4.0.0-rc.19",
|
|
41
|
+
"@unchainedshop/core-payment": "^4.0.0-rc.19",
|
|
42
|
+
"@unchainedshop/core-products": "^4.0.0-rc.19",
|
|
43
|
+
"@unchainedshop/core-warehousing": "^4.0.0-rc.19",
|
|
44
|
+
"@unchainedshop/core-worker": "^4.0.0-rc.19",
|
|
45
|
+
"@unchainedshop/events": "^4.0.0-rc.19",
|
|
46
|
+
"@unchainedshop/file-upload": "^4.0.0-rc.19",
|
|
47
|
+
"@unchainedshop/logger": "^4.0.0-rc.19",
|
|
48
|
+
"@unchainedshop/utils": "^4.0.0-rc.19"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"@aws-sdk/client-eventbridge": ">= 3.714 < 4",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"@redis/client": ">= 1 < 6",
|
|
55
55
|
"@scure/bip32": ">= 2",
|
|
56
56
|
"@scure/btc-signer": ">= 2",
|
|
57
|
+
"mime": ">= 4 < 5",
|
|
57
58
|
"expiry-map": "2.x",
|
|
58
59
|
"express": ">= 5 < 6",
|
|
59
60
|
"fastify": ">= 5.2 < 6",
|
|
60
|
-
"mime-types": ">= 2 < 4",
|
|
61
61
|
"minio": "8.x",
|
|
62
62
|
"nodemailer": ">= 6.9 < 8",
|
|
63
63
|
"open": "10.x",
|
|
@@ -94,9 +94,6 @@
|
|
|
94
94
|
"fastify": {
|
|
95
95
|
"optional": true
|
|
96
96
|
},
|
|
97
|
-
"mime-types": {
|
|
98
|
-
"optional": true
|
|
99
|
-
},
|
|
100
97
|
"minio": {
|
|
101
98
|
"optional": true
|
|
102
99
|
},
|
|
@@ -131,7 +128,6 @@
|
|
|
131
128
|
"expiry-map": "^2.0.0",
|
|
132
129
|
"express": "^5.1.0",
|
|
133
130
|
"fastify": "^5.4.0",
|
|
134
|
-
"mime-types": "^3.0.1",
|
|
135
131
|
"minio": "^8.0.5",
|
|
136
132
|
"nodemailer": "^7.0.5",
|
|
137
133
|
"open": "^10.1.2",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Readable, PassThrough } from 'node:stream';
|
|
2
2
|
import { finished, pipeline } from 'node:stream/promises';
|
|
3
|
-
import
|
|
3
|
+
import mime from 'mime/lite';
|
|
4
4
|
import {
|
|
5
5
|
FileAdapter,
|
|
6
6
|
FileDirector,
|
|
@@ -63,7 +63,7 @@ export const GridFSAdapter: IFileAdapter<
|
|
|
63
63
|
directoryName,
|
|
64
64
|
expiryDate,
|
|
65
65
|
fileName,
|
|
66
|
-
type:
|
|
66
|
+
type: mime.getType(fileName),
|
|
67
67
|
putURL,
|
|
68
68
|
url,
|
|
69
69
|
} as UploadFileData & { putURL: string };
|
|
@@ -83,7 +83,7 @@ export const GridFSAdapter: IFileAdapter<
|
|
|
83
83
|
|
|
84
84
|
const expiryDate = resolveExpirationDate();
|
|
85
85
|
const hashedFilename = await buildHashedFilename(directoryName, fileName, expiryDate);
|
|
86
|
-
const type =
|
|
86
|
+
const type = mime.getType(fileName) || (await Promise.resolve(rawFile)).mimetype;
|
|
87
87
|
|
|
88
88
|
const writeStream = await modules.gridfsFileUploads.createWriteStream(
|
|
89
89
|
directoryName,
|
|
@@ -131,7 +131,7 @@ export const GridFSAdapter: IFileAdapter<
|
|
|
131
131
|
|
|
132
132
|
const response = await fetch(href, { headers });
|
|
133
133
|
if (!response.ok) throw new Error(`Unexpected response for ${href}: ${response.statusText}`);
|
|
134
|
-
const type =
|
|
134
|
+
const type = mime.getType(fileName) || response.headers.get('content-type');
|
|
135
135
|
|
|
136
136
|
const writeStream = await modules.gridfsFileUploads.createWriteStream(
|
|
137
137
|
directoryName,
|
package/src/files/minio/index.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
resolveExpirationDate,
|
|
9
9
|
IFileAdapter,
|
|
10
10
|
} from '@unchainedshop/file-upload';
|
|
11
|
-
import
|
|
11
|
+
import mime from 'mime/lite';
|
|
12
12
|
import { Client } from 'minio';
|
|
13
13
|
import { AssumeRoleProvider } from 'minio/dist/esm/AssumeRoleProvider.mjs';
|
|
14
14
|
import { expiryOffsetInMs } from '@unchainedshop/file-upload/lib/put-expiration.js';
|
|
@@ -126,7 +126,7 @@ export const MinioAdapter: IFileAdapter = {
|
|
|
126
126
|
directoryName,
|
|
127
127
|
expiryDate,
|
|
128
128
|
fileName,
|
|
129
|
-
type:
|
|
129
|
+
type: mime.getType(fileName),
|
|
130
130
|
putURL: url,
|
|
131
131
|
url: generateMinioUrl(directoryName, _id),
|
|
132
132
|
} as UploadFileData & { putURL: string };
|
|
@@ -157,7 +157,7 @@ export const MinioAdapter: IFileAdapter = {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
const _id = await buildHashedFilename(directoryName, fileName, new Date());
|
|
160
|
-
const type =
|
|
160
|
+
const type = mime.getType(fileName) || (await Promise.resolve(rawFile)).mimetype;
|
|
161
161
|
|
|
162
162
|
const metaData = {
|
|
163
163
|
'Content-Type': type,
|
|
@@ -193,7 +193,7 @@ export const MinioAdapter: IFileAdapter = {
|
|
|
193
193
|
|
|
194
194
|
const url = new URL(fileLink);
|
|
195
195
|
const response = await fetch(url, { headers });
|
|
196
|
-
const type =
|
|
196
|
+
const type = mime.getType(fileName) || response.headers['content-type'];
|
|
197
197
|
const readable = Readable.fromWeb(response.body as ReadableStream<Uint8Array<ArrayBufferLike>>);
|
|
198
198
|
const metaData = {
|
|
199
199
|
'Content-Type': type,
|
|
@@ -5,21 +5,8 @@ import {
|
|
|
5
5
|
DeliveryPricingDirector,
|
|
6
6
|
} from '@unchainedshop/core';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import { isDeliveryAddressInSwitzerland, SwissTaxCategories } from './tax/ch.js';
|
|
11
|
-
|
|
12
|
-
const getTaxRate = ({ order, provider }: { order?: Order; provider?: DeliveryProvider }) => {
|
|
13
|
-
const taxCategoryFromProvider = provider?.configuration?.find(({ key }) => {
|
|
14
|
-
if (key === 'swiss-tax-category') return true;
|
|
15
|
-
return null;
|
|
16
|
-
})?.value;
|
|
17
|
-
|
|
18
|
-
const taxCategory = taxCategoryFromProvider
|
|
19
|
-
? SwissTaxCategories[taxCategoryFromProvider] || SwissTaxCategories.DEFAULT
|
|
20
|
-
: SwissTaxCategories.DEFAULT;
|
|
21
|
-
return taxCategory.rate(order?.ordered);
|
|
22
|
-
};
|
|
8
|
+
import { resolveTaxCategoryFromDeliveryProvider, SwissTaxCategories } from './tax/ch.js';
|
|
9
|
+
import isDeliveryAddressInCountry from './utils/isDeliveryAddressInCountry.js';
|
|
23
10
|
|
|
24
11
|
export const DeliverySwissTax: IDeliveryPricingAdapter = {
|
|
25
12
|
...DeliveryPricingAdapter,
|
|
@@ -32,11 +19,14 @@ export const DeliverySwissTax: IDeliveryPricingAdapter = {
|
|
|
32
19
|
isActivatedFor: (context) => {
|
|
33
20
|
if (!context.order) return false;
|
|
34
21
|
if (!context.orderDelivery) return false;
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
22
|
+
return isDeliveryAddressInCountry(
|
|
23
|
+
{
|
|
24
|
+
order: context.order,
|
|
25
|
+
orderDelivery: context.orderDelivery,
|
|
26
|
+
countryCode: context.countryCode,
|
|
27
|
+
},
|
|
28
|
+
['CH', 'LI'],
|
|
29
|
+
);
|
|
40
30
|
},
|
|
41
31
|
|
|
42
32
|
actions: (params) => {
|
|
@@ -47,7 +37,10 @@ export const DeliverySwissTax: IDeliveryPricingAdapter = {
|
|
|
47
37
|
...pricingAdapter,
|
|
48
38
|
|
|
49
39
|
calculate: async () => {
|
|
50
|
-
const
|
|
40
|
+
const taxCategory =
|
|
41
|
+
resolveTaxCategoryFromDeliveryProvider(context.provider) || SwissTaxCategories.DEFAULT;
|
|
42
|
+
const taxRate = taxCategory.rate(context.order?.ordered);
|
|
43
|
+
|
|
51
44
|
DeliveryPricingAdapter.log(`DeliverySwissTax -> Tax Multiplicator: ${taxRate}`);
|
|
52
45
|
params.calculationSheet.filterBy({ isTaxable: true }).forEach(({ isNetPrice, ...row }) => {
|
|
53
46
|
if (!isNetPrice) {
|
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ProductPricingDirector,
|
|
3
3
|
ProductPricingAdapter,
|
|
4
|
-
ProductPricingAdapterContext,
|
|
5
4
|
IProductPricingAdapter,
|
|
6
5
|
ProductPricingRowCategory,
|
|
7
6
|
} from '@unchainedshop/core';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
);
|
|
16
|
-
const taxCategory =
|
|
17
|
-
Object.values(SwissTaxCategories).find(
|
|
18
|
-
(t) => `swiss-tax-category:${t.value}` === productSpecialTaxTag?.trim().toLowerCase(),
|
|
19
|
-
) || SwissTaxCategories.DEFAULT;
|
|
20
|
-
|
|
21
|
-
return taxCategory.rate(order?.ordered);
|
|
22
|
-
};
|
|
7
|
+
import {
|
|
8
|
+
resolveTaxCategoryFromDeliveryProvider,
|
|
9
|
+
resolveTaxCategoryFromProduct,
|
|
10
|
+
SwissTaxCategories,
|
|
11
|
+
SwissTaxCategoryResolver,
|
|
12
|
+
} from './tax/ch.js';
|
|
13
|
+
import isDeliveryAddressInCountry from './utils/isDeliveryAddressInCountry.js';
|
|
23
14
|
|
|
24
15
|
export const ProductSwissTax: IProductPricingAdapter = {
|
|
25
16
|
...ProductPricingAdapter,
|
|
@@ -41,19 +32,40 @@ export const ProductSwissTax: IProductPricingAdapter = {
|
|
|
41
32
|
...pricingAdapter,
|
|
42
33
|
|
|
43
34
|
calculate: async () => {
|
|
35
|
+
const orderDelivery = context.order?.deliveryId
|
|
36
|
+
? await context.modules.orders.deliveries.findDelivery({
|
|
37
|
+
orderDeliveryId: context.order?.deliveryId,
|
|
38
|
+
})
|
|
39
|
+
: null;
|
|
44
40
|
if (
|
|
45
|
-
!
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
})
|
|
41
|
+
!isDeliveryAddressInCountry(
|
|
42
|
+
{
|
|
43
|
+
...context,
|
|
44
|
+
orderDelivery,
|
|
45
|
+
},
|
|
46
|
+
['CH', 'LI'],
|
|
47
|
+
)
|
|
53
48
|
) {
|
|
54
49
|
return pricingAdapter.calculate();
|
|
55
50
|
}
|
|
56
|
-
|
|
51
|
+
|
|
52
|
+
let taxCategory: SwissTaxCategoryResolver | null = resolveTaxCategoryFromProduct(
|
|
53
|
+
context.product,
|
|
54
|
+
);
|
|
55
|
+
if (!taxCategory) {
|
|
56
|
+
// No special tax category found, use default from delivery provider
|
|
57
|
+
const provider = orderDelivery?.deliveryProviderId
|
|
58
|
+
? await context.modules.delivery.findProvider({
|
|
59
|
+
deliveryProviderId: orderDelivery?.deliveryProviderId,
|
|
60
|
+
})
|
|
61
|
+
: null;
|
|
62
|
+
if (provider) taxCategory = resolveTaxCategoryFromDeliveryProvider(provider);
|
|
63
|
+
}
|
|
64
|
+
// If still no tax category found, use default
|
|
65
|
+
if (!taxCategory) taxCategory = SwissTaxCategories.DEFAULT;
|
|
66
|
+
|
|
67
|
+
const taxRate = taxCategory.rate(context.order?.ordered);
|
|
68
|
+
|
|
57
69
|
ProductPricingAdapter.log(`ProductSwissTax -> Tax Multiplicator: ${taxRate}`);
|
|
58
70
|
params.calculationSheet.filterBy({ isTaxable: true }).forEach(({ isNetPrice, ...row }) => {
|
|
59
71
|
if (!isNetPrice) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it } from 'node:test';
|
|
2
2
|
import assert from 'node:assert';
|
|
3
|
-
import { SwissTaxCategories
|
|
3
|
+
import { SwissTaxCategories } from './ch';
|
|
4
4
|
|
|
5
5
|
describe('SwissTaxCategories', () => {
|
|
6
6
|
it('DEFAULT rate', () => {
|
|
@@ -18,88 +18,3 @@ describe('SwissTaxCategories', () => {
|
|
|
18
18
|
assert.strictEqual(SwissTaxCategories.SPECIAL.rate(new Date(2024, 1, 1)), 0.038);
|
|
19
19
|
});
|
|
20
20
|
});
|
|
21
|
-
|
|
22
|
-
describe('isDeliveryAddressInSwitzerland', () => {
|
|
23
|
-
const context = {
|
|
24
|
-
modules: {
|
|
25
|
-
orders: {
|
|
26
|
-
deliveries: {
|
|
27
|
-
findDelivery: async ({ orderDeliveryId }: any) => {
|
|
28
|
-
if (orderDeliveryId === 'CH' || orderDeliveryId === 'LI')
|
|
29
|
-
return { context: { address: { countryCode: 'CH' } } };
|
|
30
|
-
if (orderDeliveryId === null) return { context: { address: null } };
|
|
31
|
-
return { context: { address: { countryCode: 'RT' } } };
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
order: {
|
|
37
|
-
deliveryId: 'CH',
|
|
38
|
-
billingAddress: { countryCode: 'LI' },
|
|
39
|
-
},
|
|
40
|
-
countryCode: 'CH',
|
|
41
|
-
};
|
|
42
|
-
it('Should return true when passed country code CH', async () => {
|
|
43
|
-
assert.strictEqual(
|
|
44
|
-
await isDeliveryAddressInSwitzerland({ ...context, countryCode: 'ch', order: null } as any),
|
|
45
|
-
true,
|
|
46
|
-
);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('Should return true when passed country code LI', async () => {
|
|
50
|
-
assert.strictEqual(
|
|
51
|
-
await isDeliveryAddressInSwitzerland({ ...context, countryCode: 'LI', order: null } as any),
|
|
52
|
-
true,
|
|
53
|
-
);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('Should return false when country is neither CH nor LI and order is null', async () => {
|
|
57
|
-
assert.strictEqual(
|
|
58
|
-
await isDeliveryAddressInSwitzerland({ ...context, countryCode: 'ET', order: null } as any),
|
|
59
|
-
false,
|
|
60
|
-
);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('Order should take precedence over country parameter', async () => {
|
|
64
|
-
// not CH or LI order so returns false
|
|
65
|
-
assert.strictEqual(
|
|
66
|
-
await isDeliveryAddressInSwitzerland({
|
|
67
|
-
...context,
|
|
68
|
-
countryCode: 'CH',
|
|
69
|
-
order: {
|
|
70
|
-
deliveryId: 'ET',
|
|
71
|
-
billingAddress: { countryCode: 'ET' },
|
|
72
|
-
},
|
|
73
|
-
} as any),
|
|
74
|
-
false,
|
|
75
|
-
);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('If order is not from CH and LI but billingAddress is, it should take precedence over country ', async () => {
|
|
79
|
-
assert.strictEqual(
|
|
80
|
-
await isDeliveryAddressInSwitzerland({
|
|
81
|
-
...context,
|
|
82
|
-
countryCode: 'IT',
|
|
83
|
-
order: {
|
|
84
|
-
deliveryId: null,
|
|
85
|
-
billingAddress: { countryCode: 'CH' },
|
|
86
|
-
},
|
|
87
|
-
} as any),
|
|
88
|
-
true,
|
|
89
|
-
);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('Should return false if billingAddress is neither CH or LI and order does not have address', async () => {
|
|
93
|
-
assert.strictEqual(
|
|
94
|
-
await isDeliveryAddressInSwitzerland({
|
|
95
|
-
...context,
|
|
96
|
-
country: null,
|
|
97
|
-
order: {
|
|
98
|
-
deliveryId: null,
|
|
99
|
-
billingAddress: { countryCode: 'HH' },
|
|
100
|
-
},
|
|
101
|
-
} as any),
|
|
102
|
-
false,
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
});
|
package/src/pricing/tax/ch.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DeliveryProvider } from '@unchainedshop/core-delivery';
|
|
2
|
+
import { Product } from '@unchainedshop/core-products';
|
|
2
3
|
|
|
3
4
|
const startOf2024 = new Date('2024-01-01T00:00:00.000+0100');
|
|
4
5
|
|
|
5
6
|
// https://www.estv.admin.ch/estv/en/home/value-added-tax/vat-rates-switzerland.html
|
|
6
7
|
|
|
7
|
-
export
|
|
8
|
-
string
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
> = {
|
|
8
|
+
export interface SwissTaxCategoryResolver {
|
|
9
|
+
value: string;
|
|
10
|
+
rate: (referenceDate?: Date) => number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const SwissTaxCategories: Record<string, SwissTaxCategoryResolver> = {
|
|
14
14
|
DEFAULT: {
|
|
15
15
|
value: 'default',
|
|
16
16
|
rate: (referenceDate = new Date()) => {
|
|
@@ -40,23 +40,26 @@ export const SwissTaxCategories: Record<
|
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
export const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
let countryCode = forceCountryCode?.toUpperCase().trim() || order?.countryCode;
|
|
43
|
+
export const resolveTaxCategoryFromDeliveryProvider = (
|
|
44
|
+
provider: DeliveryProvider,
|
|
45
|
+
): SwissTaxCategoryResolver | null => {
|
|
46
|
+
const taxCategoryFromProvider = provider?.configuration
|
|
47
|
+
?.find(({ key }) => {
|
|
48
|
+
if (key === 'swiss-tax-category') return true;
|
|
49
|
+
return null;
|
|
50
|
+
})
|
|
51
|
+
?.value?.toUpperCase();
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
countryCode = address.countryCode?.toUpperCase().trim();
|
|
58
|
-
}
|
|
59
|
-
}
|
|
53
|
+
const taxCategory = taxCategoryFromProvider ? SwissTaxCategories[taxCategoryFromProvider] : null;
|
|
54
|
+
return taxCategory;
|
|
55
|
+
};
|
|
60
56
|
|
|
61
|
-
|
|
57
|
+
export const resolveTaxCategoryFromProduct = (product: Product): SwissTaxCategoryResolver | null => {
|
|
58
|
+
const productSpecialTaxTag = product.tags?.find((tag) =>
|
|
59
|
+
tag?.trim().toLowerCase().startsWith('swiss-tax-category:'),
|
|
60
|
+
);
|
|
61
|
+
const taxCategory = Object.values(SwissTaxCategories).find(
|
|
62
|
+
(t) => `swiss-tax-category:${t.value}` === productSpecialTaxTag?.trim().toLowerCase(),
|
|
63
|
+
);
|
|
64
|
+
return taxCategory || null;
|
|
62
65
|
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import isDeliveryAddressInCountry from './isDeliveryAddressInCountry.js';
|
|
4
|
+
|
|
5
|
+
describe('isDeliveryAddressInCountry', () => {
|
|
6
|
+
const context = {
|
|
7
|
+
modules: {
|
|
8
|
+
orders: {
|
|
9
|
+
deliveries: {
|
|
10
|
+
findDelivery: async ({ orderDeliveryId }: any) => {
|
|
11
|
+
if (orderDeliveryId === 'CH' || orderDeliveryId === 'LI')
|
|
12
|
+
return { context: { address: { countryCode: 'CH' } } };
|
|
13
|
+
if (orderDeliveryId === null) return { context: { address: null } };
|
|
14
|
+
return { context: { address: { countryCode: 'RT' } } };
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
order: {
|
|
20
|
+
deliveryId: 'CH',
|
|
21
|
+
billingAddress: { countryCode: 'LI' },
|
|
22
|
+
},
|
|
23
|
+
countryCode: 'CH',
|
|
24
|
+
};
|
|
25
|
+
it('Should return true when passed country code CH', async () => {
|
|
26
|
+
assert.strictEqual(
|
|
27
|
+
await isDeliveryAddressInCountry({ ...context, countryCode: 'ch', order: null } as any, [
|
|
28
|
+
'CH',
|
|
29
|
+
'LI',
|
|
30
|
+
]),
|
|
31
|
+
true,
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('Should return true when passed country code LI', async () => {
|
|
36
|
+
assert.strictEqual(
|
|
37
|
+
await isDeliveryAddressInCountry({ ...context, countryCode: 'LI', order: null } as any, [
|
|
38
|
+
'CH',
|
|
39
|
+
'LI',
|
|
40
|
+
]),
|
|
41
|
+
true,
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('Should return false when country is neither CH nor LI and order is null', async () => {
|
|
46
|
+
assert.strictEqual(
|
|
47
|
+
await isDeliveryAddressInCountry({ ...context, countryCode: 'ET', order: null } as any, [
|
|
48
|
+
'CH',
|
|
49
|
+
'LI',
|
|
50
|
+
]),
|
|
51
|
+
false,
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('Order should take precedence over country parameter', async () => {
|
|
56
|
+
// not CH or LI order so returns false
|
|
57
|
+
assert.strictEqual(
|
|
58
|
+
await isDeliveryAddressInCountry(
|
|
59
|
+
{
|
|
60
|
+
...context,
|
|
61
|
+
countryCode: 'CH',
|
|
62
|
+
order: {
|
|
63
|
+
deliveryId: 'ET',
|
|
64
|
+
billingAddress: { countryCode: 'ET' },
|
|
65
|
+
},
|
|
66
|
+
} as any,
|
|
67
|
+
['CH', 'LI'],
|
|
68
|
+
),
|
|
69
|
+
false,
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('If order is not from CH and LI but billingAddress is, it should take precedence over country ', async () => {
|
|
74
|
+
assert.strictEqual(
|
|
75
|
+
await isDeliveryAddressInCountry(
|
|
76
|
+
{
|
|
77
|
+
...context,
|
|
78
|
+
countryCode: 'IT',
|
|
79
|
+
order: {
|
|
80
|
+
deliveryId: null,
|
|
81
|
+
billingAddress: { countryCode: 'CH' },
|
|
82
|
+
},
|
|
83
|
+
} as any,
|
|
84
|
+
['CH', 'LI'],
|
|
85
|
+
),
|
|
86
|
+
true,
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('Should return false if billingAddress is neither CH or LI and order does not have address', async () => {
|
|
91
|
+
assert.strictEqual(
|
|
92
|
+
await isDeliveryAddressInCountry(
|
|
93
|
+
{
|
|
94
|
+
...context,
|
|
95
|
+
country: null,
|
|
96
|
+
order: {
|
|
97
|
+
deliveryId: null,
|
|
98
|
+
billingAddress: { countryCode: 'HH' },
|
|
99
|
+
},
|
|
100
|
+
} as any,
|
|
101
|
+
['CH', 'LI'],
|
|
102
|
+
),
|
|
103
|
+
false,
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Order, OrderDelivery } from '@unchainedshop/core-orders';
|
|
2
|
+
|
|
3
|
+
export default function isDeliveryAddressInCountry(
|
|
4
|
+
{
|
|
5
|
+
orderDelivery,
|
|
6
|
+
order,
|
|
7
|
+
countryCode: forceCountryCode = null,
|
|
8
|
+
}: {
|
|
9
|
+
orderDelivery?: OrderDelivery | null;
|
|
10
|
+
order?: Order | null;
|
|
11
|
+
countryCode?: string | null;
|
|
12
|
+
},
|
|
13
|
+
allowedCountryCodes: string[],
|
|
14
|
+
) {
|
|
15
|
+
let countryCode = forceCountryCode?.toUpperCase().trim() || order?.countryCode;
|
|
16
|
+
|
|
17
|
+
if (orderDelivery || order) {
|
|
18
|
+
const address = orderDelivery?.context?.address || order?.billingAddress;
|
|
19
|
+
if (address?.countryCode > '') {
|
|
20
|
+
countryCode = address.countryCode?.toUpperCase().trim();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!countryCode) return false;
|
|
25
|
+
return allowedCountryCodes.includes(countryCode);
|
|
26
|
+
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { describe, it } from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
|
|
4
|
-
import { getTaxRate } from './product-swiss-tax.js';
|
|
5
|
-
|
|
6
|
-
describe('ProductSwissTax', () => {
|
|
7
|
-
describe('getTaxRate', () => {
|
|
8
|
-
it('default rate', () => {
|
|
9
|
-
assert.strictEqual(
|
|
10
|
-
getTaxRate({
|
|
11
|
-
product: {} as any,
|
|
12
|
-
order: {} as any,
|
|
13
|
-
} as any),
|
|
14
|
-
0.081,
|
|
15
|
-
);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('reduced rate', () => {
|
|
19
|
-
assert.strictEqual(
|
|
20
|
-
getTaxRate({
|
|
21
|
-
product: {
|
|
22
|
-
tags: ['swiss-tax-category:reduced'],
|
|
23
|
-
},
|
|
24
|
-
order: {},
|
|
25
|
-
} as any),
|
|
26
|
-
0.026,
|
|
27
|
-
);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('special rate', () => {
|
|
31
|
-
assert.strictEqual(
|
|
32
|
-
getTaxRate({
|
|
33
|
-
product: {
|
|
34
|
-
tags: ['swiss-tax-category:special'],
|
|
35
|
-
},
|
|
36
|
-
order: {},
|
|
37
|
-
} as any),
|
|
38
|
-
0.038,
|
|
39
|
-
);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('default rate', () => {
|
|
43
|
-
assert.strictEqual(
|
|
44
|
-
getTaxRate({
|
|
45
|
-
product: {
|
|
46
|
-
tags: ['swiss-tax-category:default'],
|
|
47
|
-
},
|
|
48
|
-
order: {},
|
|
49
|
-
} as any),
|
|
50
|
-
0.081,
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
});
|