1
0

Write proper readme

This commit is contained in:
Tim Kächele 2021-03-07 22:20:11 +01:00
parent 5719237879
commit 3e64b35558

141
README.md
View File

@ -1,28 +1,138 @@
# PlanetExpress
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/planet_express`. To experiment with that code, run `bin/console` for an interactive prompt.
TODO: Delete this and the text above, and describe your gem
Planet Express is your little helper to calculate possible discounts for your
shipments based on a given rule set and an available discount budget.
## Installation
Add this line to your application's Gemfile:
Get the code from github and run `bundle install`
```ruby
gem 'planet_express'
```
Afterwards you are ready to rumble.
And then execute:
$ bundle install
Or install it yourself as:
$ gem install planet_express
I recommend ruby 2.6.6 or MRI 2.7 to run the code. Other ruby versions
should work as well, but are not officially supported.
## Usage
TODO: Write usage instructions here
The input file has to adhere to the following format:
```
# ISO8601Date PackageSize Provider
2015-02-01 S PR
```
Now that you have an input file like that you can run the processing with
the following rake task:
```sh
$ bundle exec rake 'process[path/to/input_file.txt]'
# 2015-02-01 S MR 1.50 0.50
# 2015-02-02 S MR 1.50 0.50
# 2015-02-03 L LP 6.90 -
# 2015-02-05 S LP 1.50 -
# 2015-02-06 S MR 1.50 0.50
# 2015-02-06 L LP 6.90 -
# 2015-02-07 L MR 4.00 -
# 2015-02-08 M MR 3.00 -
# 2015-02-09 L LP 0.00 6.90
# 2015-02-10 L LP 6.90 -
# 2015-02-10 S MR 1.50 0.50
# 2015-02-10 S MR 1.50 0.50
# 2015-02-11 L LP 6.90 -
# 2015-02-12 M MR 3.00 -
# 2015-02-13 M LP 4.90 -
# 2015-02-15 S MR 1.50 0.50
# 2015-02-17 L LP 6.90 -
# 2015-02-17 S MR 1.90 0.10
# 2015-02-24 L LP 6.90 -
# 2015-02-29 CUSPS IGNORED
# 2015-03-01 S MR 1.50 0.50
```
## Architecture
The system is divided into four big groups:
- **Discounts** - provides a class to represent discounts as well as a budget
to keep track of the discount budgets for a given month
- **Shipments** - Basic representation of a shipment as in "an order that will be shipped"
- **ShippingOptions** - Struct and repository to represent providers and their shipping options
- **Rules** - contains all the logic for discount rules including a methods to apply
discounts to shipments
### Discounts
The discount class represents a discount that originated from a rule and contains
the monetary amount as well as the rule that was responsible for applying the discount.
Use the `DiscountBudgetForMonthRepository` to get the discount budget for a given month.
### Shipments
Shipments are the input for all calculation and have a date and a reference
to a shipping option. They also keep track of their applied discounts.
**Important:** There's a distinction between a valid shipment (one that was parsed correctly)
and an invalid shipment. To not make you constantly check whether you handle
a valid shipment or an invalid one, you can use the `if_valid` helper.
```ruby
shipment.if_valid do |valid_shipment|
# code that is only executed in case you have a valid shipment on hand
end
```
The package also includes a `ShipmentReader` that adheres to a simple enumerable
interface in order to decouple the IO/parsing from the remaining processing. If
you don't need it you can replace all instances of a `ShipmentReader` with a simple
array.
To provide structure output you can use the `ShipmentFormatter` which formats
a given `Shipment` in a CSV (whitespace separated) format with their discounts.
### Shipping Options
Shipping options are a struct to represent an individual shipping option, it
includes the price, the provider as well as the package size.
Use the `ShippingOptionRepository` to retrieve shipping options and query
for specific providers/package sizes.
### ShipmentDiscountCalculator
This class is the central entry point for calculating discounts for a list of
shipments. It takes a shipment_repository and a list of rules and
applies the list of rules to the given shipments
Example:
```ruby
calculator = ShipmentDiscountCalculator.new(
shipment_repository: ShipmentRepository.new(data: []),
rules: [Rule.new(...)])
calculator.run([Shipment.new])
```
### Repository
The repository base class is the managing unit to retrieve and store shared
state. When possible nobody should query the data directly, but define
a query method in the repository to retrieve the required data.
It provides an ActiveRecord like `where` method with which you can
query for multiple attributes in one call:
```ruby
repo.where(attribute_a: 5, attribute_b: "Test") # => enumerable matching the criteria
```
### Money Handling
In order to prevent floating errors when calculating discounts the system uses
integers and all prices are defined including the cents, so 1.5€ are represented
as `150`.
## Development
@ -34,7 +144,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/planet_express. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/planet_express/blob/master/CODE_OF_CONDUCT.md).
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).