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

Adapt article & group sorted order PDF (solves #49) #87

Open
wants to merge 52 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
ecf7c17
Article units squash
lentschi Mar 16, 2024
cfbe5b7
Fix typos and removed dead code
lentschi Mar 22, 2024
2a42360
Remove obsolete testing shared db along with its tasks
lentschi Mar 22, 2024
539613b
Added no-upstream for byebug
lentschi Mar 22, 2024
ba11e4b
On #47 Adapt unit ratio export/import to be interpreted as a conversi…
lentschi Mar 23, 2024
5bcea4a
On #21: stock orders: prohibit 'ordering' more than what's on stock
lentschi Mar 23, 2024
b39cb77
Started with #8
lentschi Mar 23, 2024
51c2703
Fixes #53
lentschi Mar 29, 2024
37d1b27
fix: round article quantity in order article pdf
yksflip Mar 29, 2024
d831092
Don't show articles migrate button for newly created suppliers
lentschi Mar 31, 2024
acc982d
On #8: All existing specs pass now
lentschi Apr 6, 2024
e5a2398
Rubocop fixes
lentschi Apr 6, 2024
74ac2f3
First proposal for #35
lentschi Apr 6, 2024
cb38646
On #15: Open with inset button instead of on every focus
lentschi Apr 6, 2024
8b6d01a
Fixes #56
lentschi Apr 12, 2024
90c4fcb
On #35: Adapted list of default units
lentschi Apr 12, 2024
1c9612c
Fixes #42
lentschi Apr 12, 2024
4106ee8
Fixes #42 again
lentschi Apr 12, 2024
0abb392
On #8: Implemented article version model unit tests
lentschi Apr 12, 2024
eb33fe8
On #8: Adapted article version unit tests
lentschi Apr 19, 2024
8ed4bb9
On #35 Added missing metric default unit: GRM
lentschi Apr 19, 2024
be44773
Fixes #56 again
lentschi Apr 19, 2024
6eb79bf
Fixes #59
lentschi Apr 21, 2024
a51304b
Fixes #58
lentschi Apr 21, 2024
3939556
Fixes #60
lentschi Apr 21, 2024
3941539
Fixes #65
lentschi Apr 26, 2024
6c77080
Fixes #62
lentschi Apr 26, 2024
476e322
On #8: Fixes failing tests on github
lentschi Apr 28, 2024
3ce6390
On #8: Article units integration tests
lentschi May 1, 2024
c67a465
On #8: Started with unit tests for supplier article sharing
lentschi May 5, 2024
de4792a
Fixes #68
lentschi May 20, 2024
b61b847
Fixes #67
lentschi May 20, 2024
2e19cd3
Fixes #69
lentschi May 24, 2024
2c02208
On #8: Done with sync specs
lentschi May 24, 2024
67041a1
On #15: Fixes conversion popover min-width
lentschi May 24, 2024
2ae2c6d
Fixes #61
lentschi Jun 7, 2024
0754f15
Fixes #73
lentschi Jun 7, 2024
222ada6
Better alias for #71
lentschi Jun 7, 2024
97a3f48
On #64: Add missing unit labels
lentschi Jun 22, 2024
602cff1
On #42: Fax pdf/csv: Decimals dependant on supplier_order_unit's si c…
lentschi Jun 28, 2024
366065f
feat: update seed files (#76)
yksflip Jul 5, 2024
8f87d7e
Fixes #66 (#74)
lentschi Jul 12, 2024
61a2b1a
Workaround for #78
lentschi Jul 13, 2024
681095b
Moved fork's migrations after rebase on upstream/master
lentschi Jul 26, 2024
dec2762
Fixes #85
lentschi Jul 26, 2024
9191f42
Allow price calculation for new records
lentschi Jul 26, 2024
3871c37
Fixes #83
lentschi Jul 26, 2024
756fda0
Another workaround for #78
lentschi Jul 26, 2024
b3bc712
Fixes #81
lentschi Jul 26, 2024
3be31d5
Article CSV: fix #47 and #46 (#84)
twothreenine Jul 26, 2024
3297e5e
Fix unit tests (broken since 3871c37a06f956ab897828e35e75c794d6c7bf53)
lentschi Jul 26, 2024
a8d87d7
Adapt article & group sorted order PDF (solves #49)
twothreenine Jul 29, 2024
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
Prev Previous commit
Next Next commit
On #8: All existing specs pass now
This also fixes several actual bugs (partially caused by the rabase) detected by the specs
lentschi committed Jul 26, 2024
commit acc982d6c00aca45ed79091ea16464ffb29db9a8
3 changes: 3 additions & 0 deletions HACKATHON_TODOS.md
Original file line number Diff line number Diff line change
@@ -6,6 +6,9 @@
* Investigate total_balance hidden field meaning (old issue)
* Formatting: Alignment breaks with numbers that have more than one digit (old issue; but renewed importance due to floats)
* Article (version) Field translations of new / moved fields
* What is `order_articles.units_billed` for?
* Discuss `convert_units` checkbox articles import
* Review API endpoints

# POST-merge:

1 change: 1 addition & 0 deletions app/assets/javascripts/group-order-form.js
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ class GroupOrderForm {
this.minimumBalance = config.minimumBalance;

this.initializeIncreaseDecreaseButtons();
this.submitButton$.removeAttr('disabled');
}

initializeIncreaseDecreaseButtons() {
10 changes: 8 additions & 2 deletions app/assets/javascripts/receive-order-form.js
Original file line number Diff line number Diff line change
@@ -32,6 +32,10 @@
}

convertFieldUnit(field$, fromUnit, toUnit) {
if (field$.is(':disabled')) {
return;
}

const units = parseFloat(field$.val().replace(',', '.'));
if (isNaN(units)) {
return;
@@ -51,8 +55,10 @@

convertFromBillingUnit(field$) {
const convertedValue = this.convertFieldUnit(field$, field$.data('billing-unit'), field$.data('supplier-order-unit'));
const hiddenReceivedField$ = $(`<input type="hidden" name="${field$.attr('name')}" value="${convertedValue}" />`);
this.receiveForm$.append(hiddenReceivedField$);
if (convertedValue !== undefined) {
const hiddenReceivedField$ = $(`<input type="hidden" name="${field$.attr('name')}" value="${convertedValue}" />`);
this.receiveForm$.append(hiddenReceivedField$);
}
}

updateDelta(input) {
2 changes: 1 addition & 1 deletion app/controllers/api/v1/order_articles_controller.rb
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ def show
private

def scope
OrderArticle.includes(:article_version, article: :supplier)
OrderArticle.includes(article_version: { article: :supplier })
end

def search_scope
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ def max_per_page
def scope
GroupOrderArticle
.joins(:group_order)
.includes(order_article: :article, group_order: :order)
.includes(order_article: :article_version, group_order: :order)
.where(group_orders: { ordergroup_id: current_ordergroup.id })
end

2 changes: 1 addition & 1 deletion app/controllers/order_articles_controller.rb
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ def create
# The article may be ordered with zero units - in that case do not complain.
# If order_article is ordered and a new order_article is created, an error message will be
# given mentioning that the article already exists, which is desired.
@order_article = @order.order_articles.joins(:article_version).where(article_versions: { article_id: params[:order_article][:article_version][:article_id] }).first
@order_article = @order.order_articles.joins(:article_version).where(id: params[:order_article][:article_version_id]).first
@order_article = @order.order_articles.build(params[:order_article]) unless @order_article && @order_article.units_to_order == 0
@order_article.save!
rescue StandardError
2 changes: 1 addition & 1 deletion app/controllers/orders_controller.rb
Original file line number Diff line number Diff line change
@@ -187,7 +187,7 @@ def update_order_amounts
counts[0] += 1
if oa.units_received.present?
units_received = oa.article_version.convert_quantity(oa.units_received,
oa.article_version.supplier_order_unit, oa.article_version.billing_unit)
oa.article_version.supplier_order_unit, oa.article_version.group_order_unit)
cunits[0] += units_received
oacounts = oa.redistribute units_received, rest_to
oacounts.each_with_index do |c, i|
6 changes: 0 additions & 6 deletions app/helpers/group_orders_helper.rb
Original file line number Diff line number Diff line change
@@ -45,12 +45,6 @@ def get_order_results(order_article, group_order_id)
{ group_order_article: goa, quantity: quantity, tolerance: tolerance, result: result, sub_total: sub_total }
end

def requires_tolerance_input?(order_article, ordering_data)
(
!order_article.article_version.supplier_order_unit_is_si_convertible &&
ordering_data[:order_articles][order_article.id][:ratio_group_order_unit_supplier_unit] != order_article.article_version.group_order_granularity
) || (order_article.article_version.minimum_order_quantity.presence || 0) > order_article.article_version.group_order_granularity
end

def get_missing_units_css_class(quantity_missing, article_version)
if quantity_missing == 0
17 changes: 15 additions & 2 deletions app/models/article.rb
Original file line number Diff line number Diff line change
@@ -113,6 +113,16 @@ def ordered_in_order?(order)
order.order_articles.includes(:article_version).where(article_version: { article_id: id }).where('quantity > 0').one?
end

# to get the correspondent shared article
def shared_article(supplier = self.supplier)
order_number.blank? and return nil
@shared_article ||= begin
supplier.shared_supplier.find_article_by_number(order_number)
rescue StandardError
nil
end
end

# this method checks, if the shared_article has been changed
# unequal attributes will returned in array
# if only the timestamps differ and the attributes are equal,
@@ -167,8 +177,6 @@ def unequal_attributes(new_article, options = {})
price: [latest_article_version.price.to_f.round(2), new_price.to_f.round(2)],
tax: [latest_article_version.tax, new_article.tax],
deposit: [latest_article_version.deposit.to_f.round(2), new_article.deposit.to_f.round(2)],
# take care of different num-objects.
# :article_unit_ratios_attributes => [self.latest_article_version.article_unit_ratios, new_unit_quantity.article_unit_ratios],
note: [latest_article_version.note.to_s, new_article.note.to_s]
}
)
@@ -184,6 +192,11 @@ def unequal_attributes(new_article, options = {})
ret[:article_unit_ratios_attributes] = ratio_attribs
end

if options[:convert_units] && latest_article_version.article_unit_ratios.length < 2 && new_article.article_unit_ratios.length < 2 && !new_unit_quantity.nil?
ret[:article_unit_ratios_attributes] = [new_article.article_unit_ratios.build(unit: 'XPP', quantity: new_unit_quantity, sort: 1).attributes]
# TODO: Either remove this aspect of the :convert_units feature or extend it to also work for the new units system
end

ret
end

7 changes: 7 additions & 0 deletions app/models/article_version.rb
Original file line number Diff line number Diff line change
@@ -148,6 +148,13 @@ def self.compare_attributes(attributes)
unequal_attributes.to_a.map { |a| [a[0], a[1].last] }.to_h
end

def uses_tolerance?
(
!supplier_order_unit_is_si_convertible &&
convert_quantity(1, supplier_order_unit, group_order_unit) != group_order_granularity
) || (minimum_order_quantity.presence || 0) > group_order_granularity
end

protected

# We used have the name unique per supplier+deleted_at+type. With the addition of shared_sync_method all,
1 change: 0 additions & 1 deletion app/models/invoice.rb
Original file line number Diff line number Diff line change
@@ -35,7 +35,6 @@ def orders_sum
orders
.joins(order_articles: [:article_version])
.sum('COALESCE(order_articles.units_received, order_articles.units_billed, order_articles.units_to_order)' \
+ '* article_versions.unit_quantity' \
+ '* ROUND((article_versions.price + article_versions.deposit) * (100 + article_versions.tax) / 100, 2)')
end

4 changes: 2 additions & 2 deletions app/models/order.rb
Original file line number Diff line number Diff line change
@@ -81,9 +81,9 @@ def articles_for_ordering

def supplier_articles
if stockit?
StockArticle.undeleted.reorder('articles.name')
StockArticle.undeleted.with_latest_versions_and_categories.reorder('article_versions.name')
else
supplier.articles.undeleted.reorder('articles.name')
supplier.articles.undeleted.with_latest_versions_and_categories.reorder('article_versions.name')
end
end

10 changes: 3 additions & 7 deletions app/models/order_article.rb
Original file line number Diff line number Diff line change
@@ -107,7 +107,7 @@ def total_gross_price
end

# redistribute articles over ordergroups
# quantity Number of units to distribute
# quantity Number of units to distribute (in group_order_unit)
# surplus What to do when there are more articles than ordered quantity
# :tolerance fill member orders' tolerance
# :stock move to stock
@@ -126,11 +126,7 @@ def redistribute(quantity, surplus = [:tolerance], update_totals = true)
end

# Recompute
group_order_articles.each do |goa|
group_order_total = article_version.convert_quantity(qty_for_members, article_version.supplier_order_unit,
article_version.group_order_unit)
goa.save_results!(group_order_total)
end
group_order_articles.each { |goa| goa.save_results! qty_for_members }
qty_left -= qty_for_members

# if there's anything left, move to stock if wanted
@@ -262,7 +258,7 @@ def enforce_boxfill
unless (delta_q == 0 && delta_t >= 0) ||
(delta_mis < 0 && delta_box >= 0 && delta_t >= 0) ||
(delta_q > 0 && delta_q == -delta_t)
raise ActiveRecord::RecordNotSaved.new("Change not acceptable in boxfill phase for '#{article.name}', sorry.",
raise ActiveRecord::RecordNotSaved.new("Change not acceptable in boxfill phase for '#{article_version.name}', sorry.",
self)
end
end
4 changes: 2 additions & 2 deletions app/models/supplier.rb
Original file line number Diff line number Diff line change
@@ -77,9 +77,9 @@ def mark_as_deleted
end
end

# @return [Boolean] Whether there are articles that would use tolerance (unit_quantity > 1)
# @return [Boolean] Whether there are articles that would use tolerance
def has_tolerance?
articles.where('articles.unit_quantity > 1').any?
articles.with_latest_versions_and_categories.any? { |article| article.latest_article_version.uses_tolerance? }
end

# TODO: Maybe use the nilify blanks gem instead of the following two methods?:
2 changes: 1 addition & 1 deletion app/serializers/order_article_serializer.rb
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ class OrderArticleSerializer < ActiveModel::Serializer
attributes :id, :order_id, :price
attributes :quantity, :tolerance, :units_to_order

has_one :article
has_one :article_version

def price
object.article_version.fc_price.to_f
4 changes: 2 additions & 2 deletions app/views/articles/_sync.html.haml
Original file line number Diff line number Diff line change
@@ -21,14 +21,14 @@
%i
= t '.update.update_msg', count: @updated_article_pairs.size
= t '.update.body'
= render 'sync_table', articles: @updated_article_pairs, field: 'articles', hidden_fields: %w(shared_updated_on)
= render 'sync_table', articles: @updated_article_pairs, field: 'articles', hidden_fields: []
%hr/

- if @new_articles.any?
%h2= t '.upnew.title'
%p
%i= t '.upnew.body_count', count: @new_articles.length
= render 'sync_table', articles: @new_articles, field: 'new_articles', hidden_fields: %w(shared_updated_on order_number availability)
= render 'sync_table', articles: @new_articles, field: 'new_articles', hidden_fields: %w(order_number availability)
%hr/

- if ignored_article_count > 0
5 changes: 2 additions & 3 deletions app/views/articles/_sync_table.html.haml
Original file line number Diff line number Diff line change
@@ -36,9 +36,8 @@
%td{:style => highlight_new(attrs, :name)}
= form.text_field 'name', :size => 0
= form.input :id, as: :hidden unless changed_article.new_record?
-# TODO:
-# - hidden_fields.each do |field|
-# = form.input field, as: :hidden
- hidden_fields.each do |field|
= form.input field, as: :hidden
%td{:style => highlight_new(attrs, :note)}= form.text_field 'note', class: 'input-small'
%td{:style => highlight_new(attrs, :manufacturer)}= form.text_field 'manufacturer', class: 'input-small'
%td{:style => highlight_new(attrs, :origin)}= form.text_field 'origin', class: 'input-mini'
2 changes: 1 addition & 1 deletion app/views/deliveries/show.html.haml
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@
- total_gross += quantity * stock_change.stock_article.gross_price
%tr
%td= stock_change.stock_article.name
%td= stock_change.stock_article.unit
%td= format_supplier_order_unit_with_ratios(stock_change.stock_article)
%td.numeric= quantity
%td.numeric= number_to_currency stock_change.stock_article.price
%td.numeric= number_to_currency sum
7 changes: 4 additions & 3 deletions app/views/group_orders/_form.html.haml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
:javascript
new GroupOrderForm($('.group_order_form'), {
units: unitsData,
toleranceIsCostly: #{FoodsoftConfig[:tolerance_is_costly]},
toleranceIsCostly: #{(FoodsoftConfig[:tolerance_is_costly] or false).to_json},
groupBalance: #{group_balance},
minimumBalance: #{FoodsoftConfig[:minimum_balance] or 0}
});
@@ -115,6 +115,7 @@
- quantity_data['used_quantity'] = @ordering_data[:order_articles][order_article.id][:used_quantity]
- quantity_data['price'] = @ordering_data[:order_articles][order_article.id][:price]
- quantity_data['minimum_order_quantity'] = @ordering_data[:order_articles][order_article.id][:minimum_order_quantity] unless @ordering_data[:order_articles][order_article.id][:minimum_order_quantity].nil?
- quantity_data['e2e-order-article-id'] = order_article.id
%td.quantity.group-order-input{class: ('stock-order' if @order.stockit?)}
%span.used= format_number(@ordering_data[:order_articles][order_article.id][:used_quantity])
+
@@ -129,7 +130,7 @@
= t('errors.step_error', granularity: order_article.article_version.group_order_granularity, min: 0)

%td.tolerance.group-order-input{style: ('display:none' if @order.stockit?)}
- if (requires_tolerance_input?(order_article, @ordering_data))
- if (order_article.article_version.uses_tolerance?)
%span.used= format_number(@ordering_data[:order_articles][order_article.id][:used_tolerance])
+
%span.unused= format_number(@ordering_data[:order_articles][order_article.id][:tolerance] - @ordering_data[:order_articles][order_article.id][:used_tolerance])
@@ -184,7 +185,7 @@
%strong
%span#new_balance= number_to_currency(old_balance - @group_order.price)
#order-button
= submit_tag( t('.action_save'), id: 'submit_button', class: 'btn btn-primary' )
= submit_tag( t('.action_save'), id: 'submit_button', class: 'btn btn-primary', disabled: 'disabled' )
#{link_to t('ui.or_cancel'), group_orders_path}
%input#total_balance{name: "total_balance", type: "hidden", value: @ordergroup.account_balance - @group_order.price}/
%input{name: "version", type: "hidden", value: @version}/
2 changes: 1 addition & 1 deletion app/views/order_articles/_new.html.haml
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
= close_button :modal
%h3= t '.title'
.modal-body
= form.association :article, collection: @order.supplier_articles, label_method: lambda {|a| article_label_with_unit(a)}
= form.association :article_version, collection: @order.supplier_articles.map(&:latest_article_version), label_method: lambda {|a| article_label_with_unit(a)}
.modal-footer
= link_to t('ui.close'), '#', class: 'btn', data: {dismiss: 'modal'}
= form.submit class: 'btn btn-primary'
3 changes: 3 additions & 0 deletions config/puma.rb
Original file line number Diff line number Diff line change
@@ -56,3 +56,6 @@

# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart

# TODO-no-upstream
worker_timeout 3600 if ENV.fetch('RAILS_ENV') == 'development'
16 changes: 10 additions & 6 deletions db/migrate/20240316190957_alter_articles_add_more_unit_logic.rb
Original file line number Diff line number Diff line change
@@ -48,9 +48,11 @@ def up
end

change_table :order_articles do |t|
t.change :quantity, :decimal, precision: 8, scale: 3, null: false
t.change :tolerance, :decimal, precision: 8, scale: 3, null: false
t.change :units_to_order, :decimal, precision: 8, scale: 3, null: false
t.change :quantity, :decimal, precision: 8, scale: 3, null: false, comment: 'stored in `article_versions.group_order_unit`'
t.change :tolerance, :decimal, precision: 8, scale: 3, null: false, comment: 'stored in `article_versions.group_order_unit`'
t.change :units_to_order, :decimal, precision: 8, scale: 3, null: false, comment: 'stored in `article_versions.supplier_order_unit`'
t.change :units_billed, :decimal, precision: 8, scale: 3, null: true, comment: 'stored in `article_versions.supplier_order_unit`'
t.change :units_received, :decimal, precision: 8, scale: 3, null: true, comment: 'stored in `article_versions.supplier_order_unit`'
end

change_table :group_order_articles do |t|
@@ -88,9 +90,11 @@ def down
drop_table :article_unit_ratios

change_table :order_articles do |t|
t.change :quantity, :integer, null: false
t.change :tolerance, :integer, null: false
t.change :units_to_order, :integer, null: false
t.change :quantity, :integer, null: false, comment: nil
t.change :tolerance, :integer, null: false, comment: nil
t.change :units_to_order, :integer, null: false, comment: nil
t.change :units_billed, :decimal, precision: 8, scale: 3, null: true, comment: nil
t.change :units_received, :decimal, precision: 8, scale: 3, null: true, comment: nil
end

change_table :group_order_articles do |t|
6 changes: 4 additions & 2 deletions spec/factories/article.rb
Original file line number Diff line number Diff line change
@@ -9,10 +9,11 @@
article_version_count { 1 }
order_number { nil }
unit_quantity { nil }
unit { nil }
end

after(:create) do |article, evaluator|
create_list(:article_version, evaluator.article_version_count, article: article, order_number: evaluator.order_number, unit_quantity: evaluator.unit_quantity)
create_list(:article_version, evaluator.article_version_count, article: article, order_number: evaluator.order_number, unit_quantity: evaluator.unit_quantity, unit: evaluator.unit)

article.reload
end
@@ -23,10 +24,11 @@

transient do
stock_article_version_count { 1 }
price { 1 }
end

after(:create) do |stock_article, evaluator|
create_list(:article_version, evaluator.stock_article_version_count, article: stock_article)
create_list(:article_version, evaluator.stock_article_version_count, article: stock_article, price: evaluator.price)

stock_article.reload
end
7 changes: 7 additions & 0 deletions spec/factories/article_unit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require 'factory_bot'

FactoryBot.define do
factory :article_unit do
sequence(:unit) { |n| Faker::Lorem.characters(number: rand(2..12)) + " ##{n}" }
end
end
4 changes: 2 additions & 2 deletions spec/factories/article_unit_ratio.rb
Original file line number Diff line number Diff line change
@@ -2,9 +2,9 @@

FactoryBot.define do
factory :article_unit_ratio do
unit { Faker::Unit.unit }
unit { 'XPP' } # TODO
sort { 1 }
quantity { 1 } # TODO
quantity { 1 }
article_version
end
end
11 changes: 9 additions & 2 deletions spec/factories/article_version.rb
Original file line number Diff line number Diff line change
@@ -2,8 +2,9 @@
FactoryBot.define do
factory :article_version do
sequence(:name) { |n| Faker::Lorem.words(number: rand(2..4)).join(' ') + " ##{n}" }
supplier_order_unit { 'XBO' } # TODO
group_order_unit { 'XBO' } # TODO
supplier_order_unit { 'XPK' } # TODO
group_order_unit { 'XPK' } # TODO
billing_unit { 'XPK' } # TODO
price { rand(0.1..26.0).round(2) }
tax { [6, 21].sample }
deposit { rand(10) < 8 ? 0 : [0.0, 0.80, 1.20, 12.00].sample }
@@ -13,11 +14,17 @@
transient do
article_unit_ratio_count { 1 }
unit_quantity { 1 }
unit { nil }
end

after(:create) do |article_version, evaluator|
unless evaluator.unit_quantity.nil?
article_version.group_order_unit = 'XPP'
article_version.save
end
unless evaluator.unit.nil?
article_version.supplier_order_unit = nil
article_version.unit = evaluator.unit
article_version.save
end
build_list(:article_unit_ratio, evaluator.article_unit_ratio_count,
10 changes: 5 additions & 5 deletions spec/fixtures/foodsoft_file_01.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
status;art. nummer;productnaam;notitie;producent;herkomst;eenheid;prijs ex btw;btw (%);statiegeld;colligrootte;(reserved);(reserved);categorienaam
;29932;Walnoten (ongeroosterd);bio ◎;Het grote bomenbos;Veluwe, NL;kg;2.34;6;0;1;;;Nuts
;28391;Pijnboompitten;dem;Het warme woud;TR;100g;5.56;6;0;10;;;Nuts
;1829;Appelsap (verpakt);;Appelgaarde;DE;4x250ml;3.21;6;0.4;10;;;Drinks
;177813;Tomaten;bio;De röde hof;Best, NL;500 g;1.2;6;0;20;;;Vegetables
avail.;Order number;Name;Note;Manufacturer;Origin;Unit;Price (net);VAT;Deposit;Supplier order unit;Price unit;Group order unit;Group order granularity;Minimum order quantity;Billing unit;Category;Ratios to supplier order unit
Yes;29932;Walnoten (ongeroosterd);bio ◎;Het grote bomenbos;Veluwe, NL;kg;2.34;6;0;;;;1;;;Nuts;
Yes;28391;Pijnboompitten;dem;Het warme woud;TR;100g;5.56;6;0;;;;1;;;Nuts;10 Piece
Yes;1829;Appelsap (verpakt);;Appelgaarde;DE;4x250ml;3.21;6;0.4;;;;1;;;Drinks;10 Piece
Yes;177813;Tomaten;bio;De röde hof;Best, NL;500 g;1.2;6;0;;;;1;;;Vegetables;20 Piece
Binary file modified spec/fixtures/foodsoft_file_01.ods
Binary file not shown.
Binary file modified spec/fixtures/foodsoft_file_01.xls
Binary file not shown.
Binary file modified spec/fixtures/foodsoft_file_01.xlsx
Binary file not shown.
4 changes: 2 additions & 2 deletions spec/fixtures/foodsoft_file_02.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
state;art. nummer;name;note;producer;origin;unit;net price;vat (%);deposit;unit quantity;(reserved);(reserved);category
;1;Tomatoes;organic;Tommy farm;Somewhere, UK;500 g;1.2;6;0;20;;;Vegetables
avail.;Order number;Name;Note;Manufacturer;Origin;Unit;Price (net);VAT;Deposit;Supplier order unit;Price unit;Group order unit;Group order granularity;Minimum order quantity;Billing unit;Category;Ratios to supplier order unit
Yes;1;Tomatoes;organic;Tommy farm;Somewhere, UK;500 g;1.2;6;0;;;;1;;;Vegetables;20 Piece
51 changes: 27 additions & 24 deletions spec/integration/articles_spec.rb
Original file line number Diff line number Diff line change
@@ -3,9 +3,13 @@
feature ArticlesController do
let(:user) { create(:user, groups: [create(:workgroup, role_article_meta: true)]) }
let(:supplier) { create(:supplier) }
let!(:article_unit) { create(:article_unit, unit: 'XPK') }
let!(:article_category) { create(:article_category) }

before { login user }
before do
login user
create(:article_unit, unit: 'XPP')
end

describe ':index', :js do
before { visit supplier_articles_path(supplier_id: supplier.id) }
@@ -18,20 +22,18 @@
it 'can create a new article' do
click_on I18n.t('articles.index.new')
expect(page).to have_css('form#new_article_version')
article = build(:article, supplier: supplier, article_category: article_category)
article_version = build(:article_version, supplier_order_unit: article_unit.unit)
within('#new_article_version') do
fill_in 'article_version_name', with: article.name
fill_in 'article_version_unit', with: article.unit
select article.article_category.name, from: 'article_article_category_id'
fill_in 'article_version_price', with: article.price
fill_in 'article_version_unit_quantity', with: article.unit_quantity
fill_in 'article_version_tax', with: article.tax
fill_in 'article_version_deposit', with: article.deposit
# "Element cannot be scrolled into view" error, js as workaround
# find('input[type="submit"]').click
page.execute_script('$("form#new_article_version").submit();')
fill_in 'article_version_name', with: article_version.name
select article_category.name, from: 'article_version_article_category_id'
fill_in 'article_version_price', with: article_version.price
unit_label = ArticleUnitsLib.units[article_version.supplier_order_unit][:name]
select unit_label, from: 'article_version_supplier_order_unit'
fill_in 'article_version_tax', with: article_version.tax
fill_in 'article_version_deposit', with: article_version.deposit
find('input[type="submit"]').click
end
expect(page).to have_content(article.name)
expect(page).to have_content(article_version.name)
end
end

@@ -40,6 +42,9 @@
let(:file) { Rails.root.join("spec/fixtures/#{filename}") }

before do
create(:article_category, name: 'Nuts & Seeds')
create(:article_category, name: 'Drinks')
create(:article_category, name: 'Vegetables')
visit upload_supplier_articles_path(supplier_id: supplier.id)
attach_file 'articles_file', file
end
@@ -50,12 +55,9 @@

it do
find('input[type="submit"]').click
expect(find('tr:nth-child(1) #new_articles__note').value).to eq 'bio ◎'
expect(find('tr:nth-child(2) #new_articles__name').value).to eq 'Pijnboompitten'
expect(find('tr:nth-child(1) #new_articles_0_note').value).to eq 'bio ◎'
expect(find('tr:nth-child(2) #new_articles_1_name').value).to eq 'Pijnboompitten'

4.times do |i|
all("tr:nth-child(#{i + 1}) select > option")[1].select_option
end
find('input[type="submit"]').click
expect(page).to have_content('Pijnboompitten')

@@ -69,7 +71,8 @@

it do
find('input[type="submit"]').click
expect(find("#articles_#{article.id}_name").value).to eq 'Tomatoes'
expect(find_by_id('articles_0_name').value).to eq 'Tomatoes'
expect(find_by_id('articles_0_id', visible: false).value).to eq article.latest_article_version.id.to_s
find('input[type="submit"]').click
article.reload
expect(article.name).to eq 'Tomatoes'
@@ -80,11 +83,12 @@
describe 'handles missing data' do
it do
find('input[type="submit"]').click # to overview
find('input[type="submit"]').click # missing category, re-show form
fill_in 'new_articles_0_name', with: ''
find('input[type="submit"]').click # missing name, re-show form
expect(find('tr.alert')).to be_present
expect(supplier.articles.count).to eq 0

all('tr select > option')[1].select_option
fill_in 'new_articles_0_name', with: 'Test'
find('input[type="submit"]').click # now it should succeed
expect(supplier.articles.count).to eq 1
end
@@ -96,9 +100,8 @@
it do
check('articles_outlist_absent')
find('input[type="submit"]').click
expect(find("#outlisted_articles_#{article.id}", visible: :all)).to be_present
expect(find_by_id('outlisted_articles_0', visible: :all).value).to eq article.id.to_s

all('tr select > option')[1].select_option
find('input[type="submit"]').click
expect(article.reload.deleted?).to be true
end
@@ -110,7 +113,7 @@
it do
check('articles_convert_units')
find('input[type="submit"]').click
expect(find("#articles_#{article.id}_name").value).to eq 'Tomatoes'
expect(find_by_id('articles_0_name').value).to eq 'Tomatoes'
find('input[type="submit"]').click
article.reload
expect([article.unit, article.unit_quantity, article.price]).to eq ['250 g', 40, 0.6]
8 changes: 5 additions & 3 deletions spec/integration/balancing_spec.rb
Original file line number Diff line number Diff line change
@@ -9,11 +9,13 @@
let(:order) { create(:order, supplier: supplier, article_ids: [article.id]) } # need to ref article
let(:go1) { create(:group_order, order: order) }
let(:go2) { create(:group_order, order: order) }
let(:oa) { order.order_articles.find_by_article_id(article.id) }
let(:oa) { order.order_articles.find_by_article_version_id(article.latest_article_version.id) }
let(:goa1) { create(:group_order_article, group_order: go1, order_article: oa) }
let(:goa2) { create(:group_order_article, group_order: go2, order_article: oa) }

before do
create(:article_unit, unit: 'XPP')
create(:article_unit, unit: 'XPK')
goa1.update_quantities(3, 0)
goa2.update_quantities(1, 0)
oa.update_results!
@@ -172,12 +174,12 @@
click_link I18n.t('finance.balancing.edit_results_by_articles.add_article')
expect(page).to have_css('form#new_order_article')
within('#new_order_article') do
find_by_id('order_article_article_id').select(new_article.name)
find_by_id('order_article_article_version_id').select(new_article.name)
sleep 0.25
find('input[type="submit"]').click
end
expect(page).to have_no_css('form#new_order_article')
expect(page).to have_content(new_article.name)
expect(order.order_articles.where(article_id: new_article.id)).not_to be_nil
expect(order.order_articles.where(article_version_id: new_article.latest_article_version.id)).not_to be_nil
end
end
2 changes: 1 addition & 1 deletion spec/integration/order_spec.rb
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
let(:article) { create(:article, unit_quantity: 1) }
let(:order) { create(:order, supplier: article.supplier, article_ids: [article.id]) } # need to ref article
let(:go1) { create(:group_order, order: order) }
let(:oa) { order.order_articles.find_by_article_id(article.id) }
let(:oa) { order.order_articles.find_by_article_version_id(article.latest_article_version.id) }
let(:goa1) { create(:group_order_article, group_order: go1, order_article: oa) }

before { login admin }
16 changes: 11 additions & 5 deletions spec/integration/product_distribution_example_spec.rb
Original file line number Diff line number Diff line change
@@ -24,23 +24,29 @@
login user_a
visit new_group_order_path(order_id: order.id)
scrolldown
2.times { find("[data-increase_quantity='#{oa.id}']").click }
3.times { find("[data-increase_tolerance='#{oa.id}']").click }

# expect(page).to have_css('input[type=submit]:enabled')

find(".goa-quantity[data-e2e-order-article-id='#{oa.id}']").set '2'
find(".goa-tolerance[data-e2e-order-article-id='#{oa.id}']").set '3'
close_unit_conversion_popover
find('input[type=submit]').click
expect(page).to have_selector('body')
# gruppe b bestellt 2(0)
login user_b
visit new_group_order_path(order_id: order.id)
scrolldown
2.times { find("[data-increase_quantity='#{oa.id}']").click }
find(".goa-quantity[data-e2e-order-article-id='#{oa.id}']").set '2'
close_unit_conversion_popover
find('input[type=submit]').click
expect(page).to have_css('body')
# gruppe a faellt ein dass sie doch noch mehr braucht von x und aendert auf 4(1).
login user_a
visit edit_group_order_path(id: order.group_order(user_a.ordergroup).id, order_id: order.id)
scrolldown
2.times { find("[data-increase_quantity='#{oa.id}']").click }
2.times { find("[data-decrease_tolerance='#{oa.id}']").click }
find(".goa-quantity[data-e2e-order-article-id='#{oa.id}']").set '4'
find(".goa-tolerance[data-e2e-order-article-id='#{oa.id}']").set '1'
close_unit_conversion_popover
find('input[type=submit]').click
expect(page).to have_css('body')
# die zuteilung
13 changes: 9 additions & 4 deletions spec/integration/receive_spec.rb
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
let(:order) { create(:order, supplier: supplier, article_ids: [article.id]) } # need to ref article
let(:go1) { create(:group_order, order: order) }
let(:go2) { create(:group_order, order: order) }
let(:oa) { order.order_articles.find_by_article_id(article.id) }
let(:oa) { order.order_articles.find_by_article_version_id(article.latest_article_version.id) }
let(:goa1) { create(:group_order_article, group_order: go1, order_article: oa) }
let(:goa2) { create(:group_order_article, group_order: go2, order_article: oa) }

@@ -34,6 +34,11 @@ def check_quantities(units, q1, q2)
expect(goa2.destroyed? ? 0 : goa2.result).to be_within(1e-3).of q2
end

def fill_units_field(order_article_id, with)
fill_in "order_articles_#{order_article_id}_units_received", with: with
close_unit_conversion_popover
end

before { login admin }

it 'has product ordered visible' do
@@ -58,7 +63,7 @@ def check_quantities(units, q1, q2)
it 'does not change anything when received is ordered' do
set_quantities [2, 0], [3, 2]
visit receive_order_path(id: order.id)
fill_in "order_articles_#{oa.id}_units_received", with: oa.units_to_order
fill_units_field(oa.id, oa.units_to_order)
find('input[type="submit"]').click
expect(page).to have_css('body')
check_quantities 2, 2, 4
@@ -67,7 +72,7 @@ def check_quantities(units, q1, q2)
it 'redistributes properly when received is more' do
set_quantities [2, 0], [3, 2]
visit receive_order_path(id: order.id)
fill_in "order_articles_#{oa.id}_units_received", with: 3
fill_units_field(oa.id, 3)
find('input[type="submit"]').click
expect(page).to have_css('body')
check_quantities 3, 2, 5
@@ -76,7 +81,7 @@ def check_quantities(units, q1, q2)
it 'redistributes properly when received is less' do
set_quantities [2, 0], [3, 2]
visit receive_order_path(id: order.id)
fill_in "order_articles_#{oa.id}_units_received", with: 1
fill_units_field(oa.id, 1)
find('input[type="submit"]').click
expect(page).to have_css('body')
check_quantities 1, 2, 1
4 changes: 2 additions & 2 deletions spec/models/group_order_article_spec.rb
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@

describe do
let(:article) { create(:article, supplier: order.supplier, unit_quantity: 1) }
let(:oa) { order.order_articles.create(article: article) }
let(:oa) { order.order_articles.create(article_version: article.latest_article_version) }
let(:goa) { create(:group_order_article, group_order: go, order_article: oa) }

it 'can be ordered by piece' do
@@ -65,7 +65,7 @@

describe 'distribution strategy' do
let(:article) { create(:article, supplier: order.supplier, unit_quantity: 1) }
let(:oa) { order.order_articles.create(article: article) }
let(:oa) { order.order_articles.create(article_version: article.latest_article_version) }
let(:goa) { create(:group_order_article, group_order: go, order_article: oa) }
let!(:goaq) { create(:group_order_article_quantity, group_order_article: goa, quantity: 4, tolerance: 6) }

2 changes: 1 addition & 1 deletion spec/models/order_article_spec.rb
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@ def goa_reload

it 'has expected units_to_order' do
set_quantities [3, 2], [1, 3], [1, 0]
expect(oa.units * oa.article.unit_quantity).to eq 6
expect(oa.units * oa.article_version.unit_quantity).to eq 6
expect([goa1, goa2, goa3].map(&:result)).to eq [4, 1, 1]
end

5 changes: 5 additions & 0 deletions spec/support/integration.rb
Original file line number Diff line number Diff line change
@@ -2,3 +2,8 @@
def scrolldown
page.execute_script 'window.scrollBy(0,10000)'
end

def close_unit_conversion_popover
# TODO: Make unit conversion popover more user-friendly?
find('body > .logo').click
end
13 changes: 6 additions & 7 deletions spec/swagger_helper.rb
Original file line number Diff line number Diff line change
@@ -146,15 +146,15 @@
description: 'foodcoop price'
},
quantity: {
type: :integer,
type: :float,
description: 'number of units ordered by members'
},
tolerance: {
type: :integer,
type: :float,
description: 'number of extra units that members are willing to buy to fill a box'
},
units_to_order: {
type: :integer,
type: :float,
description: 'number of units to order from the supplier'
},
article: {
@@ -298,12 +298,12 @@
properties: {
quantity:
{
type: :integer,
type: :float,
description: 'number of units ordered by the users ordergroup'
},
tolerance:
{
type: :integer,
type: :float,
description: 'number of extra units the users ordergroup is willing to buy for filling a box'
}
}
@@ -333,8 +333,7 @@
type: :integer
},
result: {
type: :number,
format: :float,
type: :float,
description: 'number of units the users ordergroup will receive or has received'
},
total_price: