2013-09-18 12:44:41 +02:00
|
|
|
require_relative '../spec_helper'
|
2013-07-14 02:49:40 +02:00
|
|
|
|
|
|
|
describe Article do
|
2023-05-12 13:01:12 +02:00
|
|
|
let(:supplier) { create(:supplier) }
|
|
|
|
let(:article) { create(:article, supplier: supplier) }
|
2013-07-14 02:49:40 +02:00
|
|
|
|
|
|
|
it 'has a unique name' do
|
2023-05-12 13:01:12 +02:00
|
|
|
article2 = build(:article, supplier: supplier, name: article.name)
|
2013-07-24 22:46:25 +02:00
|
|
|
expect(article2).to be_invalid
|
2013-07-14 02:49:40 +02:00
|
|
|
end
|
|
|
|
|
2022-10-06 12:27:34 +02:00
|
|
|
it 'can be deleted' do
|
|
|
|
expect(article).not_to be_deleted
|
|
|
|
article.mark_as_deleted
|
|
|
|
expect(article).to be_deleted
|
|
|
|
end
|
|
|
|
|
2022-10-31 16:36:06 +01:00
|
|
|
describe 'convert units' do
|
|
|
|
it 'returns nil when equal' do
|
|
|
|
expect(article.convert_units(article)).to be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false when invalid unit' do
|
2023-05-12 13:01:12 +02:00
|
|
|
article1 = build(:article, supplier: supplier, unit: 'invalid')
|
2022-10-31 16:36:06 +01:00
|
|
|
expect(article.convert_units(article1)).to be false
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'converts from ST to KI (german foodcoops legacy)' do
|
2023-05-12 13:01:12 +02:00
|
|
|
article1 = build(:article, supplier: supplier, unit: 'ST')
|
|
|
|
article2 = build(:article, supplier: supplier, name: 'banana 10-12 St', price: 12.34, unit: 'KI')
|
2022-10-31 16:36:06 +01:00
|
|
|
new_price, new_unit_quantity = article1.convert_units(article2)
|
|
|
|
expect(new_unit_quantity).to eq 10
|
|
|
|
expect(new_price).to eq 1.23
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'converts from g to kg' do
|
2023-05-12 13:01:12 +02:00
|
|
|
article1 = build(:article, supplier: supplier, unit: 'kg')
|
|
|
|
article2 = build(:article, supplier: supplier, unit: 'g', price: 0.12, unit_quantity: 1500)
|
2022-10-31 16:36:06 +01:00
|
|
|
new_price, new_unit_quantity = article1.convert_units(article2)
|
|
|
|
expect(new_unit_quantity).to eq 1.5
|
|
|
|
expect(new_price).to eq 120
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'computes changed article attributes' do
|
2023-05-12 13:01:12 +02:00
|
|
|
article2 = build(:article, supplier: supplier, name: 'banana')
|
2022-10-31 16:36:06 +01:00
|
|
|
expect(article.unequal_attributes(article2)[:name]).to eq 'banana'
|
|
|
|
end
|
|
|
|
|
2013-07-14 02:49:40 +02:00
|
|
|
it 'computes the gross price correctly' do
|
|
|
|
article.deposit = 0
|
|
|
|
article.tax = 12
|
2013-07-24 22:46:25 +02:00
|
|
|
expect(article.gross_price).to eq((article.price * 1.12).round(2))
|
2013-07-14 02:49:40 +02:00
|
|
|
article.deposit = 1.20
|
2013-07-24 22:46:25 +02:00
|
|
|
expect(article.gross_price).to eq(((article.price + 1.20) * 1.12).round(2))
|
2013-07-14 02:49:40 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'gross price >= net price' do
|
2013-07-24 22:46:25 +02:00
|
|
|
expect(article.gross_price).to be >= article.price
|
2013-07-14 02:49:40 +02:00
|
|
|
end
|
|
|
|
|
2023-06-16 13:04:03 +02:00
|
|
|
[[nil, 1],
|
|
|
|
[0, 1],
|
|
|
|
[5, 1.05],
|
|
|
|
[42, 1.42],
|
|
|
|
[100, 2]].each do |price_markup, percent|
|
|
|
|
it "computes the fc price with price_markup #{price_markup} correctly" do
|
|
|
|
FoodsoftConfig.config['price_markup'] = price_markup
|
|
|
|
expect(article.fc_price).to eq((article.gross_price * percent).round(2))
|
|
|
|
end
|
2013-07-14 02:49:40 +02:00
|
|
|
end
|
|
|
|
it 'knows when it is deleted' do
|
2014-08-19 11:39:33 +02:00
|
|
|
expect(supplier.deleted?).to be false
|
2013-07-14 02:49:40 +02:00
|
|
|
supplier.mark_as_deleted
|
2014-08-19 11:39:33 +02:00
|
|
|
expect(supplier.deleted?).to be true
|
2013-07-14 02:49:40 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'keeps a price history' do
|
2014-02-20 15:04:53 +01:00
|
|
|
expect(article.article_prices.map(&:price)).to eq([article.price])
|
2013-07-14 02:49:40 +02:00
|
|
|
oldprice = article.price
|
2013-07-25 00:01:58 +02:00
|
|
|
sleep 1 # so that the new price really has a later creation time
|
2013-07-14 02:49:40 +02:00
|
|
|
article.price += 1
|
|
|
|
article.save!
|
2014-02-20 15:04:53 +01:00
|
|
|
expect(article.article_prices.reload.map(&:price)).to eq([article.price, oldprice])
|
2013-07-14 02:49:40 +02:00
|
|
|
end
|
2013-09-18 22:27:53 +02:00
|
|
|
|
|
|
|
it 'is not in an open order by default' do
|
|
|
|
expect(article.in_open_order).to be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is knows its open order' do
|
2023-05-12 13:01:12 +02:00
|
|
|
order = create(:order, supplier: supplier, article_ids: [article.id])
|
2013-09-18 22:27:53 +02:00
|
|
|
expect(article.in_open_order).to eq(order)
|
|
|
|
end
|
2013-11-13 23:09:17 +01:00
|
|
|
|
|
|
|
it 'has no shared article by default' do
|
|
|
|
expect(article.shared_article).to be_nil
|
|
|
|
end
|
|
|
|
|
2023-05-12 13:01:12 +02:00
|
|
|
describe 'connected to a shared database', type: :feature do
|
|
|
|
let(:shared_article) { create(:shared_article) }
|
|
|
|
let(:supplier) { create(:supplier, shared_supplier_id: shared_article.supplier_id) }
|
|
|
|
let(:article) { create(:article, supplier: supplier, order_number: shared_article.order_number) }
|
2013-11-13 23:09:17 +01:00
|
|
|
|
|
|
|
it 'can be found in the shared database' do
|
2023-05-12 13:01:12 +02:00
|
|
|
expect(article.shared_article).not_to be_nil
|
2013-11-13 23:09:17 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'can find updates' do
|
|
|
|
changed = article.shared_article_changed?
|
2023-05-12 13:01:12 +02:00
|
|
|
expect(changed).not_to be_falsey
|
2013-11-13 23:09:17 +01:00
|
|
|
expect(changed.length).to be > 1
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'can be synchronised' do
|
2023-05-12 13:01:12 +02:00
|
|
|
# TODO: move article sync from supplier to article
|
2013-11-13 23:09:17 +01:00
|
|
|
article # need to reference for it to exist when syncing
|
2021-03-01 15:27:26 +01:00
|
|
|
updated_article = supplier.sync_all[0].select { |s| s[0].id == article.id }.first[0]
|
2023-05-12 13:01:12 +02:00
|
|
|
article.update(updated_article.attributes.reject { |k, _v| %w[id type].include?(k) })
|
2013-11-13 23:09:17 +01:00
|
|
|
expect(article.name).to eq(shared_article.name)
|
|
|
|
# now synchronising shouldn't change anything anymore
|
2014-08-19 11:39:33 +02:00
|
|
|
expect(article.shared_article_changed?).to be_falsey
|
2013-11-13 23:09:17 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not need to synchronise an imported article' do
|
2014-11-21 14:37:56 +01:00
|
|
|
article = shared_article.build_new_article(supplier)
|
2015-01-14 21:20:14 +01:00
|
|
|
article.article_category = create :article_category
|
2014-08-19 11:39:33 +02:00
|
|
|
expect(article.shared_article_changed?).to be_falsey
|
2013-11-13 23:09:17 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'adapts to foodcoop units when synchronising' do
|
|
|
|
shared_article.unit = '1kg'
|
|
|
|
shared_article.unit_quantity = 1
|
|
|
|
shared_article.save!
|
2014-11-21 14:37:56 +01:00
|
|
|
article = shared_article.build_new_article(supplier)
|
2013-11-13 23:09:17 +01:00
|
|
|
article.article_category = create :article_category
|
|
|
|
article.unit = '200g'
|
|
|
|
article.shared_updated_on -= 1 # to make update do something
|
|
|
|
article.save!
|
2023-05-12 13:01:12 +02:00
|
|
|
# TODO: get sync functionality in article
|
2021-03-01 15:27:26 +01:00
|
|
|
updated_article = supplier.sync_all[0].select { |s| s[0].id == article.id }.first[0]
|
2023-05-12 13:01:12 +02:00
|
|
|
article.update!(updated_article.attributes.reject { |k, _v| %w[id type].include?(k) })
|
2013-11-13 23:09:17 +01:00
|
|
|
expect(article.unit).to eq '200g'
|
|
|
|
expect(article.unit_quantity).to eq 5
|
2021-03-01 15:27:26 +01:00
|
|
|
expect(article.price).to be_within(0.005).of(shared_article.price / 5)
|
2013-11-13 23:09:17 +01:00
|
|
|
end
|
2014-01-24 22:10:00 +01:00
|
|
|
|
|
|
|
it 'does not synchronise when it has no order number' do
|
2022-10-13 18:25:52 +02:00
|
|
|
article.update(order_number: nil)
|
2014-05-21 21:24:03 +02:00
|
|
|
expect(supplier.sync_all).to eq [[], [], []]
|
2014-01-24 22:10:00 +01:00
|
|
|
end
|
2013-11-13 23:09:17 +01:00
|
|
|
end
|
2013-07-14 02:49:40 +02:00
|
|
|
end
|