Skip to content
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

Fixes #99 #100

Merged
merged 1 commit into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions app/models/article_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,13 @@ class ArticleVersion < ApplicationRecord
validates :price, numericality: { greater_than_or_equal_to: 0 }
validates :group_order_granularity, numericality: { greater_than_or_equal_to: 0 }
validates :deposit, :tax, numericality: true
validates :minimum_order_quantity,
numericality: { allow_nil: true, only_integer: false, if: :supplier_order_unit_is_si_convertible }
validates :minimum_order_quantity,
numericality: { allow_nil: true, only_integer: true, unless: :supplier_order_unit_is_si_convertible }
validates :minimum_order_quantity, numericality: { allow_nil: true }

# validates_uniqueness_of :name, :scope => [:supplier_id, :deleted_at, :type], if: Proc.new {|a| a.supplier.shared_sync_method.blank? or a.supplier.shared_sync_method == 'import' }
# validates_uniqueness_of :name, :scope => [:supplier_id, :deleted_at, :type, :unit, :unit_quantity]
validate :uniqueness_of_name
validate :only_one_unit_type
validate :minimum_order_quantity_as_integer, unless: :supplier_order_unit_is_si_convertible

# Replace numeric seperator with database format
localize_input_of :price, :tax, :deposit
Expand Down Expand Up @@ -117,13 +116,7 @@ def minimum_order_quantity=(value)
if value.blank?
self[:minimum_order_quantity] = nil
else
value = value.gsub(I18n.t('number.format.separator'), '.') if value.is_a?(String)
begin
value = value.to_i if Float(value) % 1 == 0
rescue ArgumentError
# not any number -> let validation handle this
end
super(value)
super
end
end

Expand Down Expand Up @@ -190,6 +183,17 @@ def uniqueness_of_name
end
end

def minimum_order_quantity_as_integer
begin
return if Float(minimum_order_quantity) % 1 == 0
rescue ArgumentError, TypeError
# not any number -> let numericality validation handle this
return
end

errors.add(:minimum_order_quantity, :only_integer)
end

def only_one_unit_type
return if unit.blank? || supplier_order_unit.blank?

Expand Down
1 change: 1 addition & 0 deletions app/models/order_article.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def update_results!
# 4 | 5 | 4 | 2
#
def calculate_units_to_order(quantity, tolerance = 0)
return 0 if !price.minimum_order_quantity.nil? && quantity + tolerance < price.minimum_order_quantity
return price.minimum_order_quantity if quantity > 0 && !price.minimum_order_quantity.nil? && quantity < price.minimum_order_quantity && quantity + tolerance >= price.minimum_order_quantity

unit_size = price.convert_quantity(1, price.supplier_order_unit, price.group_order_unit)
Expand Down
2 changes: 2 additions & 0 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ de:
name:
taken: Name ist bereits vergeben
taken_with_unit: Name und Einheit sind bereits vergeben
minimum_order_quantity:
only_integer: Muss eine Ganzzahl sein, wenn die Liefereinheit eine Stückeinheit ist.
supplier:
attributes:
shared_sync_method:
Expand Down
2 changes: 2 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ en:
name:
taken: name is already taken
taken_with_unit: name and unit are already taken
minimum_order_quantity:
only_integer: Must be an integer if supplier order unit is a piece unit
supplier:
attributes:
shared_sync_method:
Expand Down
2 changes: 2 additions & 0 deletions spec/factories/article.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
order_number { nil }
unit_quantity { nil }
unit { nil }
minimum_order_quantity { nil }
supplier_order_unit { 'XPK' }
group_order_unit { 'XPK' }
billing_unit { 'XPK' }
Expand All @@ -23,6 +24,7 @@
order_number: evaluator.order_number,
unit_quantity: evaluator.unit_quantity,
unit: evaluator.unit,
minimum_order_quantity: evaluator.minimum_order_quantity,
supplier_order_unit: evaluator.supplier_order_unit,
group_order_unit: evaluator.group_order_unit,
billing_unit: evaluator.billing_unit,
Expand Down
55 changes: 55 additions & 0 deletions spec/models/order_article_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,59 @@ def goa_reload
# end
end
end

describe 'minimum order quantity' do
let(:order) { create(:order, article_ids: [article.id], starts: 1.week.ago) }
let(:oa) { order.order_articles.first }
let(:go) { create(:group_order, order: order) }
let(:goa) { create(:group_order_article, group_order: go, order_article: oa) }

shared_context 'minimum order quantity' do |quantity|
before do
goa.update_quantities(quantity[:quantity], quantity[:tolerance])
oa.update_results!
oa.reload
end

it 'is calculated correctly' do
expect(oa.units_to_order).to eq quantity[:expected_units_to_order]
end
end

context 'without unit_quantity' do
let(:article) { create(:article, minimum_order_quantity: 10) }

context 'doesn\'t order anything, if the minimum order quantity hasn\'t been reached' do
include_examples 'minimum order quantity', { quantity: 4, tolerance: 0, expected_units_to_order: 0 }
end

context 'orders the minimum order quantity, if tolerance allows for it' do
include_examples 'minimum order quantity', { quantity: 9, tolerance: 1, expected_units_to_order: 10 }
end

context 'orders the desired amount, if minimum order quantity has been surpassed' do
include_examples 'minimum order quantity', { quantity: 12, tolerance: 1, expected_units_to_order: 12 }
end
end

context 'with unit_quantity' do
let(:article) { create(:article, minimum_order_quantity: 2, unit_quantity: 5) }

context 'doesn\'t order anything if the minimum order quantity hasn\'t been reached' do
include_examples 'minimum order quantity', { quantity: 4, tolerance: 0, expected_units_to_order: 0 }
end

context 'orders the minimum order quantity if tolerance allows for it' do
include_examples 'minimum order quantity', { quantity: 9, tolerance: 1, expected_units_to_order: 2 }
end

context 'orders a lower amount, even if minimum order quantity has been surpassed, but unit_quantity demands it' do
include_examples 'minimum order quantity', { quantity: 12, tolerance: 1, expected_units_to_order: 2 }
end

context 'orders the exact amount, if minimum order quantity has been surpassed and unit_quantity allows for it' do
include_examples 'minimum order quantity', { quantity: 14, tolerance: 1, expected_units_to_order: 3 }
end
end
end
end
Loading