Compare commits

..

4 commits

21 changed files with 69 additions and 17 deletions

View file

@ -51,7 +51,7 @@ gem 'ice_cube'
# At time of development 01-06-2022 mmddyyyy necessary fix for config_helper.rb form builder was not in rubygems so we pull from github, see: https://github.com/gregschmit/recurring_select/pull/152 # At time of development 01-06-2022 mmddyyyy necessary fix for config_helper.rb form builder was not in rubygems so we pull from github, see: https://github.com/gregschmit/recurring_select/pull/152
gem 'recurring_select', git: 'https://github.com/gregschmit/recurring_select' gem 'recurring_select', git: 'https://github.com/gregschmit/recurring_select'
# TODO: publish gem on github # TODO: publish gem on github
gem 'foodsoft_article_import', git: 'https://git.local-it.org/Foodsoft/foodsoft_article_import', tag: 'v0.1' gem 'foodsoft_article_import', git: 'https://git.local-it.org/Foodsoft/foodsoft_article_import', tag: 'v1.9'
gem 'roo' gem 'roo'
gem 'roo-xls' gem 'roo-xls'
gem 'spreadsheet' gem 'spreadsheet'

View file

@ -1,11 +1,10 @@
GIT GIT
remote: https://git.local-it.org/Foodsoft/foodsoft_article_import remote: https://git.local-it.org/Foodsoft/foodsoft_article_import
revision: c7e432c247ca6aa327ae889d22f78227efed2479 revision: 573851e5497758e1d27d2199f03b939e6bda9e35
tag: v0.1 tag: v1.9
specs: specs:
foodsoft_article_import (1.0.0) foodsoft_article_import (1.0.0)
roo (~> 2.9.0) roo (~> 2.9.0)
simplecov
GIT GIT
remote: https://github.com/gregschmit/recurring_select remote: https://github.com/gregschmit/recurring_select

View file

@ -51,7 +51,7 @@ class Article < ApplicationRecord
has_many :orders, through: :order_articles has_many :orders, through: :order_articles
# Replace numeric seperator with database format # Replace numeric seperator with database format
localize_input_of :price, :tax, :deposit localize_input_of :price, :tax, :deposit, :price_per
# Get rid of unwanted whitespace. {Unit#new} may even bork on whitespace. # Get rid of unwanted whitespace. {Unit#new} may even bork on whitespace.
normalize_attributes :name, :unit, :note, :manufacturer, :origin, :order_number normalize_attributes :name, :unit, :note, :manufacturer, :origin, :order_number
@ -142,7 +142,14 @@ class Article < ApplicationRecord
new_unit_quantity = new_article.unit_quantity new_unit_quantity = new_article.unit_quantity
new_unit = new_article.unit new_unit = new_article.unit
end end
puts "
" + "______________" + "
" + "______________" + "
" + "_____oha_________" + "
" + "#{new_article.unit_symbol}" + "
" + "______________"+ "
" + "______________"+ "
" + "______________"
return Article.compare_attributes( return Article.compare_attributes(
{ {
:name => [self.name, new_article.name], :name => [self.name, new_article.name],
@ -152,6 +159,8 @@ class Article < ApplicationRecord
:price => [self.price.to_f.round(2), new_price.to_f.round(2)], :price => [self.price.to_f.round(2), new_price.to_f.round(2)],
:tax => [self.tax, new_article.tax], :tax => [self.tax, new_article.tax],
:deposit => [self.deposit.to_f.round(2), new_article.deposit.to_f.round(2)], :deposit => [self.deposit.to_f.round(2), new_article.deposit.to_f.round(2)],
:price_per => [self.price_per.to_f.round(2), new_article.price_per.to_f.round(2)],
:unit_symbol => [self.unit_symbol, new_article.unit_symbol],
# take care of different num-objects. # take care of different num-objects.
:unit_quantity => [self.unit_quantity.to_s.to_f, new_unit_quantity.to_s.to_f], :unit_quantity => [self.unit_quantity.to_s.to_f, new_unit_quantity.to_s.to_f],
:note => [self.note.to_s, new_article.note.to_s] :note => [self.note.to_s, new_article.note.to_s]

View file

@ -12,6 +12,14 @@ module PriceCalculation
add_percent(gross_price, FoodsoftConfig[:price_markup]) add_percent(gross_price, FoodsoftConfig[:price_markup])
end end
def fc_price_per
if price_per > 0
add_percent(add_percent(price_per, tax), FoodsoftConfig[:price_markup])
else
fc_price
end
end
private private
def add_percent(value, percent) def add_percent(value, percent)

View file

@ -45,6 +45,8 @@ class GroupOrder < ApplicationRecord
# Build hash with relevant data # Build hash with relevant data
data[:order_articles][order_article.id] = { data[:order_articles][order_article.id] = {
:price => order_article.article.fc_price, :price => order_article.article.fc_price,
:price_per => order_article.article.fc_price_per,
:unit_symbol => order_article.article.unit_symbol,
:unit => order_article.article.unit_quantity, :unit => order_article.article.unit_quantity,
:quantity => (goa ? goa.quantity : 0), :quantity => (goa ? goa.quantity : 0),
:others_quantity => order_article.quantity - (goa ? goa.quantity : 0), :others_quantity => order_article.quantity - (goa ? goa.quantity : 0),

View file

@ -19,8 +19,10 @@ class SharedArticle < ApplicationRecord
:unit_quantity => unit_quantity, :unit_quantity => unit_quantity,
:order_number => number, :order_number => number,
:article_category => ArticleCategory.find_match(category), :article_category => ArticleCategory.find_match(category),
:price_per => price_per,
:unit_symbol => unit_symbol,
# convert to db-compatible-string # convert to db-compatible-string
:shared_updated_on => updated_on.to_formatted_s(:db) :shared_updated_on => updated_on.to_fs(:db)
) )
end end
end end

View file

@ -88,7 +88,6 @@ class Supplier < ApplicationRecord
new_attrs[:article_category] = ArticleCategory.find_match(new_attrs[:article_category]) new_attrs[:article_category] = ArticleCategory.find_match(new_attrs[:article_category])
new_attrs[:tax] ||= FoodsoftConfig[:tax_default] new_attrs[:tax] ||= FoodsoftConfig[:tax_default]
new_article = articles.build(new_attrs) new_article = articles.build(new_attrs)
if status.nil? if status.nil?
if article.nil? if article.nil?
new_articles << new_article new_articles << new_article
@ -113,6 +112,7 @@ class Supplier < ApplicationRecord
if options[:outlist_absent] if options[:outlist_absent]
outlisted_articles += articles.undeleted.where.not(order_number: all_order_numbers + [nil]) outlisted_articles += articles.undeleted.where.not(order_number: all_order_numbers + [nil])
end end
# TODO: change price_per to scale factor
return [updated_article_pairs, outlisted_articles, new_articles] return [updated_article_pairs, outlisted_articles, new_articles]
end end

View file

@ -1,5 +1,6 @@
= simple_form_for [@supplier, @article], :validate => true, :remote => true do |f| = simple_form_for [@supplier, @article], :validate => true, :remote => true do |f|
= f.hidden_field :shared_updated_on = f.hidden_field :shared_updated_on
= f.hidden_field :unit_symbol
= f.hidden_field :supplier_id = f.hidden_field :supplier_id
.modal-header .modal-header
= close_button :modal = close_button :modal

View file

@ -17,14 +17,14 @@
%i %i
= t '.update.update_msg', count: @updated_article_pairs.size = t '.update.update_msg', count: @updated_article_pairs.size
= t '.update.body' = 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: %w(shared_updated_on unit_symbol)
%hr/ %hr/
- if @new_articles.any? - if @new_articles.any?
%h2= t '.upnew.title' %h2= t '.upnew.title'
%p %p
%i= t '.upnew.body_count', count: @new_articles.length %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(shared_updated_on order_number availability unit_symbol)
%hr/ %hr/
- if ignored_article_count > 0 - if ignored_article_count > 0

View file

@ -8,6 +8,7 @@
%th= heading_helper Article, :unit %th= heading_helper Article, :unit
%th= heading_helper Article, :unit_quantity, short: true %th= heading_helper Article, :unit_quantity, short: true
%th= heading_helper Article, :price %th= heading_helper Article, :price
%th= heading_helper Article, :price_per
%th= heading_helper Article, :tax %th= heading_helper Article, :tax
%th= heading_helper Article, :deposit %th= heading_helper Article, :deposit
%th= heading_helper Article, :article_category %th= heading_helper Article, :article_category
@ -23,6 +24,7 @@
%td= article.unit %td= article.unit
%td= article.unit_quantity %td= article.unit_quantity
%td= number_to_currency article.price %td= number_to_currency article.price
%td= number_to_currency article.price_per.round(2)
%td= number_to_percentage article.tax %td= number_to_percentage article.tax
%td= number_to_currency article.deposit %td= number_to_currency article.deposit
%td= article.article_category.name if article.article_category %td= article.article_category.name if article.article_category
@ -41,6 +43,10 @@
.input-prepend .input-prepend
%span.add-on= t 'number.currency.format.unit' %span.add-on= t 'number.currency.format.unit'
= form.text_field 'price', class: 'input-mini', style: 'width: 45px' = form.text_field 'price', class: 'input-mini', style: 'width: 45px'
%td{:style => highlight_new(attrs, :price_per)}
.input-prepend
%span.add-on= t 'number.currency.format.unit'
= form.text_field 'price_per', class: 'input-mini', style: 'width: 45px'
%td{:style => highlight_new(attrs, :tax)} %td{:style => highlight_new(attrs, :tax)}
.input-append .input-append
= form.text_field 'tax', class: 'input-mini', style: 'width: 45px' = form.text_field 'tax', class: 'input-mini', style: 'width: 45px'

View file

@ -77,6 +77,7 @@
%th{style: 'width:120px'}= heading_helper StockArticle, :supplier %th{style: 'width:120px'}= heading_helper StockArticle, :supplier
%th{style: "width:13px;"} %th{style: "width:13px;"}
%th{style: "width:4.5em;"}= t '.price' %th{style: "width:4.5em;"}= t '.price'
%th{style: "width:4.5em;"}= t '.price_per'
%th{style: "width:4.5em;"}= heading_helper Article, :unit %th{style: "width:4.5em;"}= heading_helper Article, :unit
- unless @order.stockit? - unless @order.stockit?
%th{style: "width:70px;"}= heading_helper OrderArticle, :missing_units, short: true %th{style: "width:70px;"}= heading_helper OrderArticle, :missing_units, short: true
@ -100,6 +101,7 @@
%td= truncate order_article.article.supplier.name, length: 15 %td= truncate order_article.article.supplier.name, length: 15
%td= h order_article.article.origin %td= h order_article.article.origin
%td= number_to_currency(@ordering_data[:order_articles][order_article.id][:price]) %td= number_to_currency(@ordering_data[:order_articles][order_article.id][:price])
%td= "#{number_to_currency(@ordering_data[:order_articles][order_article.id][:price_per])}/#{@ordering_data[:order_articles][order_article.id][:unit_symbol]||@ordering_data[:order_articles][order_article.id][:unit]}"
%td= order_article.article.unit %td= order_article.article.unit
%td %td
- if @order.stockit? - if @order.stockit?

View file

@ -1052,6 +1052,7 @@ de:
action_save: Bestellung speichern action_save: Bestellung speichern
new_funds: Neuer Kontostand new_funds: Neuer Kontostand
price: Preis price: Preis
price_per: Preis je Mengeneinheit (ohne Pfand)
reset_article_search: Suche zurücksetzen reset_article_search: Suche zurücksetzen
search_article: Artikel suchen... search_article: Artikel suchen...
sum_amount: Gesamtbestellmenge bisher sum_amount: Gesamtbestellmenge bisher

View file

@ -1054,6 +1054,7 @@ en:
action_save: Save order action_save: Save order
new_funds: New account balance new_funds: New account balance
price: Price price: Price
price_per: Price per quantity unit (without deposit)
reset_article_search: Reset search reset_article_search: Reset search
search_article: Search for articles... search_article: Search for articles...
sum_amount: Current amount sum_amount: Current amount

View file

@ -929,6 +929,7 @@ es:
action_save: Guardar pedido action_save: Guardar pedido
new_funds: Nuevo balance de cuenta new_funds: Nuevo balance de cuenta
price: Precio price: Precio
price_per: Precio por unidad de cantidad (sin depósito)
reset_article_search: Reinicia la búsqueda reset_article_search: Reinicia la búsqueda
search_article: Busca artículos... search_article: Busca artículos...
sum_amount: Cantidad actual sum_amount: Cantidad actual

View file

@ -678,6 +678,7 @@ fr:
action_save: Enregistrer ta commande action_save: Enregistrer ta commande
new_funds: Nouveau solde new_funds: Nouveau solde
price: Prix price: Prix
price_per: Prix par unité de quantité (sans consigne)
reset_article_search: Réinitialiser la recherche reset_article_search: Réinitialiser la recherche
search_article: Rechercher des produits... search_article: Rechercher des produits...
sum_amount: Quantité déjà commandée sum_amount: Quantité déjà commandée

View file

@ -1024,6 +1024,7 @@ nl:
action_save: Bestelling opslaan action_save: Bestelling opslaan
new_funds: Nieuw tegoed new_funds: Nieuw tegoed
price: Prijs price: Prijs
price_per: Prijs per hoeveelheidseenheid (zonder statiegeld)
reset_article_search: Alles tonen reset_article_search: Alles tonen
search_article: Artikelen zoeken... search_article: Artikelen zoeken...
sum_amount: Huidig totaalbedrag sum_amount: Huidig totaalbedrag

View file

@ -0,0 +1,6 @@
class AddPricePerToArticles < ActiveRecord::Migration[7.0]
def change
add_column :articles, :price_per, :float, default: 0.0
add_column :articles, :unit_symbol, :string
end
end

View file

@ -10,7 +10,17 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_01_06_144440) do ActiveRecord::Schema[7.0].define(version: 2023_02_20_214408) do
create_table "action_text_rich_texts", charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t|
t.string "name", null: false
t.text "body", size: :long
t.string "record_type", null: false
t.bigint "record_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true
end
create_table "active_storage_attachments", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| create_table "active_storage_attachments", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t|
t.string "name", null: false t.string "name", null: false
t.string "record_type", null: false t.string "record_type", null: false
@ -75,6 +85,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_06_144440) do
t.datetime "deleted_at", precision: nil t.datetime "deleted_at", precision: nil
t.string "type" t.string "type"
t.integer "quantity", default: 0 t.integer "quantity", default: 0
t.float "price_per", default: 0.0
t.string "unit_symbol"
t.index ["article_category_id"], name: "index_articles_on_article_category_id" t.index ["article_category_id"], name: "index_articles_on_article_category_id"
t.index ["name", "supplier_id"], name: "index_articles_on_name_and_supplier_id" t.index ["name", "supplier_id"], name: "index_articles_on_name_and_supplier_id"
t.index ["supplier_id"], name: "index_articles_on_supplier_id" t.index ["supplier_id"], name: "index_articles_on_supplier_id"
@ -282,7 +294,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_06_144440) do
create_table "messages", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| create_table "messages", id: :integer, charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t|
t.integer "sender_id" t.integer "sender_id"
t.string "subject", null: false t.string "subject", null: false
t.text "body"
t.boolean "private", default: false t.boolean "private", default: false
t.datetime "created_at", precision: nil t.datetime "created_at", precision: nil
t.integer "reply_to" t.integer "reply_to"

View file

@ -7,6 +7,7 @@ FactoryBot.define do
tax { [6, 21].sample } tax { [6, 21].sample }
deposit { rand(10) < 8 ? 0 : [0.0, 0.80, 1.20, 12.00].sample } deposit { rand(10) < 8 ? 0 : [0.0, 0.80, 1.20, 12.00].sample }
unit_quantity { rand(5) < 3 ? 1 : rand(1..20) } unit_quantity { rand(5) < 3 ? 1 : rand(1..20) }
price_per { rand(0.1..26.0).round(2) }
factory :article do factory :article do
sequence(:name) { |n| Faker::Lorem.words(number: rand(2..4)).join(' ') + " ##{n}" } sequence(:name) { |n| Faker::Lorem.words(number: rand(2..4)).join(' ') + " ##{n}" }

View file

@ -1,5 +1,5 @@
BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1 BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1
29932;;;;4280001958081;4280001958203;Walnoten (ongeroosterd);bio;;;med;;GR;C%;DE-?KO-001;120;1302;10;55;;1;;1;1 kg;1;N;930190;99260;;1,41;;;;1;;;4,49;2,34;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;28,571;; 29932;;;;4280001958081;4280001958203;Walnoten (ongeroosterd);bio;;;med;;GR;C%;DE-?KO-001;120;1302;10;55;;1;;1;1 kg;1;N;930190;99260;;1,41;;;;1;;;4,49;2,34;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;1;;
28391;;;;4280001958081;4280001958203;Pijnboompitten;dem;;;med;;GR;C%;DE-?KO-001;120;1302;10;55;;1;;1;100 g;10;N;930190;99260;;1,41;;;;1;;;5,56;2.89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;28,571;; 28391;;;;4280001958081;4280001958203;Pijnboompitten;dem;;;med;;GR;C%;DE-?KO-001;120;1302;10;55;;1;;1;100 g;10;N;930190;99260;;1,41;;;;1;;;5,56;2.89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;10;;
1829;;;;4280001958081;4280001958203;Appelsap (verpakt);;;;med;;GR;C%;DE-?KO-001;120;1302;10;55;;1;4x250 ml;10;4x250 ml;10;N;930190;99260;;3,21;;;;1;;;4,49;2.89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;ml;28,571;; 1829;;;;4280001958081;4280001958203;Appelsap (verpakt);;;;med;;GR;C%;DE-?KO-001;120;1302;10;55;;1;4x250 ml;10;4x250 ml;10;N;930190;99260;;3,21;;;;1;;;4,49;2.89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;l;4;;
177813;;;;4280001958081;4280001958203;Tomaten;bio;;;med;;GR;C%;DE-?KO-001;120;1302;10;55;;1;;1;500 g;20;N;930190;99260;;1,20;;;;1;;;4,49;2.89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;g;28,571;; 177813;;;;4280001958081;4280001958203;Tomaten;bio;;;med;;GR;C%;DE-?KO-001;120;1302;10;55;;1;;1;500 g;20;N;930190;99260;;1,20;;;;1;;;4,49;2.89;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;2;;

View file

@ -1,2 +1,2 @@
BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1 BNN;3;0;Naturkost Nord, Hamburg;T;Angebot Nr. 0922;EUR;20220905;20221001;20220825;837;1
1;;;;4280001958081;4280001958203;Tomatoes;organic;;;med;;GR;C%;DE-?KO-001;120;1302;10;55;;1;;20;500 g;1;N;930190;99260;;1,41;;;;1;;;4,49;1,20;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;g;28,571;; 1;;;;4280001958081;4280001958203;Tomatoes;organic;;;med;;GR;C%;DE-?KO-001;120;1302;10;55;;1;;20;500 g;1;N;930190;99260;;1,41;;;;1;;;4,49;1,20;J;;2;3;;;;;;;;;;;;;;;;;;;A;;;;;Kg;2;;