frictional

package module
v0.0.0-...-1b4b3b6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 25, 2024 License: MIT Imports: 5 Imported by: 0

README

Frictional

Frictional force is the force generated by two surfaces that contact and slide against each other. The mechanical advantage of a machine is reduced by friction, or in other words, the ratio of output to input is reduced because of friction.

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠉⢦⠤⡄⠀⠀⠀⠀⠀⠀⠀⢻⠺⣆⠈⢆⠘⣷⡀⠘⣆⠀⠀⠀⠀⠈⠑⠰⠀⣿⠀⠿⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⢧⠀⠀⢿⠀⠀⠀⠀⠀⠀⠀⠀⠈⢧⣸⢦⠈⢦⠈⠿⠀⠻⢦⡀⠀⠀⠀⠀⠀⣦⣿⠀⣶⢰⠀⠀
⠀⠀⠰⡂⠀⠀⠀⠀⠀⠀⠀⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣠⡞⠲⣧⠀⠀⠀⠀⠀⠀⠀⠠⠼⢿⠙⣧⡈⢳⡀⠀⢶⣄⠈⠓⠦⠤⠤⠼⠟⠁⠸⠇⣼⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣰⠥⠳⢶⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠁⠀⠀⠀⠀⠂⢀⣀⣀⣤⠤⠤⠤⠘⠃⢸⣿⢦⡈⠲⣄⠙⠻⠶⠀⠀⢠⣤⣶⠟⢀⡴⠁⠀⠀
⠂⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⠀⢀⠻⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⣀⡤⠖⢚⣏⣩⣥⣴⣶⣶⣿⣷⣾⣿⣿⣿⣿⣿⣦⣄⣙⠲⢤⣄⣀⣀⣀⣠⡴⣯⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣤⠏⠙⠛⠀⠀⠀⢀⣠⠖⢋⣁⡤⠞⠋⢀⣠⠴⢚⣩⣤⣴⣿⣿⡿⢿⣭⣥⠤⠒⠒⠂⠀⠂⠀⠀⠈⠛⢿⣿⡏⠙⢛⢿⣿⣿⣯⡈⢳⡉⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⢀⣀⠴⠿⠒⠊⠉⣀⡤⢴⣺⢿⣷⣿⣛⣯⡭⠭⠴⠚⠛⠻⢶⣾⣿⣗⠦⣄⡀⠀⠀⠀⠀⠀⠀⢻⣧⠏⠉⢻⠷⣌⡙⢿⣆⠹⡀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⠴⠚⠉⠀⢀⣀⣤⣖⣫⣵⠞⠋⠀⣼⣿⣿⣿⣅⠀⠀⠀⠀⠀⠀⠀⠙⣟⠻⢿⣶⠭⣷⣦⣄⣀⠀⠀⢨⡟⠀⠀⢸⠀⠀⠙⢮⣿⣧⣧⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢀⣠⠴⠚⠉⠀⢀⣤⠶⣏⡭⠗⠛⣧⠟⠁⠀⠀⣼⣻⠏⠻⣿⣿⣷⣾⣿⣿⣿⣿⣶⡶⢾⣧⣀⣩⣷⣾⣿⣷⢾⣿⣷⡿⠃⠀⠀⣸⣆⣀⣀⣈⣿⡟⣿⠀⢰⠀
⠀⠀⠀⠀⠀⠀⠀⠉⠀⢀⣠⠴⢚⣩⠶⡻⠋⠀⠀⢠⠏⠀⠀⢀⣾⣿⠃⠀⠀⠀⢉⣽⠍⣽⣿⡏⢛⣿⣿⠛⠿⣿⣟⠹⣿⡯⠴⠚⠉⠉⠀⠀⢀⣴⣿⣿⡿⣿⣿⣿⡇⠿⡀⡸⠀
⠀⠀⠀⠀⠀⠀⣠⣴⣞⣉⡴⠚⡽⢡⠞⠁⠀⠀⡰⠃⠀⠀⣠⣾⠟⠁⠀⢦⡀⠀⠀⠸⣿⣿⡀⠻⠛⢰⣾⡀⠀⡈⢿⢄⣻⣽⡄⠀⠀⠀⢠⣴⣿⣿⣿⠿⣿⣿⣿⣿⣿⠀⣿⠃⠀
⠀⠀⣀⡤⣶⡯⢻⢟⡿⠃⣰⣾⣷⠋⠀⠀⢀⠞⠁⠀⣠⣾⠟⠁⠀⠀⢰⡿⢿⡄⠀⠀⠀⠙⠹⡟⠛⠉⣍⣭⣴⣛⣴⣾⠟⠋⠁⠀⠀⠀⢸⡟⢿⢋⡿⢀⣼⣿⣿⣿⠇⠀⡇⠀⠀
⠀⠈⢰⠞⠁⣴⠿⠋⢀⣾⠟⡱⠃⠀⠀⠀⠀⠀⣠⡾⠋⠀⠀⠀⠀⠀⡿⠀⠀⠀⠀⠀⠀⠀⢻⠇⠀⠀⠀⠈⠙⣿⣿⠅⠀⠀⠀⠀⠀⣀⣴⣿⣿⣿⣷⣾⠟⢋⡽⠋⠀⡴⠃⠀⠀
⠀⡰⢋⡠⠞⠁⠀⡴⡻⢋⡜⠁⠀⢀⠀⢀⡴⣿⢏⡇⠀⠀⠀⠀⠀⠰⠃⠀⠀⠀⠀⠀⠀⠀⠏⠀⠀⠀⠀⠀⠀⠀⠉⠀⠀⠀⢠⣘⣿⣿⣿⣿⡿⠟⠉⣿⠖⠋⢀⡤⠚⠀⠀⠀⠀
⡾⠗⠉⠀⠀⠀⠀⡼⢁⠎⠀⠀⢠⠞⣠⢻⡟⠁⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⡇⣿⣿⣿⣿⡐⠀⢸⣃⠤⠖⠋⠀⠀⠀⠀⠀⠀
⠀⠀⠀⢀⣤⢃⣼⠁⡼⠀⠀⢀⡟⣼⠁⢸⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠟⠃⠃⠀⠀⠹⡇⠀⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣀⠠⠶⢛⣷⣿⠃⢰⡇⠀⠀⣸⢠⣿⡀⢸⡀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⡼⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣀⣴⠟⢩⡟⠀⡿⡇⠀⠀⡇⣾⣿⣷⣀⣧⠀⠘⡆⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣀⣀⣀⣀⣹⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠟⠁⢠⣿⠇⡼⠁⣷⠀⢰⣷⣿⣿⣿⣿⠻⢧⡀⠹⡄⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣅⢀⣠⠤⠖⡿⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⢀⣿⣿⣰⠃⠀⣿⠀⢸⣿⣿⣿⣿⣿⡇⠀⣽⣦⠘⠂⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⠏⠀⢀⡞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⡞⡿⣿⠇⠀⠀⣿⠀⢸⣿⣿⣿⣿⣿⣿⡾⠛⠁⠀⣠⠜⠂⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣴⡖⠒⠛⠛⠲⢬⣥⣴⢠⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢸⢉⠁⡇⠀⣠⣼⣿⠀⢸⡿⠿⠛⢻⣿⣿⣿⣤⢖⢿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡘⠛⠻⠿⣿⣿⣯⣿⣿⣶⣾⠟⡱⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣄⡏⢸⢸⠁⢀⣾⠉⣿⡀⠀⡇⠀⠀⠸⣿⣿⣿⣿⣿⣿⣿⣌⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣶⠀⠀⠀⠈⠉⠉⠉⠉⢱⡾⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠙⢾⣸⢸⡞⠀⢰⣿⣧⡀⢻⡀⠀⠀⢻⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣶⣤⣀⣀⣀⣀⣤⡾⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠙⠿⣦⡀⢰⡟⠉⠙⢮⣿⣀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⡀⠀⠐⠀⠀⠀⠀⠀⠀⠀⣹⣿⡿⠿⣏⢩⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠈⠿⣿⡥⣤⣴⠞⠉⠉⠁⣠⢿⣿⣿⣿⣿⣿⣿⣛⣿⡿⠻⡿⣿⣶⣄⣧⠀⠀⠀⠀⠀⠚⠋⠁⠀⠀⢹⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠈⠛⢿⣇⠀⣠⡶⠛⠁⠀⣻⡿⠟⠋⠀⠀⣿⡛⠀⣠⢧⠸⡿⣏⡟⠷⣄⡀⠀⠀⠀⠀⠀⠀⣠⡾⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣀⢠⡀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣵⣶⣤⣶⣿⣯⠀⠰⠃⠀⠀⠈⢧⢠⠏⠨⢿⡱⠘⣿⡀⠈⠙⠓⠶⠶⠒⠚⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣛⣻⣿⣷⣄⡀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⣿⣥⣿⣷⣦⡴⠒⠛⢏⠀⠀⠀⠙⠲⢬⣹⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠉⠉⠛⢿⣿⣖⠦⣄⡀⠀⠀⠙⢿⣿⣿⣿⣿⣿⢁⣿⣀⣠⠀⣾⡧⠀⠀⠀⠀⠀⠈⠉⠙⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⠃⢀⣠⡤⠤⢤⣄⡀⠀⠀⠀⢠⣦⠄
⠀⠀⠀⠀⠀⠀⠙⢮⡳⣄⠙⠢⣀⠀⠀⠙⠿⣿⣿⣿⢹⡟⠃⠀⠀⠸⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⡀⠀⠀⠀⠀⠉⠛⠀⠛⠋⠀⠀
⠉⠑⠒⠿⣶⣦⣀⠈⢳⣌⠳⣄⠈⠳⣄⠀⠀⠘⢿⣿⡾⠀⠀⠀⠀⠀⡷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠉⠙⢿⣾⣿⣆⡈⠳⣤⡉⣦⡀⠀⠈⢿⠇⠀⠀⠸⠁⡜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠋⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

Provides a set of types and functions to calculate sales subtotals, including taxes and discounts. It is designed to be flexible and extensible, allowing developers to define their own rules for calculating taxes and discounts.

Features

  • Minimal dependencies: Only alpacadecimal as backend for calculations.

  • Decimal Arithmetic: The Frictional module provides a set of types and functions for decimal arithmetic, including Decimal types for representing decimal values and functions for adding, subtracting, multiplying, and dividing decimal values.

  • Uses custom Visitor pattern to allow developers to define their own rules for calculating taxes, discounts and other ways of manipulate the buffer.

Usage

To use the Frictional module, you need to import it into your Go code:

$ go get github.com/profe-ajedrez/baggins
import "github.com/profe-ajedrez/baggins"

Imagine the following case

1 You have the sale of a product with a unit value excluding taxes of $1044.543103448276

2 You will sell 35157 units

3 You will apply a 10% discount

4 You will also apply a discount of $100 to the total without sales tax

5 You must apply a percentage tax of 16%

6 You must apply a tax in the amount of 0.04 per 100 units for packaging.

This case can be modeled as follows:

func main() {
	// define entry values
	unitValue := udfs("1044.543103448276")
	qty := udfs("35157")
	percDiscount := udfs("10")
	amountLineDiscount := udfs("100")
	percTax := udfs("16")
	amountLineTax := qty.Div(HundredValue).Round(0).Mul(udfs("0.04"))

	// define the buffer holder
	calc := NewFromUnitValue(unitValue)

	// define the visitors
	qtyVisitor := WithQTY(qty)
	percDiscVisitor := NewPercentualDiscount(percDiscount)
	amountDiscVisitor := NewAmountDiscount(amountLineDiscount)
	percTaxVisitor := NewUnbufferedPercTax(percTax)
	amountTaxVisitor := NewUnbufferedAmountTax(amountLineTax)

	// make the visitors visite the buffer holder
	calc.Bind(qtyVisitor)
	calc.Bind(percDiscVisitor)
	calc.Bind(amountDiscVisitor)
	calc.Bind(percTaxVisitor)
	calc.Bind(amountTaxVisitor)

	net = calc.Snapshot()

	calc.Add(percTaxVisitor.Amount())
	calc.Add(amountTaxVisitor.Amount())

	brute = calc.Snapshot()

	totalTaxes = percTaxVisitor.Amount().Add(amountTaxVisitor.Amount())
	totalDiscounts = percDiscVisitor.Amount().Add(amountDiscVisitor.Amount())

	fmt.Printf("net: %v", net)
	fmt.Printf("brute: %v", brute)
	fmt.Printf("totalTaxes: %v", totalTaxes)
	fmt.Printf("totalDiscounts: %v", totalDiscounts)

	// Output:
	// net:            udfs("33050601.6991379353988"),
	// brute:          udfs("38338712.051000005062608"),
	// totalTaxes:     udfs("5288110.351862069663808"),
	// totalDiscounts: udfs("3672400.1887931039332"),
}


func udfs(d string) alpacadecimal.Decimal {
	return unsafeDecFromStr(d)
}

func unsafeDecFromStr(d string) alpacadecimal.Decimal {
	dec, _ := alpacadecimal.NewFromString(d)
	return dec
}


See the examples folder for more usage examples.

Warning

Most of the visitors provided by this library do not perform any validation. For example, Tax and its derivatives do not verify that the ratio is greater than zero, which could cause a panic due to division by zero. This is a conscious decision, we leave it to the user to worry about whether the values ​​are valid.

Documentation

Overview

Package frictional lets perform sales calculations considering rules as discounts and taxes.

Index

Examples

Constants

View Source
const (
	// Percentual represents a percentage value
	Percentual = ValueType(0)
	// Amount represents an absolute amount value.
	Amount = ValueType(1)
)

Variables

View Source
var HundredValue = alpacadecimal.NewFromInt(hundred)

HundredValue returns an alpacadecimal.Decimal representing the value 100.

View Source
var InverseValue = alpacadecimal.NewFromInt(minusOne)

InverseValue is an alpacadecimal.Decimal representing the value -1.

One is an alpacadecimal.Decimal representing the value 1.

Functions

func Hundred

func Hundred() alpacadecimal.Decimal

func Inverse

func Inverse() alpacadecimal.Decimal

Inverse returns an alpacadecimal.Decimal representing the value -1. Allocates a new value

func NewInvalidScaleErr

func NewInvalidScaleErr[T constraints.Integer](scale T) error

func NewNegativeDiscountAmountErr

func NewNegativeDiscountAmountErr(ratio alpacadecimal.Decimal) error

func NewNegativeDiscountRatioErr

func NewNegativeDiscountRatioErr(ratio alpacadecimal.Decimal) error

func NewNegativeTaxErr

func NewNegativeTaxErr(ratio alpacadecimal.Decimal) error

func NewNotFromUnitValue

func NewNotFromUnitValue() error

func NewOver100DiscountAmountErr

func NewOver100DiscountAmountErr(ratio alpacadecimal.Decimal) error

func NewOver100DiscountRatioErr

func NewOver100DiscountRatioErr(ratio alpacadecimal.Decimal) error

func NewOverTaxableTaxErr

func NewOverTaxableTaxErr(ratio alpacadecimal.Decimal) error

func PowerOfTen

func PowerOfTen(n int) alpacadecimal.Decimal

PowerOfTen returns an alpacadecimal.Decimal representing the value of 10 raised to the power of n. If n is 1, it returns 10. If n is 0, it returns 1. Otherwise, it returns 10 raised to the power of n. allocates one new value

func Zero

func Zero() alpacadecimal.Decimal

Zero returns an alpacadecimal.Decimal representing the value 0. Allocates a new value

Types

type AmountDiscount

type AmountDiscount struct {
	Discount
}

AmountDiscount represents a discount that is applied as a fixed amount. It embeds the Discount struct, which contains the ratio and amount fields.

func NewAmountDiscount

func NewAmountDiscount(amount alpacadecimal.Decimal) *AmountDiscount

NewAmountDiscount creates a new AmountDiscount instance with the given fixed amount. The amount represents the fixed discount to be applied.

func (*AmountDiscount) Do

func (pd *AmountDiscount) Do(b Frictional)

Do applies the fixed amount discount to the given Frictional value. If the Frictional value's buffer is zero, the discount ratio is set to zero. This implemenetation doesnt check for negative discounts

type AmountTax

type AmountTax struct {
	Tax
}

AmountTax is a Tax that applies a fixed amount to the Frictional value. It wraps over the Tax struct and implements the Do method to calculate the tax amount.

func NewAmountTax

func NewAmountTax(amount alpacadecimal.Decimal) *AmountTax

func (*AmountTax) Do

func (pt *AmountTax) Do(b Frictional)

type AmountUndiscount

type AmountUndiscount struct {
	*Discount
}

func NewAmountUnDiscount

func NewAmountUnDiscount(amount alpacadecimal.Decimal) *AmountUndiscount

func (*AmountUndiscount) Do

func (u *AmountUndiscount) Do(b Frictional)

type AmountUntax

type AmountUntax struct {
	Tax
}

func NewAmountUnTax

func NewAmountUnTax(amount alpacadecimal.Decimal) *AmountUntax

func (*AmountUntax) Do

func (pu *AmountUntax) Do(b Frictional)

type Arithmetic

type Arithmetic interface {
	// Add adds the given decimal value
	Add(alpacadecimal.Decimal)
	// Sub subtracts the given decimal value
	Sub(alpacadecimal.Decimal)
	// Mul multiplies the buffer by the given value
	Mul(alpacadecimal.Decimal)
	// Div divides the Frictional by the given decimal value.
	Div(alpacadecimal.Decimal)
}

Arithmetic is an interface that defines arithmetic operations that can be performed on a Frictional.

type DefaultFrictional

type DefaultFrictional struct {
	// contains filtered or unexported fields
}

DefaultFrictional is a concrete implementation of the Frictional It holds the current value of the Frictional as an alpacadecimal.Decimal. Is used as a common default implementation of the Frictional interface. Instead of using it directly you should use FromUnitValue or FromBrute as needed. Also, you could implement your own Frictional type by embedding this struct, to get the basic functionality

func (*DefaultFrictional) Add

Add adds the given decimal value to the Frictional.

func (*DefaultFrictional) Bind

func (b *DefaultFrictional) Bind(e Visitor)

Bind binds the given Visitor to the defaultFrictional instance. The Visitor will be invoked with the defaultFrictional instance when the Do method is called on the Visitor.

func (*DefaultFrictional) Div

Div divides the Frictional by the given decimal value. This could trigger a division by zero panic because this implementation doesn't check if the given value is zero or not.

func (*DefaultFrictional) Mul

Mul multiplies the Frictional by the given decimal value.

func (*DefaultFrictional) Reset

func (b *DefaultFrictional) Reset()

Reset sets the Frictional to zero.

func (*DefaultFrictional) Restore

func (b *DefaultFrictional) Restore(s alpacadecimal.Decimal)

Restore sets the value of the Frictional instance to the provided decimal value.

func (*DefaultFrictional) Snapshot

func (b *DefaultFrictional) Snapshot() alpacadecimal.Decimal

Snapshot returns the current value of the Frictional.

func (*DefaultFrictional) String

func (b *DefaultFrictional) String() string

String returns a string representation of the Frictional value.

func (*DefaultFrictional) Sub

Sub subtracts the given decimal value from the Frictional.

func (*DefaultFrictional) Value

Value returns the current value of the Frictional.

type Discount

type Discount struct {
	// contains filtered or unexported fields
}

Discount represents a discount that can be applied to a Frictional value. The ratio field represents the percentage discount, and the amount field represents the fixed amount discount.

func (*Discount) Amount

func (d *Discount) Amount() alpacadecimal.Decimal

Amount returns the fixed amount discount.

func (*Discount) Ratio

func (d *Discount) Ratio() alpacadecimal.Decimal

Ratio returns the ratio of the discount.

func (*Discount) String

func (d *Discount) String() string

String returns a string representation of the Discount, including the ratio and amount.

type DiscountHandler

type DiscountHandler struct {
	// contains filtered or unexported fields
}

func NewDiscountHandler

func NewDiscountHandler() *DiscountHandler

func (*DiscountHandler) WithAmountDiscount

func (t *DiscountHandler) WithAmountDiscount(value alpacadecimal.Decimal)

func (*DiscountHandler) WithPercentualDiscount

func (t *DiscountHandler) WithPercentualDiscount(value alpacadecimal.Decimal)

type DiscountHandlerFromUnitValue

type DiscountHandlerFromUnitValue struct {
	*DiscountHandler
}

func NewDiscHandlerFromUnitValue

func NewDiscHandlerFromUnitValue() *DiscountHandlerFromUnitValue

func (*DiscountHandlerFromUnitValue) Discountable

func (*DiscountHandlerFromUnitValue) Do

func (*DiscountHandlerFromUnitValue) TotalAmount

func (*DiscountHandlerFromUnitValue) TotalRatio

type Frictional

type Frictional interface {

	// Bind allows a Visitor to interact with the Frictional instance.
	Bind(Visitor)
	// Returns a string representation of the Frictional instance, including the current value of the buffer.
	String() string

	// Value returns the current value of the Frictional.
	Value() alpacadecimal.Decimal

	// Reset sets the buffer to zero.
	Reset()
	// Snapshot returns a copy of the current buffer value.
	Snapshot() alpacadecimal.Decimal
	// Restore sets the buffer to the provided decimal value.
	Restore(alpacadecimal.Decimal)

	Arithmetic
	// contains filtered or unexported methods
}

Frictional provides methods to interact with Visitors which updates its internal value to calculate a value appliying rules as discounts or taxes If needed you can implement your own Frictional type!

type FromBrute

type FromBrute struct {
	*DefaultFrictional
}

FromBrute is a thing able to be converted from the brute subtotal removing elements as discounts and taxes through defined binded visitors

Example
package main

import (
	"fmt"

	"github.com/alpacahq/alpacadecimal"
	"github.com/profe-ajedrez/frictional"
)

func udfs(s string) alpacadecimal.Decimal {
	d, _ := alpacadecimal.NewFromString(s)
	return d
}

func main() {
	// Create a new FromBrute instance with a default buffer
	bg := frictional.NewFromBruteDefault().WithBrute(udfs("1619.1"))

	// Create a SnapshotVisitor to capture the brute value
	brute := &frictional.SnapshotVisitor{}

	// Create a SnapshotVisitor to capture the net value
	net := &frictional.SnapshotVisitor{}

	// Create a SnapshotVisitor to capture the net value with discount
	netWD := &frictional.SnapshotVisitor{}

	// Create a UnitValue instance with a quantity of 3
	unitValue := frictional.NewUnitValue(udfs("3"))

	// Bind the visitors to the FromBrute instance
	bg.Bind(brute)
	bg.Bind(frictional.NewPercentualUnTax(udfs("16")))
	bg.Bind(net)
	bg.Bind(frictional.NewPercentualUnDiscount(udfs("0")))
	bg.Bind(netWD)
	bg.Bind(unitValue)
	bg.Bind(frictional.NewRound(12))

	netRounded := net.Get().Round(6)

	// Round the unitValue to 12 decimal places
	unitValue.Round(12)

	// Print the results
	fmt.Printf("Brute value: %v\nNet value: %v\nNet rounded: %v\nNet value with discount: %v\nUnit value: %v\nBuffer value: %v", brute.Get().String(), net.Get().String(), netRounded.String(), netWD.Get().String(), unitValue.Get().String(), bg.Value().String())
}
Output:

Brute value: 1619.1
Net value: 1395.7758620689655172
Net rounded: 1395.775862
Net value with discount: 1395.7758620689655172
Unit value: 465.258620689655
Buffer value: 465.258620689655

func NewFromBrute

func NewFromBrute(brute alpacadecimal.Decimal) *FromBrute

NewFromBrute returns a new instance of FromBrute with the provided brute value set as the Frictional.

func NewFromBruteDefault

func NewFromBruteDefault() *FromBrute

NewFromBruteDefault returns a new instance of FromBrute with a zero-valued.

func (*FromBrute) WithBrute

func (f *FromBrute) WithBrute(brute alpacadecimal.Decimal) *FromBrute

WithBrute sets the value of the FromBrute instance to the provided brute value and returns the updated instance.

type FromUnitValue

type FromUnitValue struct {
	*DefaultFrictional
}

FromUnitValue wraps DefaultDecimal and implements the Frictional interface. Should be used when you want to perform calculations over a unit value to get a subtotal

code block:

package main

import (

	"fmt"

	"github.com/alpacahq/alpacadecimal"
	"github.com/profe-ajedrez/frictional"

)

func udfs(d string) alpacadecimal.Decimal {
	return unsafeDecFromStr(d)
}

func unsafeDecFromStr(d string) alpacadecimal.Decimal {
	dec, _ := alpacadecimal.NewFromString(d)
	return dec
}

func main() {
	// Define the values which will be used in the calculations

	unitValue := udfs("1044.543103448276")
	qty := udfs("35157")
	percDiscount := udfs("10")
	amountLineDiscount := udfs("100")
	percTax := udfs("16")
	amountLineTax := qty.Div(frictional.HundredValue).Round(0).Mul(udfs("0.04"))

	// instance the calculator as a new FromUnitValue
	calc := frictional.NewFromUnitValue(unitValue)

	// define the visitors to be used in the calculations
	qtyVisitor := frictional.WithQTY(qty)
	percDiscVisitor := frictional.NewPercentualDiscount(percDiscount)
	amountDiscVisitor := frictional.NewAmountDiscount(amountLineDiscount)
	percTaxVisitor := frictional.NewUnbufferedPercTax(percTax)
	amountTaxVisitor := frictional.NewUnbufferedAmountTax(amountLineTax)

	// bind the visitors to the calculator
	calc.Bind(qtyVisitor)
	calc.Bind(percDiscVisitor)
	calc.Bind(amountDiscVisitor)
	calc.Bind(percTaxVisitor)
	calc.Bind(amountTaxVisitor)

	// get the net value from the snapshot visitor
	net := calc.Snapshot()

	calc.Add(percTaxVisitor.Amount())
	calc.Add(amountTaxVisitor.Amount())

	// get the brute value from the snapshot visitor
	brute := calc.Snapshot()

	// get the total taxes amount from the percTaxVisitor and amountTaxVisitor visitors
	totalTaxes := percTaxVisitor.Amount().Add(amountTaxVisitor.Amount())

	// get the total discount amount from the percDiscVisitor and amountDiscVisitor visitors
	totalDiscounts := percDiscVisitor.Amount().Add(amountDiscVisitor.Amount())

	fmt.Println("net: ", net.String())
	fmt.Println("brute: ", brute.String())
	fmt.Println("total discounts: ", totalDiscounts.String())
	fmt.Println("total taxes: ", totalTaxes.String())
}

Output:

net: 33050601.6991379353988
brute: 38338712.051000005062608
total discounts: 5288110.351862069663808
total taxes: 3672400.1887931039332

func NewFromUnitValue

func NewFromUnitValue(entry alpacadecimal.Decimal) *FromUnitValue

NewFromUnitValue returns a new instance of FromUnitValue with the provided entry value

func NewFromUnitValueDefault

func NewFromUnitValueDefault() *FromUnitValue

NewFromUnitValueDefault returns a new instance of FromUnitValue with a zero-valued.

type PercTax

type PercTax struct {
	Tax
}

PercTax is a percentual based tax visitor. Wraps over Tax structure and implements the Do method.

func NewPercTax

func NewPercTax(ratio alpacadecimal.Decimal) *PercTax

NewPercTax creates a new PercTax instance with the given tax ratio. The PercTax struct wraps over the Tax struct and implements the Do method to calculate the tax amount based on the given ratio.

func (*PercTax) Do

func (pt *PercTax) Do(b Frictional)

Do applies the percentual tax to the Frictional instance's value and updates the Frictional instance's buffer directly. It calculates the tax amount based on the Frictional instance's value and the tax ratio, and adds the tax amount to the Frictional instance's buffer. It also stores the calculated tax amount and the taxable value in the PercTax struct. This implemenetation doesnt check for negative taxes

type PercentualDiscount

type PercentualDiscount struct {
	Discount
}

PercentualDiscount represents a discount that is applied as a percentage of the Frictional value. It embeds the Discount struct, which contains the ratio and amount fields.

func NewPercentualDiscount

func NewPercentualDiscount(ratio alpacadecimal.Decimal) *PercentualDiscount

NewPercentualDiscount creates a new PercentualDiscount instance with the given ratio. The ratio represents the percentage discount to be applied.

func (*PercentualDiscount) Do

func (pd *PercentualDiscount) Do(b Frictional)

Do applies the percentual discount to the given Frictional value. It calculates the discount amount by multiplying the Frictional value's buffer by the discount ratio, and then dividing by 100 to get the percentage. The calculated discount amount is then subtracted from the Frictional value. This implemenetation doesnt check for negative discounts

type PercentualUndiscount

type PercentualUndiscount struct {
	*Discount
}

func NewPercentualUnDiscount

func NewPercentualUnDiscount(ratio alpacadecimal.Decimal) *PercentualUndiscount

func (*PercentualUndiscount) Do

type PercentualUntax

type PercentualUntax struct {
	Tax
}

func NewPercentualUnTax

func NewPercentualUnTax(ratio alpacadecimal.Decimal) *PercentualUntax

func (*PercentualUntax) Do

func (pu *PercentualUntax) Do(b Frictional)

type Qty

type Qty struct {
	// contains filtered or unexported fields
}

func WithQTY

func WithQTY(qty alpacadecimal.Decimal) Qty

func (Qty) Do

func (q Qty) Do(b Frictional)

type Round

type Round struct {
	// contains filtered or unexported fields
}

Round is a visitor which performs a rounding operation with a specified scale. rounding usually implies a rescale operation, which is costly, use with care.

func NewRound

func NewRound(scale int32) Round

NewRound creates a new Round visitor with the specified scale. The Round visitor can be used to perform a rounding operation on a Frictional value. The scale parameter determines the number of decimal places to round to.

func (Round) Do

func (r Round) Do(b Frictional)

Do applies a rounding operation to the given Frictional value, using the scale specified when the Round visitor was created. This effectively rescales the Frictional value to the desired number of decimal places.

type SnapshotVisitor

type SnapshotVisitor struct {
	// contains filtered or unexported fields
}

SnapshotVisitor lets take a snapshot at the current value of a Frictional

func NewSnapshot

func NewSnapshot() *SnapshotVisitor

func (*SnapshotVisitor) Do

func (s *SnapshotVisitor) Do(b Frictional)

func (*SnapshotVisitor) Get

type Tax

type Tax struct {
	// contains filtered or unexported fields
}

Tax struct holds the components necessary for tax calculation on a Frictional value. It includes the tax ratio, the tax amount, and the taxable base amount. This struct is typically used as a visitor to apply tax calculations to a Frictional value.

func (*Tax) Amount

func (pt *Tax) Amount() alpacadecimal.Decimal

Amount returns the amount of tax calculated for the Frictional value.

func (*Tax) Ratio

func (pt *Tax) Ratio() alpacadecimal.Decimal

Ratio returns the tax ratio for the Frictional value.

func (*Tax) Taxable

func (pt *Tax) Taxable() alpacadecimal.Decimal

Taxable returns the taxable value for the Frictional value that this Tax was applied to.

type TaxHandler

type TaxHandler struct {
	// contains filtered or unexported fields
}

TaxHandler lets apply many taxes over the save Frictional value

Example
package main

import (
	"fmt"

	"github.com/alpacahq/alpacadecimal"
	"github.com/profe-ajedrez/frictional"
)

func udfs(s string) alpacadecimal.Decimal {
	d, _ := alpacadecimal.NewFromString(s)
	return d
}

func main() {
	entry := udfs("75.25")
	b := frictional.NewFromUnitValue(entry)

	b.Bind(frictional.WithQTY(udfs("1.5")))

	th := frictional.NewTaxHandlerFromUnitValue()
	th.WithPercentualTax(udfs("12.5"))

	net := frictional.SnapshotVisitor{}
	net.Do(b)

	th.Do(b)

	brute := frictional.SnapshotVisitor{}
	brute.Do(b)

	fmt.Printf("Entry value: %v\n", entry)
	fmt.Printf("Quantity: %v\n", udfs("1.5"))
	fmt.Printf("Tax rate: %v%%\n", udfs("12.5"))
	fmt.Printf("Net value (before tax): %v\n", net.Get())
	fmt.Printf("Brute value (after tax): %v\n", brute.Get())
	fmt.Printf("Total tax ratio: %v\n", th.TotalRatio())
	fmt.Printf("Total tax amount: %v\n", th.TotalAmount())
	fmt.Printf("Taxable amount: %v\n", th.Taxable())

}
Output:

Entry value: 75.25
Quantity: 1.5
Tax rate: 12.5%
Net value (before tax): 112.875
Brute value (after tax): 126.984375
Total tax ratio: 12.5
Total tax amount: 14.109375
Taxable amount: 112.875

func NewTaxHandler

func NewTaxHandler() *TaxHandler

func (*TaxHandler) WithAmountTax

func (t *TaxHandler) WithAmountTax(value alpacadecimal.Decimal)

func (*TaxHandler) WithPercentualTax

func (t *TaxHandler) WithPercentualTax(value alpacadecimal.Decimal)

type TaxHandlerFromUnitValue

type TaxHandlerFromUnitValue struct {
	*TaxHandler
}
Example

ExampleTaxHandlerFromUnitValue demonstrates the usage of the TaxHandlerFromUnitValue type. It creates a new Frictional instance with an initial value of 232.5 and a quantity of 3, then applies a 16% tax rate using the TaxHandlerFromUnitValue. The net value before tax, the brute value after tax, the total ratio, and the taxable amount are printed.

package main

import (
	"fmt"

	"github.com/alpacahq/alpacadecimal"
	"github.com/profe-ajedrez/frictional"
)

func udfs(s string) alpacadecimal.Decimal {
	d, _ := alpacadecimal.NewFromString(s)
	return d
}

func main() {
	// Create a new FromUnitValue instance with an initial value of 232.5
	entry := udfs("232.5")
	b := frictional.NewFromUnitValue(entry)

	// Bind a visitor to apply a quantity of 3
	b.Bind(frictional.WithQTY(udfs("3")))

	// Create a new TaxHandlerFromUnitValue instance
	th := frictional.NewTaxHandlerFromUnitValue()
	th.WithPercentualTax(udfs("16")) // Set the tax rate to 16%

	// Snapshot the net value before applying tax
	net := frictional.SnapshotVisitor{}
	net.Do(b)

	// Apply the tax handler to the Frictional instance
	th.Do(b)

	// Snapshot the brute value after applying tax
	brute := frictional.SnapshotVisitor{}
	brute.Do(b)

	// Print the results
	fmt.Printf("Net value (before tax): %v\nBrute value (after tax): %v\nTotal ratio: %v\nTotal amount: %v\nTaxable amount: %v", net.Get().String(), brute.Get().String(), th.TotalRatio().String(), th.TotalAmount().String(), th.Taxable().String())
}
Output:

Net value (before tax): 697.5
Brute value (after tax): 809.1
Total ratio: 16
Total amount: 111.6
Taxable amount: 697.5

func NewTaxHandlerFromUnitValue

func NewTaxHandlerFromUnitValue() *TaxHandlerFromUnitValue

func (*TaxHandlerFromUnitValue) Do

func (*TaxHandlerFromUnitValue) Taxable

func (*TaxHandlerFromUnitValue) TotalAmount

func (*TaxHandlerFromUnitValue) TotalRatio

type UnbufferedAmountTax

type UnbufferedAmountTax struct {
	Tax
}

UnbufferedAmountTax is a Tax that applies a fixed amount to the Frictional value. It wraps over the Tax struct and implements the Do method to calculate the tax amount, but does not modify the Frictional instance's buffer directly.

func NewUnbufferedAmountTax

func NewUnbufferedAmountTax(amount alpacadecimal.Decimal) *UnbufferedAmountTax

func (*UnbufferedAmountTax) Do

func (pt *UnbufferedAmountTax) Do(b Frictional)

Do applies the fixed amount tax to the Frictional instance's value. It does not modify the Frictional instance's buffer directly. This implementation calculates the tax ratio based on the fixed amount and the Frictional instance's value. This implemenetation doesnt check for negative taxes

type UnbufferedPercTax

type UnbufferedPercTax struct {
	Tax
}

UnbufferedPercTax is a Visitor that applies a percentual tax to the Frictional instance's value. It does not modify the Frictional instance's buffer directly.

func NewUnbufferedPercTax

func NewUnbufferedPercTax(ratio alpacadecimal.Decimal) *UnbufferedPercTax

func (*UnbufferedPercTax) Do

func (pt *UnbufferedPercTax) Do(b Frictional)

Do applies the percentual tax to the Frictional instance's value. It does not modify the Frictional instance's buffer directly. This implemenetation doesnt check for negative taxes

type UnitValue

type UnitValue struct {
	// contains filtered or unexported fields
}

func NewUnitValue

func NewUnitValue(qty alpacadecimal.Decimal) *UnitValue

func (*UnitValue) Do

func (q *UnitValue) Do(b Frictional)

func (*UnitValue) Get

func (q *UnitValue) Get() alpacadecimal.Decimal

func (*UnitValue) Round

func (q *UnitValue) Round(sc int32)

type ValueType

type ValueType int8

ValueType is an enum that represents wether a thing is a percentual or an amount. Percentual and Amount are the two possible ValueType values, representing whether a value is a percentage or an absolute amount.

The ten, hundred, one, minusOne, and zero constants represent common numeric values used in the package.

The percentualValue and amountValue strings represent the string representations of the Percentual and Amount ValueType values, respectively.

func NewValueTypeFromInt

func NewValueTypeFromInt(v int) ValueType

NewValueTypeFromInt returns a ValueType based on the given integer. If the integer is 1, it returns Amount. Otherwise, it returns Percentual.

func NewValueTypeFromString

func NewValueTypeFromString(s string) ValueType

NewValueTypeFromString returns a ValueType based on the given string. If the string is "1", it returns Amount. Otherwise, it returns Percentual.

func (ValueType) IsAmount

func (v ValueType) IsAmount() bool

IsAmount returns true if the ValueType is Amount, false otherwise.

func (ValueType) IsPercentual

func (v ValueType) IsPercentual() bool

IsPercentual returns true if the ValueType is Percentual, false otherwise.

func (ValueType) String

func (v ValueType) String() string

String returns the string representation of ValueType

type Visitor

type Visitor interface {
	Do(Frictional)
}

Visitor is an interface that defines a method for performing an operation on a Frictional. The Do method takes a Frictional as an argument and performs some operation on it.

Directories

Path Synopsis
examples
frombrute command
fromunitvalue command
mockfrictional
Package mockfrictional is a mock implementation of the Frictional interface.
Package mockfrictional is a mock implementation of the Frictional interface.
tax_handler command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL