shipping-method.entity.ts 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { ConfigurableOperation } from '@vendure/common/lib/generated-types';
  2. import { DeepPartial } from '@vendure/common/lib/shared-types';
  3. import { Column, Entity, JoinTable, ManyToMany } from 'typeorm';
  4. import { ChannelAware } from '../../common/types/common-types';
  5. import { getConfig } from '../../config/config-helpers';
  6. import { ShippingCalculator, ShippingPrice } from '../../config/shipping-method/shipping-calculator';
  7. import { ShippingEligibilityChecker } from '../../config/shipping-method/shipping-eligibility-checker';
  8. import { VendureEntity } from '../base/base.entity';
  9. import { Channel } from '../channel/channel.entity';
  10. import { Order } from '../order/order.entity';
  11. /**
  12. * @description
  13. * A ShippingMethod is used to apply a shipping price to an {@link Order}. It is composed of a
  14. * {@link ShippingEligibilityChecker} and a {@link ShippingCalculator}. For a given Order,
  15. * the `checker` is used to determine whether this ShippingMethod can be used. If yes, then
  16. * the ShippingMethod can be applied and the `calculator` is used to determine the price of
  17. * shipping.
  18. *
  19. * @docsCategory entities
  20. */
  21. @Entity()
  22. export class ShippingMethod extends VendureEntity implements ChannelAware {
  23. private readonly allCheckers: { [code: string]: ShippingEligibilityChecker } = {};
  24. private readonly allCalculators: { [code: string]: ShippingCalculator } = {};
  25. constructor(input?: DeepPartial<ShippingMethod>) {
  26. super(input);
  27. const checkers = getConfig().shippingOptions.shippingEligibilityCheckers || [];
  28. const calculators = getConfig().shippingOptions.shippingCalculators || [];
  29. this.allCheckers = checkers.reduce((hash, o) => ({ ...hash, [o.code]: o }), {});
  30. this.allCalculators = calculators.reduce((hash, o) => ({ ...hash, [o.code]: o }), {});
  31. }
  32. @Column() code: string;
  33. @Column() description: string;
  34. @Column('simple-json') checker: ConfigurableOperation;
  35. @Column('simple-json') calculator: ConfigurableOperation;
  36. @ManyToMany(type => Channel)
  37. @JoinTable()
  38. channels: Channel[];
  39. async apply(order: Order): Promise<ShippingPrice | undefined> {
  40. const calculator = this.allCalculators[this.calculator.code];
  41. if (calculator) {
  42. const { price, priceWithTax } = await calculator.calculate(order, this.calculator.args);
  43. return {
  44. price: Math.round(price),
  45. priceWithTax: Math.round(priceWithTax),
  46. };
  47. }
  48. }
  49. async test(order: Order): Promise<boolean> {
  50. const checker = this.allCheckers[this.checker.code];
  51. if (checker) {
  52. return checker.check(order, this.checker.args);
  53. } else {
  54. return false;
  55. }
  56. }
  57. }