Add option to ignore delivered amounts in order group distribution (#765)
This commit is contained in:
parent
ecda1c1478
commit
45a8911ca6
11 changed files with 69 additions and 4 deletions
|
@ -128,15 +128,18 @@ class GroupOrderArticle < ApplicationRecord
|
||||||
order_quantities = GroupOrderArticleQuantity.where(group_order_article_id: order_article.group_order_article_ids).order('created_on')
|
order_quantities = GroupOrderArticleQuantity.where(group_order_article_id: order_article.group_order_article_ids).order('created_on')
|
||||||
logger.debug "GroupOrderArticleQuantity records found: #{order_quantities.size}"
|
logger.debug "GroupOrderArticleQuantity records found: #{order_quantities.size}"
|
||||||
|
|
||||||
|
first_order_first_serve = (FoodsoftConfig[:distribution_strategy] == FoodsoftConfig::DistributionStrategy::FIRST_ORDER_FIRST_SERVE)
|
||||||
|
|
||||||
# Determine quantities to be ordered...
|
# Determine quantities to be ordered...
|
||||||
order_quantities.each do |goaq|
|
order_quantities.each do |goaq|
|
||||||
q = [goaq.quantity, total - total_quantity].min
|
q = goaq.quantity
|
||||||
|
q = [q, total - total_quantity].min if first_order_first_serve
|
||||||
total_quantity += q
|
total_quantity += q
|
||||||
if goaq.group_order_article_id == self.id
|
if goaq.group_order_article_id == self.id
|
||||||
logger.debug "increasing quantity by #{q}"
|
logger.debug "increasing quantity by #{q}"
|
||||||
quantity += q
|
quantity += q
|
||||||
end
|
end
|
||||||
break if total_quantity >= total
|
break if total_quantity >= total && first_order_first_serve
|
||||||
end
|
end
|
||||||
|
|
||||||
# Determine tolerance to be ordered...
|
# Determine tolerance to be ordered...
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
class ConfigSerializer < ActiveModel::Serializer
|
class ConfigSerializer < ActiveModel::Serializer
|
||||||
|
|
||||||
# details
|
# details
|
||||||
attributes :name, :homepage, :contact
|
attributes :name, :homepage, :contact
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
attributes :currency_unit, :currency_space, :default_locale, :price_markup,
|
attributes :currency_unit, :currency_space, :default_locale, :price_markup,
|
||||||
:tolerance_is_costly, :use_apple_points, :use_tolerance
|
:tolerance_is_costly, :distribution_strategy, :use_apple_points, :use_tolerance
|
||||||
|
|
||||||
# layout
|
# layout
|
||||||
attributes :page_footer_html, :webstats_tracking_code_html
|
attributes :page_footer_html, :webstats_tracking_code_html
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
= config_input form, :use_nick, as: :boolean
|
= config_input form, :use_nick, as: :boolean
|
||||||
= config_input form, :tolerance_is_costly, as: :boolean
|
= config_input form, :tolerance_is_costly, as: :boolean
|
||||||
|
- distribution_strategy_options = FoodsoftConfig::DistributionStrategy.constants.map { |c| FoodsoftConfig::DistributionStrategy.const_get(c) }
|
||||||
|
= config_input form, :distribution_strategy, as: :select, collection: distribution_strategy_options,
|
||||||
|
include_blank: false, input_html: {class: 'input-xxlarge'}, label_method: ->(s){ t("config.keys.distribution_strategy_options.#{s}") }
|
||||||
= config_input form, :disable_invite, as: :boolean
|
= config_input form, :disable_invite, as: :boolean
|
||||||
= config_input form, :help_url, as: :url, input_html: {class: 'input-xlarge'}
|
= config_input form, :help_url, as: :url, input_html: {class: 'input-xlarge'}
|
||||||
= config_input form, :webstats_tracking_code, as: :text, input_html: {class: 'input-xxlarge', rows: 3}
|
= config_input form, :webstats_tracking_code, as: :text, input_html: {class: 'input-xxlarge', rows: 3}
|
||||||
|
|
|
@ -597,6 +597,7 @@ de:
|
||||||
tasks_upfront_days: Anzahl der Tage, für welche du im Voraus wiederkehrende Aufgaben definieren möchtest
|
tasks_upfront_days: Anzahl der Tage, für welche du im Voraus wiederkehrende Aufgaben definieren möchtest
|
||||||
tax_default: Standard Mehrwertsteuersatz für neue Artikel
|
tax_default: Standard Mehrwertsteuersatz für neue Artikel
|
||||||
tolerance_is_costly: Eine möglichst große Menge im Rahmen der Tolerenz bestellen. Wenn dies nicht aktiviert ist, wird im Rahmen der Toleranz nur so viel bestellt, dass damit komplette Einheiten (Boxen) bestellt werden können. Die Option wirkt sich auch auf die Toleranz des Gesamtpreises einer offenen Mitgliederbestellung aus.
|
tolerance_is_costly: Eine möglichst große Menge im Rahmen der Tolerenz bestellen. Wenn dies nicht aktiviert ist, wird im Rahmen der Toleranz nur so viel bestellt, dass damit komplette Einheiten (Boxen) bestellt werden können. Die Option wirkt sich auch auf die Toleranz des Gesamtpreises einer offenen Mitgliederbestellung aus.
|
||||||
|
distribution_strategy: Wie bei der Verteilung von Artikeln nach dem Empfangen einer Bestellung vorgegangen werden soll.
|
||||||
use_apple_points: Wenn das Apfel Punktesystem aktiviert ist, ist es erforderlich, dass Mitglieder Aufgaben erledigen um bestellen zu können.
|
use_apple_points: Wenn das Apfel Punktesystem aktiviert ist, ist es erforderlich, dass Mitglieder Aufgaben erledigen um bestellen zu können.
|
||||||
use_boxfill: Wenn aktiviert, können Benutzer nahe am Ende der Bestellung diese nur mehr so verändern, dass sich die Gesamtsumme erhöht. Dies hilft beim auffüllen der verbleibenden Kisten. Es muss trotzdem noch das Kistenauffülldatum bei der Bestellung gesetzt werden.
|
use_boxfill: Wenn aktiviert, können Benutzer nahe am Ende der Bestellung diese nur mehr so verändern, dass sich die Gesamtsumme erhöht. Dies hilft beim auffüllen der verbleibenden Kisten. Es muss trotzdem noch das Kistenauffülldatum bei der Bestellung gesetzt werden.
|
||||||
use_iban: Zusätzlich Feld für die internationale Kontonummer bei Benutzern und Lieferanten anzeigen
|
use_iban: Zusätzlich Feld für die internationale Kontonummer bei Benutzern und Lieferanten anzeigen
|
||||||
|
@ -650,6 +651,10 @@ de:
|
||||||
tax_default: Mehrwertsteuer
|
tax_default: Mehrwertsteuer
|
||||||
time_zone: Zeitzone
|
time_zone: Zeitzone
|
||||||
tolerance_is_costly: Bestelltoleranz maximal ausnutzen, um möglichst große Mengen zu bestellen
|
tolerance_is_costly: Bestelltoleranz maximal ausnutzen, um möglichst große Mengen zu bestellen
|
||||||
|
distribution_strategy: Verteilungs-Strategie
|
||||||
|
distribution_strategy_options:
|
||||||
|
first_order_first_serve: Zuerst an die verteilen, die zuerst bestellt haben
|
||||||
|
no_automatic_distribution: Keine automatische Verteilung
|
||||||
use_apple_points: Apfelpunkte verwenden
|
use_apple_points: Apfelpunkte verwenden
|
||||||
use_boxfill: Kistenauffüllphase
|
use_boxfill: Kistenauffüllphase
|
||||||
use_iban: IBAN verwenden
|
use_iban: IBAN verwenden
|
||||||
|
|
|
@ -597,6 +597,7 @@ en:
|
||||||
tasks_upfront_days: For how many days in advance you would like to schedule periodic tasks.
|
tasks_upfront_days: For how many days in advance you would like to schedule periodic tasks.
|
||||||
tax_default: Default VAT percentage for new articles.
|
tax_default: Default VAT percentage for new articles.
|
||||||
tolerance_is_costly: Order as much of the member tolerance as possible (compared to only as much needed to fill the last box). Enabling this also includes the tolerance in the total price of the open member order.
|
tolerance_is_costly: Order as much of the member tolerance as possible (compared to only as much needed to fill the last box). Enabling this also includes the tolerance in the total price of the open member order.
|
||||||
|
distribution_strategy: How articles should be distributed after an order has been received.
|
||||||
use_apple_points: When the apple point system is enabled, members are required to do some tasks to be able to keep ordering.
|
use_apple_points: When the apple point system is enabled, members are required to do some tasks to be able to keep ordering.
|
||||||
use_boxfill: When enabled, near end of an order, members are only able to change their order when increases the total amount ordered. This helps to fill any remaining boxes. You still need to set a box-fill date for the orders.
|
use_boxfill: When enabled, near end of an order, members are only able to change their order when increases the total amount ordered. This helps to fill any remaining boxes. You still need to set a box-fill date for the orders.
|
||||||
use_iban: When enabled, supplier and user provide an additonal field for storing the international bank account number.
|
use_iban: When enabled, supplier and user provide an additonal field for storing the international bank account number.
|
||||||
|
@ -650,6 +651,10 @@ en:
|
||||||
tax_default: Default VAT
|
tax_default: Default VAT
|
||||||
time_zone: Time zone
|
time_zone: Time zone
|
||||||
tolerance_is_costly: Tolerance is costly
|
tolerance_is_costly: Tolerance is costly
|
||||||
|
distribution_strategy: Distribution strategy
|
||||||
|
distribution_strategy_options:
|
||||||
|
first_order_first_serve: First distribute to those who ordered first
|
||||||
|
no_automatic_distribution: No automatic distribution
|
||||||
use_apple_points: Apple points
|
use_apple_points: Apple points
|
||||||
use_boxfill: Box-fill phase
|
use_boxfill: Box-fill phase
|
||||||
use_iban: Use IBAN
|
use_iban: Use IBAN
|
||||||
|
|
|
@ -561,6 +561,7 @@ es:
|
||||||
tasks_upfront_days: Con cuántos días de antelación te gustaría programar las tareas periódicas.
|
tasks_upfront_days: Con cuántos días de antelación te gustaría programar las tareas periódicas.
|
||||||
tax_default: Porcentaje por defecto del IVA para artículos nuevos.
|
tax_default: Porcentaje por defecto del IVA para artículos nuevos.
|
||||||
tolerance_is_costly: Pide lo que más permita la tolerancia de los miembros (en lugar de sólo lo necesario para llenar la última caja). Permitir esto también incluye la tolerancia en el precio final del pedido abierto de cada miembro.
|
tolerance_is_costly: Pide lo que más permita la tolerancia de los miembros (en lugar de sólo lo necesario para llenar la última caja). Permitir esto también incluye la tolerancia en el precio final del pedido abierto de cada miembro.
|
||||||
|
distribution_strategy: Cómo se deben distribuir los artículos después de recibir un pedido.
|
||||||
use_apple_points: Cuando el sistema de puntos-manzana está habilitado los miembros deberán realizar algunas tareas para poder hacer pedidos.
|
use_apple_points: Cuando el sistema de puntos-manzana está habilitado los miembros deberán realizar algunas tareas para poder hacer pedidos.
|
||||||
use_boxfill: Cuando está activado, cerca del cierre de un pedido los miembros no podrán cambiar su pedido a menos que se incremente el valor pedido total. Esto ayudará a llenar las cajas que faltan. Igualmente deberás decidir una fecha de llenado de cajas para los pedidos.
|
use_boxfill: Cuando está activado, cerca del cierre de un pedido los miembros no podrán cambiar su pedido a menos que se incremente el valor pedido total. Esto ayudará a llenar las cajas que faltan. Igualmente deberás decidir una fecha de llenado de cajas para los pedidos.
|
||||||
use_iban: Cuando esta opción está habilitada, el proveedor y el usuario pueden guardan también su número de cuenta bancaria internacional (IBAN).
|
use_iban: Cuando esta opción está habilitada, el proveedor y el usuario pueden guardan también su número de cuenta bancaria internacional (IBAN).
|
||||||
|
@ -605,6 +606,10 @@ es:
|
||||||
tax_default: IVA por defecto
|
tax_default: IVA por defecto
|
||||||
time_zone: Zona horaria
|
time_zone: Zona horaria
|
||||||
tolerance_is_costly: La tolerancia es prioritaria
|
tolerance_is_costly: La tolerancia es prioritaria
|
||||||
|
distribution_strategy: Estrategia de distribución
|
||||||
|
distribution_strategy_options:
|
||||||
|
first_order_first_serve: Primero distribuya a quienes ordenaron primero
|
||||||
|
no_automatic_distribution: Sin distribución automática
|
||||||
use_apple_points: Puntos-manzana
|
use_apple_points: Puntos-manzana
|
||||||
use_boxfill: Fase de llenar las cajas
|
use_boxfill: Fase de llenar las cajas
|
||||||
use_iban: Usar IBAN
|
use_iban: Usar IBAN
|
||||||
|
|
|
@ -403,6 +403,7 @@ fr:
|
||||||
hints:
|
hints:
|
||||||
homepage: Site de votre coop.
|
homepage: Site de votre coop.
|
||||||
name: Le nom de votre coop.
|
name: Le nom de votre coop.
|
||||||
|
distribution_strategy: Comment procéder à la distribution des articles après réception d'une commande.
|
||||||
keys:
|
keys:
|
||||||
contact:
|
contact:
|
||||||
city: Ville
|
city: Ville
|
||||||
|
@ -413,6 +414,10 @@ fr:
|
||||||
zip_code: Code postal
|
zip_code: Code postal
|
||||||
currency_unit: Monnaie
|
currency_unit: Monnaie
|
||||||
name: Nom
|
name: Nom
|
||||||
|
distribution_strategy: Stratégie de distribution
|
||||||
|
distribution_strategy_options:
|
||||||
|
first_order_first_serve: Distribuez d'abord à ceux qui ont commandé en premier
|
||||||
|
no_automatic_distribution: Pas de distribution automatique
|
||||||
tabs:
|
tabs:
|
||||||
language: Langue
|
language: Langue
|
||||||
list: Liste
|
list: Liste
|
||||||
|
|
|
@ -597,6 +597,7 @@ nl:
|
||||||
tasks_upfront_days: Hoeveel dagen vantevoren je periodieke taken wil aanmaken.
|
tasks_upfront_days: Hoeveel dagen vantevoren je periodieke taken wil aanmaken.
|
||||||
tax_default: Standaard BTW percentage voor nieuwe artikelen.
|
tax_default: Standaard BTW percentage voor nieuwe artikelen.
|
||||||
tolerance_is_costly: Bestel zoveel artikelen als mogelijk in de tolerantie (in plaats van net genoeg om de laatste doos te vullen). Dit zorgt er ook voor dat de tolerantie in de prijs van open ledenbestellingen wordt meegenomen.
|
tolerance_is_costly: Bestel zoveel artikelen als mogelijk in de tolerantie (in plaats van net genoeg om de laatste doos te vullen). Dit zorgt er ook voor dat de tolerantie in de prijs van open ledenbestellingen wordt meegenomen.
|
||||||
|
distribution_strategy: Hoe verder te gaan met de distributie van artikelen na ontvangst van een bestelling.
|
||||||
use_apple_points: Wanneer het appelpunten systeem is geactiveerd, kunnen leden slechts bestellen wanneer ze meewerken aan taken.
|
use_apple_points: Wanneer het appelpunten systeem is geactiveerd, kunnen leden slechts bestellen wanneer ze meewerken aan taken.
|
||||||
use_boxfill: Wanneer dit aan staat, kunnen gebruikers aan het einde van de bestelfase hun bestelling alleen wijzigen als het de totale bestelling vergroot. Dit helpt om dozen te vullen. Bij de bestelling moet nog wel de dozen-vul-datum ingevuld worden.
|
use_boxfill: Wanneer dit aan staat, kunnen gebruikers aan het einde van de bestelfase hun bestelling alleen wijzigen als het de totale bestelling vergroot. Dit helpt om dozen te vullen. Bij de bestelling moet nog wel de dozen-vul-datum ingevuld worden.
|
||||||
use_iban: Om leverancier en gebruiker een extra veld te geven voor het internationale bankrekeningnummer (IBAN).
|
use_iban: Om leverancier en gebruiker een extra veld te geven voor het internationale bankrekeningnummer (IBAN).
|
||||||
|
@ -650,6 +651,10 @@ nl:
|
||||||
tax_default: Standaard BTW
|
tax_default: Standaard BTW
|
||||||
time_zone: Tijdzone
|
time_zone: Tijdzone
|
||||||
tolerance_is_costly: Tolerantie is duur
|
tolerance_is_costly: Tolerantie is duur
|
||||||
|
distribution_strategy: Distributie strategie
|
||||||
|
distribution_strategy_options:
|
||||||
|
first_order_first_serve: Verdeel eerst onder degenen die het eerst hebben besteld
|
||||||
|
no_automatic_distribution: Geen automatische distributie
|
||||||
use_apple_points: Appelpunten
|
use_apple_points: Appelpunten
|
||||||
use_boxfill: Dozen vullen fase
|
use_boxfill: Dozen vullen fase
|
||||||
use_iban: IBAN gebruiken
|
use_iban: IBAN gebruiken
|
||||||
|
|
|
@ -54,6 +54,12 @@ class FoodsoftConfig
|
||||||
# Loaded configuration
|
# Loaded configuration
|
||||||
APP_CONFIG = ActiveSupport::HashWithIndifferentAccess.new
|
APP_CONFIG = ActiveSupport::HashWithIndifferentAccess.new
|
||||||
|
|
||||||
|
# distribution strategy config values enum
|
||||||
|
module DistributionStrategy
|
||||||
|
FIRST_ORDER_FIRST_SERVE = 'first_order_first_serve'
|
||||||
|
NO_AUTOMATIC_DISTRIBUTION = 'no_automatic_distribution'
|
||||||
|
end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
# Load and initialize foodcoop configuration file.
|
# Load and initialize foodcoop configuration file.
|
||||||
|
@ -260,6 +266,7 @@ class FoodsoftConfig
|
||||||
tasks_period_days: 7,
|
tasks_period_days: 7,
|
||||||
tasks_upfront_days: 49,
|
tasks_upfront_days: 49,
|
||||||
shared_supplier_article_sync_limit: 200,
|
shared_supplier_article_sync_limit: 200,
|
||||||
|
distribution_strategy: FoodsoftConfig::DistributionStrategy::FIRST_ORDER_FIRST_SERVE,
|
||||||
# The following keys cannot, by default, be set by foodcoops themselves.
|
# The following keys cannot, by default, be set by foodcoops themselves.
|
||||||
protected: {
|
protected: {
|
||||||
multi_coop_install: true,
|
multi_coop_install: true,
|
||||||
|
|
9
spec/factories/group_order_article_quantity.rb
Normal file
9
spec/factories/group_order_article_quantity.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
require 'factory_bot'
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
|
||||||
|
# requires order_article
|
||||||
|
factory :group_order_article_quantity do
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -42,4 +42,23 @@ describe GroupOrderArticle do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'distribution strategy' do
|
||||||
|
let(:article) { create :article, supplier: order.supplier, unit_quantity: 1 }
|
||||||
|
let(:oa) { order.order_articles.create(:article => article) }
|
||||||
|
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 }
|
||||||
|
|
||||||
|
it 'can calculate the result for the distribution strategy "first order first serve"' do
|
||||||
|
res = goa.calculate_result(2)
|
||||||
|
expect(res).to eq(quantity: 2, tolerance: 0, total: 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can calculate the result for the distribution strategy "no automatic distribution"' do
|
||||||
|
FoodsoftConfig[:distribution_strategy] = FoodsoftConfig::DistributionStrategy::NO_AUTOMATIC_DISTRIBUTION
|
||||||
|
|
||||||
|
res = goa.calculate_result(2)
|
||||||
|
expect(res).to eq(quantity: 4, tolerance: 0, total: 4)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue