Write proper readme
This commit is contained in:
parent
5719237879
commit
3e64b35558
141
README.md
141
README.md
@ -1,28 +1,138 @@
|
|||||||
# PlanetExpress
|
# 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.
|
Planet Express is your little helper to calculate possible discounts for your
|
||||||
|
shipments based on a given rule set and an available discount budget.
|
||||||
TODO: Delete this and the text above, and describe your gem
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add this line to your application's Gemfile:
|
Get the code from github and run `bundle install`
|
||||||
|
|
||||||
```ruby
|
Afterwards you are ready to rumble.
|
||||||
gem 'planet_express'
|
|
||||||
```
|
|
||||||
|
|
||||||
And then execute:
|
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.
|
||||||
$ bundle install
|
|
||||||
|
|
||||||
Or install it yourself as:
|
|
||||||
|
|
||||||
$ gem install planet_express
|
|
||||||
|
|
||||||
## Usage
|
## 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
|
## 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).
|
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
|
## License
|
||||||
|
|
||||||
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
||||||
|
Loading…
Reference in New Issue
Block a user