Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
profe-ajedrez committed Sep 5, 2021
0 parents commit 654b7bb
Show file tree
Hide file tree
Showing 13 changed files with 491 additions and 0 deletions.
Empty file added index.js
Empty file.
86 changes: 86 additions & 0 deletions lib/b2c6/currency/Currency.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { AbstractArithmetizable } from "../mathematics/AbstractArithmetizable";

export class Currency extends AbstractArithmetizable {
static defaultCurrencyIsoName = "CLP";
static defaultDecimals = 2;

#isoName;
#isoDecimals;
#storer;
#numberStorerFabric;


/**
* constructor
*
* @param {Object} inits options for currency instance
*/
constructor(inits) {
super();
inits = {
...{
isoName: Currency.defaultCurrencyIsoName,
decimals: Currency.defaultDecimals,
ammount: 0,
numberStorerFabric: null
},
...inits
};

this.#isoName = inits.isoName;
this.#isoDecimals = inits.isoDecimals;
this.#numberStorerFabric = inits.numberStorerFabric;

this.#storer = new this.#numberStorerFabric(inits.ammount);
}

get isoDecimals() {
return this.#isoDecimals
}

get isoName() {
return this.#isoName
}

get ammount() {
return this.#storer.toString();
}

add(value) {
const pojo = this.toPojo();
pojo.ammount = this.#storer.add(value).toString();
return new Currency(pojo);
}

substract() {
const pojo = this.toPojo();
pojo.ammount = this.#storer.substract(value).toString();
return new Currency(pojo);
}

multiply() {
const pojo = this.toPojo();
pojo.ammount = this.#storer.multiply(value).toString();
return new Currency(pojo);
}

divide() {
const pojo = this.toPojo();
pojo.ammount = this.#storer.divide(value).toString();
return new Currency(pojo);
}

toString() {
return this.#storer.toString();
}


toPojo() {
return {
isoName: this.#isoName,
decimals: this.#isoDecimals,
ammount: this.toString(),
numberStorerFabric: this.#numberStorerFabric
};
}
}
32 changes: 32 additions & 0 deletions lib/b2c6/errors/Errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class InstanciatingAbstractClassError extends Error {
constructor(message = "You are trying to instantiate an abstract class, asshole!") {
super(message);
this.name = "InstanciatingAbstractClassError";
}
}

class UndefinedMethod extends Error {
constructor (message = "You are trying to invoke an undefined method, asshole") {
super(message);
this.name = 'UndefinedMethod';
}
}

/**
* InvokingAbstractClassMethod
*
* Exception throwed when invoking a method from an abstract class
*/
class InvokingAbstractClassMethod extends UndefinedMethod {
constructor (message = "You are trying to invoke a method of an abstract class, asshole! (May be you have not implement this method in the concrete class yet? moron!)") {
super(message);
this.name = 'InvokingAbstractClassMethod';
}
}


module.exports = {
InstanciatingAbstractClassError,
UndefinedMethod,
InvokingAbstractClassMethod
};
25 changes: 25 additions & 0 deletions lib/b2c6/mathematics/AbstractArithmetizable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { InstanciatingAbstractClassError, InvokingAbstractClassMethod } from "../errors/Errors";

export class AbstractArithmetizable {
constructor() {
if (this.constructor === AbstractArithmetizable) {
throw new InstanciatingAbstractClassError();
}
}

add() {
throw new InvokingAbstractClassMethod("AbstractArithmetizable::add");
}

substract() {
throw new InvokingAbstractClassMethod("AbstractArithmetizable::substract");
}

multiply() {
throw new InvokingAbstractClassMethod("AbstractArithmetizable::multiply");
}

divide() {
throw new InvokingAbstractClassMethod("AbstractArithmetizable::denominator");
}
}
74 changes: 74 additions & 0 deletions lib/b2c6/mathematics/DecimalChanta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { AbstractArithmetizable } from "./AbstractArithmetizable";

const DEFAULT_PRECISION = 32;
const ROUND_TO_NEAREST = true;

export class DecimalChanta extends AbstractArithmetizable {
static precision = DEFAULT_PRECISION;
static round = ROUND_TO_NEAREST;
static poweredFactor = BigInt("1" + "0".repeat(DecimalChanta.precision));


static createFromBigInt(bigInt) {
const pojo = { _daBigValue: bigInt };
return Object.assign( Object.create(DecimalChanta.prototype), pojo);
}

static roundedDivision(numerator, denominator) {
const correction = (DecimalChanta.round ? numerator * 2n / denominator % 2n : 0n);
return DecimalChanta.createFromBigInt(numerator / denominator + correction);
}



constructor(value) {
super();
if (value instanceof DecimalChanta) {
return value;
}

let [ integerPart, decimalPart ] = String(value).split(".").map( (e, i) => {
if (typeof e != "undefined" && !!e) {
return e;
}
});

decimalPart = decimalPart ?? "0";

this._daBigValue = BigInt(integerPart + decimalPart.padEnd(DecimalChanta.precision, "0")
.slice(0, DecimalChanta.precision))
+ BigInt(DecimalChanta.round && decimalPart[DecimalChanta.precision] >= "5");
}

add(value) {
return DecimalChanta.createFromBigInt(this._daBigValue + new DecimalChanta(value)._daBigValue);
}

substract(value) {
return DecimalChanta.createFromBigInt(this._daBigValue - new DecimalChanta(value)._daBigValue);
}

multiply(value) {
return DecimalChanta.roundedDivision(this._daBigValue * new DecimalChanta(value)._daBigValue, DecimalChanta.poweredFactor);
}

divide(value) {
return DecimalChanta.roundedDivision(this._daBigValue * DecimalChanta.poweredFactor, new DecimalChanta(value)._daBigValue);
}


toString() {
const s = this._daBigValue.toString().padStart(DecimalChanta.precision + 1, "0");
return s.slice(0, -DecimalChanta.precision) + "." + s.slice(-DecimalChanta.precision)
.replace(/\.?0+$/, "");
}
}

const proxy = new Proxy(
DecimalChanta,
{
set: function(obj, prop) {
DecimalChanta.poweredFactor = BigInt("1" + "0".repeat(DecimalChanta.precision))
}
}
);
5 changes: 5 additions & 0 deletions lib/b2c6/storers/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
dist
.vscode
.git
package-lock.json
38 changes: 38 additions & 0 deletions lib/b2c6/storers/AbstractStorer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { InstanciatingAbstractClassError, InvokingAbstractClassMethod } from "../errors/Errors";

/**
* AbstracStorer
*
* Provides an abstract interface to implement custom storers.
*
* An storer is a component responsible of handle the arithmetical
* operation over an object.
*
*/
export class AbstractStorer {
constructor() {
if (this.constructor === AbstractStorer) {
throw new InstanciatingAbstractClassError();
}
}

add() {
throw new InvokingAbstractClassMethod("AbstractStorer::add");
}

substract() {
throw new InvokingAbstractClassMethod("AbstractStorer::substract");
}

multiply() {
throw new InvokingAbstractClassMethod("AbstractStorer::multiply");
}

divide() {
throw new InvokingAbstractClassMethod("AbstractStorer::denominator");
}

toString() {
throw new InvokingAbstractClassMethod("AbstractStorer::toString");
}
}
51 changes: 51 additions & 0 deletions lib/b2c6/storers/BigStorer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { AbstractStorer } from './AbstractStorer';
import Big from 'big.js';


/**
* BigStorer
*
* NumberStorer para la librería Big.js
* @link https://github.com/MikeMcl/big.js/
*/
export class BigStorer extends AbstractStorer {

static #fromDecimalChanta(decimal) {
return new Big(decimal.toString());
}

#ammount;

constructor(rawAmmount) {
super();

Big.PE = 32;
Big.NE = -32;
this.#ammount = new Big(rawAmmount);
}

get ammount() {
return this.#ammount;
}

add(value) {
return this.#ammount.plus(value);
}

substract(value) {
return this.#ammount.minus(value);
}

multiply(value) {
return this.#ammount.times(value);
}

divide(value) {
return this.#ammount.div(value);
}

toString() {
return this.ammount.toString();
}

}
49 changes: 49 additions & 0 deletions lib/b2c6/storers/DecimalChantaStorer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { AbstractStorer } from "./AbstractStorer";
import { DecimalChanta } from "../mathematics/DecimalChanta";

/**
* DecimalChantaStorer
*
* Implements a DecimaChanta based storer.
*
* Encapsulates DecimalChanta services.
*
*/
export class DecimalChantaStorer extends AbstractStorer {

#ammount;

/**
* constructor
*
* @param {Mixed} rawAmmount The value to be stored as a DecimalChanta value
*/
constructor(rawAmmount) {
super();
this.#ammount = new DecimalChanta(rawAmmount);
}

get ammount() {
return this.#ammount;
}

add(value) {
return this.#ammount.add(value);
}

substract(value) {
return this.#ammount.substract(value);
}

multiply(value) {
return this.#ammount.multiply(value);
}

divide() {
return this.#ammount.divide(value);
}

toString() {
return this.ammount.toString();
}
}
Loading

0 comments on commit 654b7bb

Please sign in to comment.