New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@restorecommerce/cart

Package Overview
Dependencies
Maintainers
0
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@restorecommerce/cart

[![Build Status][build]](https://travis-ci.org/restorecommerce/cart?branch=master)[![Dependencies][depend]](https://david-dm.org/restorecommerce/cart)[![Coverage Sta

  • 1.0.9
  • latest
  • Source
  • npm
  • Socket score

Version published
Maintainers
0
Created
Source

@restorecommerce/cart

Build StatusDependenciesCoverage Status

An backend agnostic purely data-driven shopping cart that can be used on client- and server side.

Features

  • Item handling (add, remove etc.)
  • VAT calculation with extensible tax model
    • EU tax calculation built-in (for sub-threshold based taxation)
  • Shipping cost calculation based on selected courier and plan
  • Extensibility for adding couriers
  • Totals calculation based on items, taxes and shipping
  • Can run completely offline
  • Local storage on browsers via pluggable serializers
  • Back-end agnostic
  • Fully typed

Usage

Basic Example

Cart Instantiation:

const cart = new Cart({
  serializer: new MockSerializer(),
  shippingMethod: new Courier({
    source: JSON.stringify(data.publicDHL),
    shipping: {originCountry: 'DE'}
  }),
  taxOriginCountry: 'DE',
  taxes: {
    vat_standard: {
      rate: new Decimal(1.19),
      desc: '+ VAT 19%'
    },
    vat_reduced: {
      rate: new Decimal(1.07),
      desc: '+ VAT 7%'
    }
  }
});

Setting serializer and shippingMethod is optional.

setDestinationCountry(country: string)

cart.setDestinationCountry('LV');

getShippingMethod()

cart.getShippingMethod();

Output:

Courier {
  _source: {
    assumptions: {
      currency: 'eur',
      dimensions: [Object],
      length: 'mm',
      ranges: [Object],
      weight: 'gram'
    },
    zones: {
      '1': [Object],
      '2': [Object],
      '3': [Object],
      '4': [Object],
      '5': [Object],
      '6': [Object],
      '7': [Object],
      '8': [Object],
      national: [Object]
    }
  },
  _shipping: {
    destinationCountry: 'LV',
    originCountry: 'DE' }
}

getShipping()

There is no setShipping setter, since info about shipping is taken from ShippingMethod's source property.

cart.getShipping(); // calculates shipping cost

Output:

{
  price: '15.99',
  taxType: 'vat_standard',
  maxWeight: 5000,
  type: 'package',
  zone: '1',
  human: {
    zone: '1 (all EU countries)',
    offer: 'Package up to 5kg',
  }
}

getSerializer()

cart.getSerializer();

getTaxRates()

cart.getTaxRates();

Output:

{
  taxes: {
    vat_standard: {
      rate: '1.19',
      desc: '+ VAT 19%'
    },
    vat_reduced: {
      rate: '1.07',
      desc: '+ VAT 7%'
    }
  }
}

addItems(items: IItem[])

cart.addItems([{
  sku: 'cr2-blue',
  price: new Decimal('12.95'), // Price
  taxType: 'vat_reduced',
  weight: 210, // grams
  height: 2.20, // cm
  width: 13.5, // cm
  depth: 8.22, // cm
  quantity: 7,
}, {
  sku: 'cr5-red',
  price: new Decimal('1.10'),
  taxType: 'vat_standard',
  weight: 210, // grams
  height: 2.20, // cm
  width: 13.5, // cm
  depth: 8.22, // cm
  quantity: 15,
}, {
  sku: 'cr3-yellow',
  price: new Decimal('2.48'),
  taxType: 'vat_standard',
  weight: 210, // grams
  height: 2.20, // cm
  width: 13.5, // cm
  depth: 8.22, // cm
  quantity: 3,
}]);

remItem(sku: string)

cart.remItem('cr3-yellow');

getItems()

cart.getItems();

Output:

[
  {
    sku: 'cr2-blue',
    price: 12.95,
    taxType: 'vat_reduced',
    weight: 210,
    height: 2.2,
    width: 13.5,
    depth: 8.22,
    quantity: 7
  },
  {
    sku: 'cr5-red',
    price: 1.10,
    taxType: 'vat_standard',
    weight: 210,
    height: 2.2,
    width: 13.5,
    depth: 8.22,
    quantity: 15
   }
]

setCustomer(customer: ICustomer)

cart.setCustomer({
  type: CustomerType.COMMERCIAL,
});

setCustomerType(type: CustomerType)

This modifies the customer..

cart.setCustomerType(CustomerType.PRIVATE);

getCustomer()

cart.getCustomer();

Output:

{
  type: 1 // 0 - COMMERCIAL / 1 - PRIVATE
}

modifyItem(item: any)

cart.modifyItem({
  sku: 'cr5-red',
  // no update for other Cart properties as no change
  quantity: 10, // change only quantity
});

modifyItemQuantity(sku: string, quantity: number)

cart.modifyItemQuantity('cr5-red', 5); // adds 5 to initial quantity

getItemQuantity(sku: string)

`Amount of cr2-blue = ${cart.getItemQuantity('cr5-red')}`;

Output:

Amount of cr5-red = 15 // 10 + 5

getItemCount()

`Amount of unique products = ${cart.getItemCount()}`;

Output:

Amount of unique products = 2

getGrandQuantity()

`Amount of all products = ${cart.getGrandQuantity()}`;

Output:

Amount of all products = 22 // 15 + 7

getTaxes(keepOriginalTaxType?: boolean )

cart.getTaxes();

Output:

netPrice and rate are instances of Decimal.

{
  vat_standard: {
    netPrice: '32.49',
    rate: '1.19',
    desc: '+ VAT 19%'
  },
  vat_reduced: {
    netPrice: '90.65',
    rate: '1.07',
    desc: '+ VAT 7%'
  }
}

static round(money: Money)

Parameter could be number|string|Decimal. Returns string.

Cart.round(1.120); // '1.12'
Cart.round('1.123'); // '1.13'
Cart.round(new Decimal(1.125)); // '1.13'
Cart.round(new Decimal('1.127')); // '1.13'

getTotalNet()

Total net (without taxes).

Cart.round(cart.getTotalNet()); // '123.14'

Calculation:

1) customer.billing.countryCode === 'LV' => VAT + 19% / 7%
2) cr2_blue: Price * quantity => 12.95 * 7  = 90.65
3) cr5_red:  Price * quantity => 1.10 * 15  = 16.5
4) Max Weight of all items = 22 items * 210 grams  = 4620 grams =>
shipping = 15.99 euro for package less than 5000 grams to EU
5) sum = 90.65 + 16.5 + 15.99 = 123.14

getTotalGross()

Total gross (with taxes).

Cart.round(cart.getTotalGross()); // '135.66'

Calculation:

1) cr2_blue => cr2_blue + VAT 7% = 90.65 * 1.07 = 96.9955
2) cr5_red => cr5_red + VAT 19% = 16.5 * 1.19 = 19.635
3) shipping => shipping + VAT 19% = 15.99 * 1.19 = 19.0281
4) sum  =>  96.9955 + 19.635 + 19.0281 = 135.6586
5) round(135.6586) = 135.66

Tests

More examples of using the Cart can be found in test/index.ts.

Reference

MethodDescription
getItems(): IItems / undefinedGet Items
private setItems(items: IItem[]): voidSet items
getCustomer(): ICustomer / undefinedGet customer
setCustomer(customer: ICustomer): voidSet customer
getShippingMethod(): IShippingMethod/ undefinedGet shipping method
setShippingMethod(shippingMethod: IShippingMethod): voidSet shipping method
getSerializer(): ISerializer / undefinedGet serializer
setSerializer(serializer: ISerializer): voidSet serializer
getTaxRates(): TaxRatesGet tax rates
private setTaxRates(taxRates: TaxRates)Set tax rates
setCustomerType(type: CustomerType): voidSet customer's type (PRIVATE/COMMERCIAL)
setDestinationCountry(country: string): voidSet destination country
addItems(items: IItem[]): voidAdd item/items to the cart
remItem(sku: string): voidRemove item from the cart by SKU (Stock Keeping Unit)
modifyItem(item: any)Update item
modifyItemQuantity(sku: string, quantity: number): voidModify item's quantity
getItemCount(): numberGet item count
getItemQuantity(sku: string): numberGet quantity of particular item
getGrandQuantity(): numberItem count x quantity of each item
getTaxes(keepOriginalTaxType?: boolean ): { [taxType: string]: { netPrice: Decimal, rate: Decimal, desc: string, price: Decimal } } Get tax list, with ratios and additive costs
getTotalNet(): numberGet sum of item and shipping costs (taxes excluded)
getTotalGross(): numberGet sum of item and shipping costs (taxes included)
getShipping(): { price: Money, [prop: string]: any }Get item's shipping info
static round(money: Money): stringConvert money type (number/string/Decimal) to string with rounding

Development

To lint, transpile and test, run:

npm test

Couriers

IShippingMethod interface implementations:

Courier Plans:

Calculation Logic

Taxes

For VAT calculation, the cart applies the EU ruleset for taxation which is exemplified in the following with a shop that is located in Germany and customer location location/ type being:

  • Germany private: VAT applies
  • Germany commercial: VAT applies
  • Other EU countries private: VAT applies
  • Other EU countries commercial: VAT free
  • Non-EU countries private: VAT free
  • Non-EU countries commercial: VAT free

This also works for other countries as it's just a simplification of this for most countries. Sales taxes and other country specific taxes can be added.

Legal background:

Keywords

FAQs

Package last updated on 23 Sep 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc