Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/modules / ___dist / money / Money.js
Size: Mime:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.Money = void 0;

var _mobx = require("xmobx/mobx");

var _exotic = require("../exotic");

var _chainAble = require("../chain-able");

var _deps = require("./deps");

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

// const cloneAndFreeze = x => freeze(JSON.parse(JSON.stringify(x)))

/**
 * @param {Object} thisArg
 * @param {String | Symbol} prop
 * @curried 1
 */
function enumerableFor(thisArg, prop) {
  if (arguments.length === 1) {
    return function curriedEnumerableFor(curriedProp) {
      enumerableFor(thisArg, curriedProp);
    };
  }

  if ((0, _exotic.isArray)(prop)) {
    prop.forEach(key => enumerableFor(thisArg, key));
    return enumerableFor;
  }

  const prototype = Object.getPrototypeOf(thisArg);
  const descriptor = Object.getOwnPropertyDescriptor(thisArg, prop) || Object.getOwnPropertyDescriptor(prototype, prop) || {};
  Object.defineProperty(thisArg, prop, _objectSpread({}, descriptor, {
    enumerable: true // get: descriptor.get,
    // set: descriptor.set,

  }));
  return enumerableFor;
}
/**
 * @todo what to do when reg === sale ?
 * @todo toCheapest() // use with from as low as...
 * @todo toHighest()
 *
 * @see catalog/product/index get salePrice()
 * @type {ValueObject<MoneyValueObject>}
 */


let Money = class Money {
  // ========= data ======
  // static types = {
  // for tests
  // inspect() {
  //   return {
  //     ...this.toJSON(),
  //     INSPECTING: true,
  //   }
  // }
  static from(pricingReference) {
    /**
     * @todo @hack - way to make observable not update on computed
     * clone(pricingReference) || pricingReference
     */
    const pricing = (0, _mobx.isObservable)(pricingReference) ? (0, _mobx.toJS)(pricingReference) : pricingReference; // const frozenMoney = transformPricing(pricing)

    (0, _deps.transformPricing)(pricing);
    const money = new Money(); // always must be an array...

    if ((0, _exotic.isNil)(pricing)) {
      console.warn('NILL_PRICING');
      return money;
    }

    money.priceList = (0, _exotic.isArray)(pricing) ? pricing : [pricing];
    (0, _chainAble.freeze)(money.priceList);
    return money;
  }

  constructor(pricing = undefined) {
    this.currencycode = '$';
    this.priceList = Object.freeze([]);
    this.makeGettersEnumerable();
  }
  /**
   * @description updates PropertyDescriptors to make them enumerable
   * @example
   *    var canada = {get eh() return 1, moose: 2}
   *    {...canada} === {moose: 2}
   *
   *    makeEnumerable(canada, 'eh')
   *    {...canada} === {eh: 1, moose: 2}
   */


  makeGettersEnumerable() {
    const makeEnumerable = enumerableFor(this); // 'symbol' => may be reserved

    makeEnumerable(['reg', 'sale', 'hasRange', 'hasSaleAndReg']);
  } // ========= queruy ======
  // eslint-disable-next-line


  find(specification) {
    // console.log({ where: specification, self: this })
    // @notempty
    const findings = this.priceList.filter(specification);
    const found = (0, _deps.fromFindingsToFound)(findings);
    return found;
  }
  /**
   * @param {Function | Object} specification
   * @return {PriceType}
   */


  where(specification) {
    const found = this.find(specification);

    found.toString = () => (0, _deps.toFormattedPriceValue)(found.value); // defineFinal


    const existing = Object.getOwnPropertyDescriptor(found, 'toString');

    if (existing.writable !== false) {
      Object.defineProperty(found, 'toString', {
        configurable: true,
        writable: true,
        enumerable: false,

        value() {
          return (0, _deps.toFormattedPriceValue)(found.value);
        }

      });
    }

    found[Symbol.toPrimitive] = function (type) {
      if (type === 'number') {
        return found.value;
      } else {
        return (0, _deps.toFormattedPriceValue)(found.value);
      }
    };

    return found;
  }
  /**
   * @param {String} type sale | reg | original
   * @return {PriceType}
   */


  whereType(type) {
    // console.log({ type })
    return this.where(x => x.type === type);
  } // ========= computed ======

  /**
   * @return {String}
   */
  // get symbol() {
  //   return this.currencycode
  // }

  /**
   * @return {Boolean}
   */


  get hasRange() {
    return this.priceList.some(_deps.isRange);
  }
  /**
   * @description has a sale, reg, AT LEAST 2 ARE UNIQUE
   * @return {Boolean}
   */


  get hasSaleAndReg() {
    const reg = this.reg,
          sale = this.sale;
    return reg.isValid && sale.isValid && reg.toString() !== sale.toString();
  } // ========= types ======

  /**
   * @return {MoneyValueObject}
   */


  get sale() {
    const sale = this.whereType('sale'); // no sale if it's
    // 1. a real value
    // 2. same as regular

    if (sale.value && sale.value === this.reg.value) {
      return '';
    } else {
      return sale;
    }
  }
  /**
   * @note reg === original - just client specific wording
   * @return {MoneyValueObject}
   */


  get reg() {
    const reg = this.whereType('reg');
    return reg;
  } // yagni for now
  // @todo - min of the whole price, sale and max?
  // get min() { }
  // get max() { }
  // ========= transforms ======

  /**
   * @todo setFormatter
   * @param {*} [formatting]
   * @return {Object | String | Number}
   */


  toFormatted(formatting = 1 | 2 | Function) {
    if (this.hasSaleAndReg) {
      const sale = this.sale,
            reg = this.reg;
      return {
        sale: sale.toString(),
        reg: reg.toString()
      };
    } else if (this.sale) {
      // should define data at top - this is premature optimization tsk tsk
      // still understandable
      // prefer sale > reg? if formatting matches?
      return this.sale.toString();
    } else {
      return this.reg.toString();
    } // const formattedSale = fromRangeToString(sale.min, sale.max)
    // price.sale = minPrice + +

  }

  toJSON() {
    return {
      reg: this.reg,
      sale: this.sale
    };
  }

  toString() {
    return this.toFormatted();
  }
  /**
   * @todo
   * @alias toArray
   *
   * @description give price as a range
   * @param {Boolean} [recursive=false] if we have a [sale-range] & [reg-range], nested array
   *
   * @example
   *  .toRange(true)
   *  //=> [[1.1, 2.2], [1.1, 2.2]]
   *
   * @example
   *  .toRange()
   *  // => [1.1, 2.2]
   *
   */


  toRange(recursive = false) {//
  }

};
exports.Money = Money;
var _default = Money;
exports.default = _default;