@unchainedshop/plugins 5.0.0-alpha.1 → 5.0.0-alpha.3
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/events/aws-eventbridge.d.ts +7 -1
- package/lib/events/aws-eventbridge.js +5 -11
- package/lib/events/redis.d.ts +3 -1
- package/lib/events/redis.js +5 -5
- package/lib/files/gridfs/api.js +1 -1
- package/lib/files/gridfs/handler-express.js +1 -1
- package/lib/filters/local-search/index.js +0 -6
- package/lib/filters/local-search.js +1 -9
- package/lib/payment/cryptopay/db/CryptopayTransactions.d.ts +1 -1
- package/lib/payment/cryptopay/db/CryptopayTransactions.js +8 -3
- package/lib/payment/cryptopay/module.d.ts +5 -5
- package/lib/payment/cryptopay/module.js +2 -2
- package/lib/payment/datatrans-v2/adapter.js +12 -9
- package/lib/payment/datatrans-v2/build3DSCardholder.d.ts +12 -0
- package/lib/payment/datatrans-v2/build3DSCardholder.js +44 -0
- package/lib/payment/paypal-checkout.js +17 -5
- package/lib/payment/payrexx/payrexx.js +4 -4
- package/lib/payment/stripe/stripe.js +1 -1
- package/lib/presets/base.js +4 -0
- package/lib/presets/countries/eu.d.ts +1 -0
- package/lib/presets/countries/eu.js +7 -0
- package/lib/presets/countries/uk.d.ts +1 -0
- package/lib/presets/countries/uk.js +7 -0
- package/lib/presets/countries/us.d.ts +1 -0
- package/lib/presets/countries/us.js +7 -0
- package/lib/pricing/delivery-eu-tax/adapter.d.ts +3 -0
- package/lib/pricing/delivery-eu-tax/adapter.js +55 -0
- package/lib/pricing/delivery-eu-tax/index.d.ts +4 -0
- package/lib/pricing/delivery-eu-tax/index.js +10 -0
- package/lib/pricing/delivery-eu-tax.d.ts +2 -0
- package/lib/pricing/delivery-eu-tax.js +55 -0
- package/lib/pricing/delivery-swiss-tax/adapter.js +7 -26
- package/lib/pricing/delivery-swiss-tax.js +7 -26
- package/lib/pricing/delivery-uk-tax/adapter.d.ts +3 -0
- package/lib/pricing/delivery-uk-tax/adapter.js +43 -0
- package/lib/pricing/delivery-uk-tax/index.d.ts +4 -0
- package/lib/pricing/delivery-uk-tax/index.js +10 -0
- package/lib/pricing/delivery-uk-tax.d.ts +2 -0
- package/lib/pricing/delivery-uk-tax.js +43 -0
- package/lib/pricing/delivery-us-sales-tax/adapter.d.ts +3 -0
- package/lib/pricing/delivery-us-sales-tax/adapter.js +58 -0
- package/lib/pricing/delivery-us-sales-tax/index.d.ts +4 -0
- package/lib/pricing/delivery-us-sales-tax/index.js +10 -0
- package/lib/pricing/delivery-us-sales-tax.d.ts +2 -0
- package/lib/pricing/delivery-us-sales-tax.js +58 -0
- package/lib/pricing/product-eu-tax/adapter.d.ts +3 -0
- package/lib/pricing/product-eu-tax/adapter.js +56 -0
- package/lib/pricing/product-eu-tax/index.d.ts +4 -0
- package/lib/pricing/product-eu-tax/index.js +10 -0
- package/lib/pricing/product-eu-tax.d.ts +2 -0
- package/lib/pricing/product-eu-tax.js +56 -0
- package/lib/pricing/product-quotation-price.d.ts +2 -0
- package/lib/pricing/product-quotation-price.js +40 -0
- package/lib/pricing/product-swiss-tax/adapter.js +7 -26
- package/lib/pricing/product-swiss-tax.js +7 -26
- package/lib/pricing/product-uk-tax/adapter.d.ts +3 -0
- package/lib/pricing/product-uk-tax/adapter.js +57 -0
- package/lib/pricing/product-uk-tax/index.d.ts +4 -0
- package/lib/pricing/product-uk-tax/index.js +10 -0
- package/lib/pricing/product-uk-tax.d.ts +2 -0
- package/lib/pricing/product-uk-tax.js +57 -0
- package/lib/pricing/product-us-sales-tax/adapter.d.ts +3 -0
- package/lib/pricing/product-us-sales-tax/adapter.js +52 -0
- package/lib/pricing/product-us-sales-tax/index.d.ts +4 -0
- package/lib/pricing/product-us-sales-tax/index.js +10 -0
- package/lib/pricing/product-us-sales-tax.d.ts +2 -0
- package/lib/pricing/product-us-sales-tax.js +52 -0
- package/lib/pricing/tax/applyTaxRateToTaxableRows.d.ts +23 -0
- package/lib/pricing/tax/applyTaxRateToTaxableRows.js +30 -0
- package/lib/pricing/tax/ch-tax-rates.json +24 -0
- package/lib/pricing/tax/ch.js +6 -30
- package/lib/pricing/tax/eraRates.d.ts +10 -0
- package/lib/pricing/tax/eraRates.js +15 -0
- package/lib/pricing/tax/eu-tax-rates.json +797 -0
- package/lib/pricing/tax/eu.d.ts +12 -0
- package/lib/pricing/tax/eu.js +38 -0
- package/lib/pricing/tax/uk-tax-rates.json +18 -0
- package/lib/pricing/tax/uk.d.ts +10 -0
- package/lib/pricing/tax/uk.js +23 -0
- package/lib/pricing/tax/us-tax-rates.json +334 -0
- package/lib/pricing/tax/us.d.ts +11 -0
- package/lib/pricing/tax/us.js +20 -0
- package/lib/pricing/utils/isDeliveryAddressInCountry.d.ts +1 -1
- package/lib/pricing/utils/isDeliveryAddressInCountry.js +3 -8
- package/lib/pricing/utils/resolveDeliveryLocation.d.ts +10 -0
- package/lib/pricing/utils/resolveDeliveryLocation.js +9 -0
- package/lib/quotations/manual/adapter.js +6 -1
- package/lib/quotations/manual.js +6 -1
- package/lib/worker/gc-guests/adapter.d.ts +9 -0
- package/lib/worker/gc-guests/adapter.js +56 -0
- package/lib/worker/gc-guests/index.d.ts +4 -0
- package/lib/worker/gc-guests/index.js +13 -0
- package/lib/worker/gc-guests.d.ts +8 -0
- package/lib/worker/gc-guests.js +55 -0
- package/lib/worker/invalidate-carts/adapter.d.ts +9 -0
- package/lib/worker/invalidate-carts/adapter.js +52 -0
- package/lib/worker/invalidate-carts/index.d.ts +4 -0
- package/lib/worker/invalidate-carts/index.js +13 -0
- package/lib/worker/invalidate-carts.d.ts +8 -0
- package/lib/worker/invalidate-carts.js +51 -0
- package/lib/worker/zombie-killer/adapter.d.ts +2 -0
- package/lib/worker/zombie-killer/adapter.js +26 -3
- package/lib/worker/zombie-killer/index.js +4 -1
- package/lib/worker/zombie-killer.d.ts +1 -0
- package/lib/worker/zombie-killer.js +24 -3
- package/package.json +25 -8
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {} from '@unchainedshop/core';
|
|
2
|
+
import { ProductUkTax } from "./adapter.js";
|
|
3
|
+
export const ProductUkTaxPlugin = {
|
|
4
|
+
key: 'shop.unchained.pricing.product-uk-tax',
|
|
5
|
+
label: 'Product UK Tax Plugin',
|
|
6
|
+
version: '1.0.0',
|
|
7
|
+
adapters: [ProductUkTax],
|
|
8
|
+
};
|
|
9
|
+
export default ProductUkTaxPlugin;
|
|
10
|
+
export { ProductUkTax } from "./adapter.js";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ProductPricingDirector, ProductPricingAdapter, ProductPricingRowCategory, } from '@unchainedshop/core';
|
|
2
|
+
import { resolveUkTaxCategoryFromDeliveryProvider, resolveUkTaxCategoryFromProduct, UkTaxCategories, UK_VAT_COUNTRY_CODES, } from "./tax/uk.js";
|
|
3
|
+
import isDeliveryAddressInCountry from "./utils/isDeliveryAddressInCountry.js";
|
|
4
|
+
import { applyTaxRateToTaxableRows } from "./tax/applyTaxRateToTaxableRows.js";
|
|
5
|
+
export const ProductUkTax = {
|
|
6
|
+
...ProductPricingAdapter,
|
|
7
|
+
key: 'shop.unchained.pricing.product-uk-tax',
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
label: 'Apply UK VAT on Product',
|
|
10
|
+
orderIndex: 80,
|
|
11
|
+
isActivatedFor: () => {
|
|
12
|
+
return true;
|
|
13
|
+
},
|
|
14
|
+
actions: (params) => {
|
|
15
|
+
const pricingAdapter = ProductPricingAdapter.actions(params);
|
|
16
|
+
const { context } = params;
|
|
17
|
+
return {
|
|
18
|
+
...pricingAdapter,
|
|
19
|
+
calculate: async () => {
|
|
20
|
+
const orderDelivery = context.order?.deliveryId
|
|
21
|
+
? await context.modules.orders.deliveries.findDelivery({
|
|
22
|
+
orderDeliveryId: context.order?.deliveryId,
|
|
23
|
+
})
|
|
24
|
+
: null;
|
|
25
|
+
if (!isDeliveryAddressInCountry({
|
|
26
|
+
...context,
|
|
27
|
+
orderDelivery,
|
|
28
|
+
}, UK_VAT_COUNTRY_CODES)) {
|
|
29
|
+
return pricingAdapter.calculate();
|
|
30
|
+
}
|
|
31
|
+
let taxCategory = resolveUkTaxCategoryFromProduct(context.product);
|
|
32
|
+
if (!taxCategory) {
|
|
33
|
+
const provider = orderDelivery?.deliveryProviderId
|
|
34
|
+
? await context.modules.delivery.findProvider({
|
|
35
|
+
deliveryProviderId: orderDelivery?.deliveryProviderId,
|
|
36
|
+
})
|
|
37
|
+
: null;
|
|
38
|
+
if (provider)
|
|
39
|
+
taxCategory = resolveUkTaxCategoryFromDeliveryProvider(provider);
|
|
40
|
+
}
|
|
41
|
+
if (!taxCategory)
|
|
42
|
+
taxCategory = UkTaxCategories.STANDARD;
|
|
43
|
+
const taxRate = taxCategory.rate(context.order?.ordered);
|
|
44
|
+
ProductPricingAdapter.log(`ProductUkTax -> Tax Multiplicator: ${taxRate}`);
|
|
45
|
+
applyTaxRateToTaxableRows({
|
|
46
|
+
calculationSheet: params.calculationSheet,
|
|
47
|
+
resultSheet: pricingAdapter.resultSheet(),
|
|
48
|
+
taxRate,
|
|
49
|
+
baseCategory: ProductPricingRowCategory.Item,
|
|
50
|
+
adapterKey: ProductUkTax.key,
|
|
51
|
+
});
|
|
52
|
+
return pricingAdapter.calculate();
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
ProductPricingDirector.registerAdapter(ProductUkTax);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ProductPricingAdapter, ProductPricingRowCategory, } from '@unchainedshop/core';
|
|
2
|
+
import { US_COUNTRY_CODE, isProductExemptFromUsSalesTax, resolveUsSalesTaxRate } from "../tax/us.js";
|
|
3
|
+
import resolveDeliveryLocation from "../utils/resolveDeliveryLocation.js";
|
|
4
|
+
import { applyTaxRateToTaxableRows } from "../tax/applyTaxRateToTaxableRows.js";
|
|
5
|
+
export const ProductUsSalesTax = {
|
|
6
|
+
...ProductPricingAdapter,
|
|
7
|
+
key: 'shop.unchained.pricing.product-us-sales-tax',
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
label: 'Apply US State Sales Tax on Product',
|
|
10
|
+
orderIndex: 80,
|
|
11
|
+
isActivatedFor: () => {
|
|
12
|
+
return true;
|
|
13
|
+
},
|
|
14
|
+
actions: (params) => {
|
|
15
|
+
const pricingAdapter = ProductPricingAdapter.actions(params);
|
|
16
|
+
const { context } = params;
|
|
17
|
+
return {
|
|
18
|
+
...pricingAdapter,
|
|
19
|
+
calculate: async () => {
|
|
20
|
+
if (isProductExemptFromUsSalesTax(context.product)) {
|
|
21
|
+
return pricingAdapter.calculate();
|
|
22
|
+
}
|
|
23
|
+
const orderDelivery = context.order?.deliveryId
|
|
24
|
+
? await context.modules.orders.deliveries.findDelivery({
|
|
25
|
+
orderDeliveryId: context.order?.deliveryId,
|
|
26
|
+
})
|
|
27
|
+
: null;
|
|
28
|
+
const { countryCode, regionCode } = resolveDeliveryLocation({ ...context, orderDelivery });
|
|
29
|
+
if (countryCode !== US_COUNTRY_CODE)
|
|
30
|
+
return pricingAdapter.calculate();
|
|
31
|
+
const taxRate = resolveUsSalesTaxRate({
|
|
32
|
+
regionCode,
|
|
33
|
+
referenceDate: context.order?.ordered,
|
|
34
|
+
});
|
|
35
|
+
if (taxRate === null) {
|
|
36
|
+
ProductPricingAdapter.log(`ProductUsSalesTax -> unknown state '${regionCode}', no sales tax applied`);
|
|
37
|
+
return pricingAdapter.calculate();
|
|
38
|
+
}
|
|
39
|
+
ProductPricingAdapter.log(`ProductUsSalesTax -> Tax Multiplicator: ${taxRate}`);
|
|
40
|
+
applyTaxRateToTaxableRows({
|
|
41
|
+
calculationSheet: params.calculationSheet,
|
|
42
|
+
resultSheet: pricingAdapter.resultSheet(),
|
|
43
|
+
taxRate,
|
|
44
|
+
baseCategory: ProductPricingRowCategory.Item,
|
|
45
|
+
adapterKey: ProductUsSalesTax.key,
|
|
46
|
+
});
|
|
47
|
+
return pricingAdapter.calculate();
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
export default ProductUsSalesTax;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {} from '@unchainedshop/core';
|
|
2
|
+
import { ProductUsSalesTax } from "./adapter.js";
|
|
3
|
+
export const ProductUsSalesTaxPlugin = {
|
|
4
|
+
key: 'shop.unchained.pricing.product-us-sales-tax',
|
|
5
|
+
label: 'Product US Sales Tax Plugin',
|
|
6
|
+
version: '1.0.0',
|
|
7
|
+
adapters: [ProductUsSalesTax],
|
|
8
|
+
};
|
|
9
|
+
export default ProductUsSalesTaxPlugin;
|
|
10
|
+
export { ProductUsSalesTax } from "./adapter.js";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ProductPricingDirector, ProductPricingAdapter, ProductPricingRowCategory, } from '@unchainedshop/core';
|
|
2
|
+
import { US_COUNTRY_CODE, isProductExemptFromUsSalesTax, resolveUsSalesTaxRate } from "./tax/us.js";
|
|
3
|
+
import resolveDeliveryLocation from "./utils/resolveDeliveryLocation.js";
|
|
4
|
+
import { applyTaxRateToTaxableRows } from "./tax/applyTaxRateToTaxableRows.js";
|
|
5
|
+
export const ProductUsSalesTax = {
|
|
6
|
+
...ProductPricingAdapter,
|
|
7
|
+
key: 'shop.unchained.pricing.product-us-sales-tax',
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
label: 'Apply US State Sales Tax on Product',
|
|
10
|
+
orderIndex: 80,
|
|
11
|
+
isActivatedFor: () => {
|
|
12
|
+
return true;
|
|
13
|
+
},
|
|
14
|
+
actions: (params) => {
|
|
15
|
+
const pricingAdapter = ProductPricingAdapter.actions(params);
|
|
16
|
+
const { context } = params;
|
|
17
|
+
return {
|
|
18
|
+
...pricingAdapter,
|
|
19
|
+
calculate: async () => {
|
|
20
|
+
if (isProductExemptFromUsSalesTax(context.product)) {
|
|
21
|
+
return pricingAdapter.calculate();
|
|
22
|
+
}
|
|
23
|
+
const orderDelivery = context.order?.deliveryId
|
|
24
|
+
? await context.modules.orders.deliveries.findDelivery({
|
|
25
|
+
orderDeliveryId: context.order?.deliveryId,
|
|
26
|
+
})
|
|
27
|
+
: null;
|
|
28
|
+
const { countryCode, regionCode } = resolveDeliveryLocation({ ...context, orderDelivery });
|
|
29
|
+
if (countryCode !== US_COUNTRY_CODE)
|
|
30
|
+
return pricingAdapter.calculate();
|
|
31
|
+
const taxRate = resolveUsSalesTaxRate({
|
|
32
|
+
regionCode,
|
|
33
|
+
referenceDate: context.order?.ordered,
|
|
34
|
+
});
|
|
35
|
+
if (taxRate === null) {
|
|
36
|
+
ProductPricingAdapter.log(`ProductUsSalesTax -> unknown state '${regionCode}', no sales tax applied`);
|
|
37
|
+
return pricingAdapter.calculate();
|
|
38
|
+
}
|
|
39
|
+
ProductPricingAdapter.log(`ProductUsSalesTax -> Tax Multiplicator: ${taxRate}`);
|
|
40
|
+
applyTaxRateToTaxableRows({
|
|
41
|
+
calculationSheet: params.calculationSheet,
|
|
42
|
+
resultSheet: pricingAdapter.resultSheet(),
|
|
43
|
+
taxRate,
|
|
44
|
+
baseCategory: ProductPricingRowCategory.Item,
|
|
45
|
+
adapterKey: ProductUsSalesTax.key,
|
|
46
|
+
});
|
|
47
|
+
return pricingAdapter.calculate();
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
ProductPricingDirector.registerAdapter(ProductUsSalesTax);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { PricingCalculation } from '@unchainedshop/utils';
|
|
2
|
+
export interface TaxableCalculation extends PricingCalculation {
|
|
3
|
+
isTaxable?: boolean;
|
|
4
|
+
isNetPrice?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface TaxResultSheet {
|
|
7
|
+
calculation: PricingCalculation[];
|
|
8
|
+
addTax: (row: {
|
|
9
|
+
amount: number;
|
|
10
|
+
rate: number;
|
|
11
|
+
baseCategory: string;
|
|
12
|
+
meta?: unknown;
|
|
13
|
+
}) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare const applyTaxRateToTaxableRows: <Calculation extends TaxableCalculation>({ calculationSheet, resultSheet, taxRate, baseCategory, adapterKey, }: {
|
|
16
|
+
calculationSheet: {
|
|
17
|
+
filterBy: (filter?: Partial<Calculation>) => Calculation[];
|
|
18
|
+
};
|
|
19
|
+
resultSheet: TaxResultSheet;
|
|
20
|
+
taxRate: number;
|
|
21
|
+
baseCategory: string;
|
|
22
|
+
adapterKey: string;
|
|
23
|
+
}) => void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const applyTaxRateToTaxableRows = ({ calculationSheet, resultSheet, taxRate, baseCategory, adapterKey, }) => {
|
|
2
|
+
calculationSheet
|
|
3
|
+
.filterBy({ isTaxable: true })
|
|
4
|
+
.forEach(({ isNetPrice, ...row }) => {
|
|
5
|
+
if (!isNetPrice) {
|
|
6
|
+
const taxAmount = row.amount - row.amount / (1 + taxRate);
|
|
7
|
+
resultSheet.calculation.push({
|
|
8
|
+
...row,
|
|
9
|
+
amount: -taxAmount,
|
|
10
|
+
isTaxable: false,
|
|
11
|
+
isNetPrice: false,
|
|
12
|
+
meta: { adapter: adapterKey },
|
|
13
|
+
});
|
|
14
|
+
resultSheet.addTax({
|
|
15
|
+
amount: taxAmount,
|
|
16
|
+
rate: taxRate,
|
|
17
|
+
baseCategory,
|
|
18
|
+
meta: { adapter: adapterKey },
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
resultSheet.addTax({
|
|
23
|
+
amount: row.amount * taxRate,
|
|
24
|
+
rate: taxRate,
|
|
25
|
+
baseCategory,
|
|
26
|
+
meta: { adapter: adapterKey },
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"source": "https://www.estv.admin.ch/estv/en/home/value-added-tax/vat-rates-switzerland.html",
|
|
3
|
+
"verifiedAt": "2026-08-20",
|
|
4
|
+
"timezone": "+01:00",
|
|
5
|
+
"categories": {
|
|
6
|
+
"default": [
|
|
7
|
+
{ "validFrom": "2001-01-01", "rate": 0.076 },
|
|
8
|
+
{ "validFrom": "2011-01-01", "rate": 0.08 },
|
|
9
|
+
{ "validFrom": "2018-01-01", "rate": 0.077 },
|
|
10
|
+
{ "validFrom": "2024-01-01", "rate": 0.081 }
|
|
11
|
+
],
|
|
12
|
+
"reduced": [
|
|
13
|
+
{ "validFrom": "2001-01-01", "rate": 0.024 },
|
|
14
|
+
{ "validFrom": "2011-01-01", "rate": 0.025 },
|
|
15
|
+
{ "validFrom": "2024-01-01", "rate": 0.026 }
|
|
16
|
+
],
|
|
17
|
+
"special": [
|
|
18
|
+
{ "validFrom": "2001-01-01", "rate": 0.036 },
|
|
19
|
+
{ "validFrom": "2011-01-01", "rate": 0.038 },
|
|
20
|
+
{ "validFrom": "2018-01-01", "rate": 0.037 },
|
|
21
|
+
{ "validFrom": "2024-01-01", "rate": 0.038 }
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}
|
package/lib/pricing/tax/ch.js
CHANGED
|
@@ -1,33 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return 0.077;
|
|
8
|
-
}
|
|
9
|
-
return 0.081;
|
|
10
|
-
},
|
|
11
|
-
},
|
|
12
|
-
REDUCED: {
|
|
13
|
-
value: 'reduced',
|
|
14
|
-
rate: (referenceDate = new Date()) => {
|
|
15
|
-
if (referenceDate.getTime() < startOf2024.getTime()) {
|
|
16
|
-
return 0.025;
|
|
17
|
-
}
|
|
18
|
-
return 0.026;
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
SPECIAL: {
|
|
22
|
-
value: 'special',
|
|
23
|
-
rate: (referenceDate = new Date()) => {
|
|
24
|
-
if (referenceDate.getTime() < startOf2024.getTime()) {
|
|
25
|
-
return 0.037;
|
|
26
|
-
}
|
|
27
|
-
return 0.038;
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
};
|
|
1
|
+
import swissTaxRates from './ch-tax-rates.json' with { type: 'json' };
|
|
2
|
+
import { compileEraRates, rateForDate } from "./eraRates.js";
|
|
3
|
+
export const SwissTaxCategories = Object.fromEntries(Object.entries(swissTaxRates.categories).map(([value, eras]) => [
|
|
4
|
+
value.toUpperCase(),
|
|
5
|
+
{ value, rate: rateForDate(compileEraRates(eras, swissTaxRates.timezone)) },
|
|
6
|
+
]));
|
|
31
7
|
export const resolveTaxCategoryFromDeliveryProvider = (provider) => {
|
|
32
8
|
const taxCategoryFromProvider = provider?.configuration
|
|
33
9
|
?.find(({ key }) => {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface TaxRateEra {
|
|
2
|
+
validFrom: string;
|
|
3
|
+
rate: number;
|
|
4
|
+
}
|
|
5
|
+
export interface CompiledTaxRateEra {
|
|
6
|
+
validFrom: number;
|
|
7
|
+
rate: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const compileEraRates: (eras: TaxRateEra[], utcOffset: string) => CompiledTaxRateEra[];
|
|
10
|
+
export declare const rateForDate: (eras: CompiledTaxRateEra[]) => (referenceDate?: Date) => number;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const compileEraRates = (eras, utcOffset) => eras
|
|
2
|
+
.map(({ validFrom, rate }) => ({
|
|
3
|
+
validFrom: new Date(`${validFrom}T00:00:00.000${utcOffset}`).getTime(),
|
|
4
|
+
rate,
|
|
5
|
+
}))
|
|
6
|
+
.sort((left, right) => left.validFrom - right.validFrom);
|
|
7
|
+
export const rateForDate = (eras) => (referenceDate = new Date()) => {
|
|
8
|
+
const time = referenceDate.getTime();
|
|
9
|
+
let applicable = eras[0];
|
|
10
|
+
for (const era of eras) {
|
|
11
|
+
if (era.validFrom <= time)
|
|
12
|
+
applicable = era;
|
|
13
|
+
}
|
|
14
|
+
return applicable.rate;
|
|
15
|
+
};
|