-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow creating custom vat rates #377
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,16 @@ | ||
module Taxes | ||
class SetVatRate < Infra::Command | ||
attribute :product_id, Infra::Types::UUID | ||
attribute :vat_rate, Infra::Types::VatRate | ||
attribute :vat_rate_code, Infra::Types::String | ||
end | ||
|
||
class DetermineVatRate < Infra::Command | ||
attribute :product_id, Infra::Types::UUID | ||
attribute :order_id, Infra::Types::UUID | ||
end | ||
end | ||
|
||
class AddAvailableVatRate < Infra::Command | ||
attribute :available_vat_rate_id, Infra::Types::UUID | ||
attribute :vat_rate, Infra::Types::VatRate | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,51 +3,74 @@ | |
module Taxes | ||
class TaxesTest < Test | ||
def test_setting_available_vat_rate | ||
vat_rate = Infra::Types::VatRate.new(code: "50", rate: 50) | ||
add_available_vat_rate(vat_rate) | ||
|
||
product_id = SecureRandom.uuid | ||
vat_rate_set = VatRateSet.new(data: { product_id: product_id, vat_rate: available_vat_rate }) | ||
vat_rate_set = VatRateSet.new(data: { product_id: product_id, vat_rate: vat_rate }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. small tip, you could do
instead :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer to leave this as is for now, as it is consistent with the rest of the code in the project. In the future we can add a rubocop rule to enforce style guides :) |
||
assert_events("Taxes::Product$#{product_id}", vat_rate_set) do | ||
set_vat_rate(product_id, available_vat_rate) | ||
set_vat_rate(product_id, vat_rate.code) | ||
end | ||
end | ||
|
||
def test_setting_unavailable_vat_rate_should_raise_error | ||
product_id = SecureRandom.uuid | ||
assert_raises(Product::VatRateNotApplicable) do | ||
set_vat_rate(product_id, unavailable_vat_rate) | ||
unavailable_vat_rate = Infra::Types::VatRate.new(code: "20", rate: 20) | ||
|
||
assert_raises(Taxes::VatRateNotApplicable) do | ||
set_vat_rate(product_id, unavailable_vat_rate.code) | ||
end | ||
end | ||
|
||
def test_determining_vat_rate | ||
vat_rate = Infra::Types::VatRate.new(code: "50", rate: 50) | ||
add_available_vat_rate(vat_rate) | ||
|
||
order_id = SecureRandom.uuid | ||
product_id = SecureRandom.uuid | ||
another_product_id = SecureRandom.uuid | ||
|
||
set_vat_rate(product_id, available_vat_rate) | ||
vat_rate_determined = VatRateDetermined.new(data: { order_id: order_id, product_id: product_id, vat_rate: available_vat_rate }) | ||
set_vat_rate(product_id, vat_rate.code) | ||
vat_rate_determined = VatRateDetermined.new(data: { order_id: order_id, product_id: product_id, vat_rate: vat_rate }) | ||
assert_events("Taxes::Order$#{order_id}", vat_rate_determined) do | ||
determine_vat_rate(order_id, product_id, available_vat_rate) | ||
determine_vat_rate(order_id, product_id, vat_rate) | ||
end | ||
assert_events("Taxes::Order$#{order_id}") do | ||
determine_vat_rate(order_id, another_product_id, available_vat_rate) | ||
determine_vat_rate(order_id, another_product_id, vat_rate) | ||
end | ||
end | ||
|
||
def test_adding_available_vat_rate | ||
available_vat_rate_id = SecureRandom.uuid | ||
vat_rate = Infra::Types::VatRate.new(code: "50", rate: 50) | ||
available_vat_rate_added = AvailableVatRateAdded.new(data: { available_vat_rate_id: available_vat_rate_id, vat_rate: vat_rate }) | ||
|
||
assert_events("Taxes::AvailableVatRate$#{vat_rate.code}", available_vat_rate_added) do | ||
add_available_vat_rate(vat_rate, available_vat_rate_id) | ||
end | ||
end | ||
|
||
def test_should_not_allow_for_double_registration | ||
vat_rate = Infra::Types::VatRate.new(code: "50", rate: 50) | ||
add_available_vat_rate(vat_rate) | ||
|
||
assert_raises(VatRateAlreadyExists) do | ||
add_available_vat_rate(vat_rate) | ||
end | ||
end | ||
|
||
private | ||
|
||
def set_vat_rate(product_id, vat_rate) | ||
run_command(SetVatRate.new(product_id: product_id, vat_rate: vat_rate)) | ||
def set_vat_rate(product_id, vat_rate_code) | ||
run_command(SetVatRate.new(product_id: product_id, vat_rate_code: vat_rate_code)) | ||
end | ||
|
||
def determine_vat_rate(order_id, product_id, vat_rate) | ||
run_command(DetermineVatRate.new(order_id: order_id, product_id: product_id, vat_rate: vat_rate)) | ||
end | ||
|
||
def available_vat_rate | ||
Configuration.available_vat_rates.first | ||
end | ||
|
||
def unavailable_vat_rate | ||
Infra::Types::VatRate.new(code: "50", rate: 50) | ||
def add_available_vat_rate(vat_rate, available_vat_rate_id = SecureRandom.uuid) | ||
run_command(AddAvailableVatRate.new(available_vat_rate_id: available_vat_rate_id, vat_rate: vat_rate)) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
require_relative "test_helper" | ||
|
||
module Taxes | ||
class VatRateCatalogTest < Test | ||
class VatRateByCodeTest < VatRateCatalogTest | ||
def setup | ||
@vat_rate = Infra::Types::VatRate.new(code: "50", rate: 50) | ||
add_available_vat_rate(@vat_rate) | ||
end | ||
|
||
def test_returns_available_vat_rate | ||
assert_equal @vat_rate, catalog.vat_rate_by_code("50") | ||
end | ||
|
||
def test_returns_nil_when_vat_rate_is_not_available | ||
assert_nil catalog.vat_rate_by_code("60") | ||
end | ||
end | ||
|
||
private | ||
|
||
def catalog | ||
VatRateCatalog.new(@event_store) | ||
end | ||
|
||
def add_available_vat_rate(vat_rate, available_vat_rate_id = SecureRandom.uuid) | ||
run_command(AddAvailableVatRate.new(available_vat_rate_id: available_vat_rate_id, vat_rate: vat_rate)) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
class AvailableVatRatesController < ApplicationController | ||
class AvailableVatRateForm | ||
include ActiveModel::Model | ||
include ActiveModel::Validations | ||
|
||
attr_reader :code, :rate | ||
|
||
def initialize(params) | ||
@code = params[:code] | ||
@rate = params[:rate] | ||
end | ||
Comment on lines
+6
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
validates :code, presence: true | ||
validates :rate, presence: true, numericality: { only_numeric: true, greater_than: 0 } | ||
end | ||
|
||
def new | ||
end | ||
|
||
def create | ||
available_vat_rate_id = SecureRandom.uuid | ||
available_vat_rate_form = AvailableVatRateForm.new(available_vat_rate_params) | ||
|
||
unless available_vat_rate_form.valid? | ||
return render "new", locals: { errors: available_vat_rate_form.errors }, status: :unprocessable_entity | ||
end | ||
|
||
add_available_vat_rate(available_vat_rate_form.code, available_vat_rate_form.rate, available_vat_rate_id) | ||
rescue Taxes::VatRateAlreadyExists | ||
flash.now[:notice] = "VAT rate already exists" | ||
render "new", status: :unprocessable_entity | ||
else | ||
redirect_to available_vat_rates_path, notice: "VAT rate was successfully created" | ||
end | ||
|
||
def index | ||
@available_vat_rates = VatRates::AvailableVatRate.all | ||
end | ||
|
||
private | ||
|
||
def add_available_vat_rate(code, rate, available_vat_rate_id) | ||
command_bus.(add_available_vat_rate_cmd(code, rate, available_vat_rate_id)) | ||
end | ||
|
||
def add_available_vat_rate_cmd(code, rate, available_vat_rate_id) | ||
Taxes::AddAvailableVatRate.new( | ||
available_vat_rate_id: available_vat_rate_id, | ||
vat_rate: Infra::Types::VatRate.new(code: code, rate: rate) | ||
) | ||
end | ||
|
||
def available_vat_rate_params | ||
params.permit(:code, :rate) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using
code
instead ofuuid
in the stream name.This helps ensure uniqueness of vat rates and simplifies some logic.
Please let me know what you think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically it is a good choice. However I am wondering if the model is correct. But I don't have an answer yet. It is good for first iteration I guess.